diff options
| -rw-r--r-- | media/jni/soundpool/SoundPool.cpp | 41 | ||||
| -rw-r--r-- | media/jni/soundpool/SoundPool.h | 4 | 
2 files changed, 29 insertions, 16 deletions
| diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp index a705bcc37406..d4b54c3ac02b 100644 --- a/media/jni/soundpool/SoundPool.cpp +++ b/media/jni/soundpool/SoundPool.cpp @@ -187,6 +187,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) { @@ -211,18 +222,21 @@ int SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unuse  {      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) @@ -237,7 +251,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; @@ -247,7 +260,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; diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h index 4aacf5335531..98d2fa25207c 100644 --- a/media/jni/soundpool/SoundPool.h +++ b/media/jni/soundpool/SoundPool.h @@ -180,6 +180,7 @@ public:      // called from SoundPoolThread      void sampleLoaded(int sampleID); +    sp<Sample> findSample(int sampleID);      // called from AudioTrack thread      void done_l(SoundChannel* channel); @@ -191,8 +192,7 @@ public:  private:      SoundPool() {} // no default constructor      bool startThreads(); -    void doLoad(sp<Sample>& sample); -    sp<Sample> findSample(int sampleID) { return mSamples.valueFor(sampleID); } +    sp<Sample> findSample_l(int sampleID);      SoundChannel* findChannel (int channelID);      SoundChannel* findNextChannel (int channelID);      SoundChannel* allocateChannel_l(int priority, int sampleID); |