diff options
| author | Andy Hung <hunga@google.com> | 2015-12-02 15:55:23 -0800 |
|---|---|---|
| committer | Andy Hung <hunga@google.com> | 2015-12-02 18:05:32 -0800 |
| commit | 19c47afbc402542720ddd280e1bbde3b2277b586 (patch) | |
| tree | d2c3657298566f4466ea0f6ee51217ffe1a9b7a1 /media | |
| parent | 09c291c838bc74bb7c10c22f7232abb946cad8ff (diff) | |
| download | frameworks_av-19c47afbc402542720ddd280e1bbde3b2277b586.zip frameworks_av-19c47afbc402542720ddd280e1bbde3b2277b586.tar.gz frameworks_av-19c47afbc402542720ddd280e1bbde3b2277b586.tar.bz2 | |
DO NOT MERGE SoundPool: add lock for findSample access from SoundPoolThread
Sample decoding still occurs in SoundPoolThread
without holding the SoundPool lock.
Bug: 25781119
Change-Id: I11fde005aa9cf5438e0390a0d2dfe0ec1dd282e8
Diffstat (limited to 'media')
| -rw-r--r-- | media/libmedia/SoundPool.cpp | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/media/libmedia/SoundPool.cpp b/media/libmedia/SoundPool.cpp index d2e381b..29ad7ea 100644 --- a/media/libmedia/SoundPool.cpp +++ b/media/libmedia/SoundPool.cpp @@ -183,6 +183,17 @@ bool SoundPool::startThreads() return mDecodeThread != NULL; } +sp<Sample> SoundPool::findSample(int sampleID) +{ + Mutex::Autolock lock(&mLock); + return findSample_l(sampleID); +} + +sp<Sample> SoundPool::findSample_l(int sampleID) +{ + return mSamples.valueFor(sampleID); +} + SoundChannel* SoundPool::findChannel(int channelID) { for (int i = 0; i < mMaxChannels; ++i) { @@ -206,29 +217,42 @@ SoundChannel* SoundPool::findNextChannel(int channelID) int SoundPool::load(const char* path, int priority __unused) { ALOGV("load: path=%s, priority=%d", path, priority); - Mutex::Autolock lock(&mLock); - sp<Sample> sample = new Sample(++mNextSampleID, path); - mSamples.add(sample->sampleID(), sample); - doLoad(sample); - return sample->sampleID(); + int sampleID; + { + Mutex::Autolock lock(&mLock); + sampleID = ++mNextSampleID; + sp<Sample> sample = new Sample(sampleID, path); + mSamples.add(sampleID, sample); + sample->startLoad(); + } + // mDecodeThread->loadSample() must be called outside of mLock. + // mDecodeThread->loadSample() may block on mDecodeThread message queue space; + // the message queue emptying may block on SoundPool::findSample(). + // + // It theoretically possible that sample loads might decode out-of-order. + mDecodeThread->loadSample(sampleID); + return sampleID; } int SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unused) { ALOGV("load: fd=%d, offset=%" PRId64 ", length=%" PRId64 ", priority=%d", fd, offset, length, priority); - Mutex::Autolock lock(&mLock); - sp<Sample> sample = new Sample(++mNextSampleID, fd, offset, length); - mSamples.add(sample->sampleID(), sample); - doLoad(sample); - return sample->sampleID(); -} - -void SoundPool::doLoad(sp<Sample>& sample) -{ - ALOGV("doLoad: loading sample sampleID=%d", sample->sampleID()); - sample->startLoad(); - mDecodeThread->loadSample(sample->sampleID()); + int sampleID; + { + Mutex::Autolock lock(&mLock); + sampleID = ++mNextSampleID; + sp<Sample> sample = new Sample(sampleID, fd, offset, length); + mSamples.add(sampleID, sample); + sample->startLoad(); + } + // mDecodeThread->loadSample() must be called outside of mLock. + // mDecodeThread->loadSample() may block on mDecodeThread message queue space; + // the message queue emptying may block on SoundPool::findSample(). + // + // It theoretically possible that sample loads might decode out-of-order. + mDecodeThread->loadSample(sampleID); + return sampleID; } bool SoundPool::unload(int sampleID) @@ -243,7 +267,6 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume, { ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f", sampleID, leftVolume, rightVolume, priority, loop, rate); - sp<Sample> sample; SoundChannel* channel; int channelID; @@ -253,7 +276,7 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume, return 0; } // is sample ready? - sample = findSample(sampleID); + sp<Sample> sample(findSample_l(sampleID)); if ((sample == 0) || (sample->state() != Sample::READY)) { ALOGW(" sample %d not READY", sampleID); return 0; |
