summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/AudioFlinger.cpp
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-10-02 19:41:47 -0700
committerEric Laurent <elaurent@google.com>2014-10-02 19:41:47 -0700
commit1b92868010b5c1409692a86f6b27e4a265b64c1a (patch)
treeaa514a65d23d1bebbceef49cc6b7f2662c7bad76 /services/audioflinger/AudioFlinger.cpp
parentd8b03abf1d003e2940a19f0071ea2892689dd10e (diff)
downloadframeworks_av-1b92868010b5c1409692a86f6b27e4a265b64c1a.zip
frameworks_av-1b92868010b5c1409692a86f6b27e4a265b64c1a.tar.gz
frameworks_av-1b92868010b5c1409692a86f6b27e4a265b64c1a.tar.bz2
audioflinger: fix pre processing transfer between record threads.
Fix two problems remaining with pre processing effects transfer from one record thread to the next in case of tear down due to device connection: 1 - the enabled state of the effects was not communicated to the new HAL input stream. 2 - the effects saved in orphan chains list were not transfered to the new thread when a AudioRecord was created. Bug: 17757378. Change-Id: I0923c98470db3b51154dc89846157780a4c21e86
Diffstat (limited to 'services/audioflinger/AudioFlinger.cpp')
-rw-r--r--services/audioflinger/AudioFlinger.cpp48
1 files changed, 43 insertions, 5 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index e200857..e48af20 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1436,6 +1436,16 @@ sp<IAudioRecord> AudioFlinger::openRecord(
IPCThreadState::self()->getCallingUid(),
flags, tid, &lStatus);
LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
+
+ if (lStatus == NO_ERROR) {
+ // Check if one effect chain was awaiting for an AudioRecord to be created on this
+ // session and move it to this thread.
+ sp<EffectChain> chain = getOrphanEffectChain_l((audio_session_t)lSessionId);
+ if (chain != 0) {
+ Mutex::Autolock _l(thread->mLock);
+ thread->addEffectChain_l(chain);
+ }
+ }
}
if (lStatus != NO_ERROR) {
@@ -2034,14 +2044,41 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
}
ALOGV("closeInput() %d", input);
+
+ // If we still have effect chains, it means that a client still holds a handle
+ // on at least one effect. We must either move the chain to an existing thread with the
+ // same session ID or put it aside in case a new record thread is opened for a
+ // new capture on the same session
+ sp<EffectChain> chain;
{
- // If we still have effect chains, it means that a client still holds a handle
- // on at least one effect. We must keep the chain alive in case a new record
- // thread is opened for a new capture on the same session
Mutex::Autolock _sl(thread->mLock);
Vector< sp<EffectChain> > effectChains = thread->getEffectChains_l();
- for (size_t i = 0; i < effectChains.size(); i++) {
- putOrphanEffectChain_l(effectChains[i]);
+ // Note: maximum one chain per record thread
+ if (effectChains.size() != 0) {
+ chain = effectChains[0];
+ }
+ }
+ if (chain != 0) {
+ // first check if a record thread is already opened with a client on the same session.
+ // This should only happen in case of overlap between one thread tear down and the
+ // creation of its replacement
+ size_t i;
+ for (i = 0; i < mRecordThreads.size(); i++) {
+ sp<RecordThread> t = mRecordThreads.valueAt(i);
+ if (t == thread) {
+ continue;
+ }
+ if (t->hasAudioSession(chain->sessionId()) != 0) {
+ Mutex::Autolock _l(t->mLock);
+ ALOGV("closeInput() found thread %d for effect session %d",
+ t->id(), chain->sessionId());
+ t->addEffectChain_l(chain);
+ break;
+ }
+ }
+ // put the chain aside if we could not find a record thread with the same session id.
+ if (i == mRecordThreads.size()) {
+ putOrphanEffectChain_l(chain);
}
}
audioConfigChanged(AudioSystem::INPUT_CLOSED, input, NULL);
@@ -2478,6 +2515,7 @@ sp<IEffect> AudioFlinger::createEffect(
// session and used it instead of creating a new one.
sp<EffectChain> chain = getOrphanEffectChain_l((audio_session_t)sessionId);
if (chain != 0) {
+ Mutex::Autolock _l(thread->mLock);
thread->addEffectChain_l(chain);
}
}