summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndy Hung <hunga@google.com>2015-12-02 15:55:23 -0800
committerAndy Hung <hunga@google.com>2015-12-03 18:54:00 +0000
commit3d6a7149802928ecf3f58b7218b0e82699b492df (patch)
treed1733d4792e95ae68ed843927cf38291863e4c42 /media
parent6afc659b00c3f4a83b9f5f3c744b7119b33340b4 (diff)
downloadframeworks_av-3d6a7149802928ecf3f58b7218b0e82699b492df.zip
frameworks_av-3d6a7149802928ecf3f58b7218b0e82699b492df.tar.gz
frameworks_av-3d6a7149802928ecf3f58b7218b0e82699b492df.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.cpp61
1 files changed, 42 insertions, 19 deletions
diff --git a/media/libmedia/SoundPool.cpp b/media/libmedia/SoundPool.cpp
index 22e9fad..a2b5e30 100644
--- a/media/libmedia/SoundPool.cpp
+++ b/media/libmedia/SoundPool.cpp
@@ -179,6 +179,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) {
@@ -202,29 +213,42 @@ SoundChannel* SoundPool::findNextChannel(int channelID)
int SoundPool::load(const char* path, int priority)
{
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)
{
ALOGV("load: fd=%d, offset=%lld, length=%lld, 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)
@@ -239,7 +263,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;
@@ -249,7 +272,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;