From 47f8c7303c9e2054f1492b02b6c7472385c52dc9 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 7 Mar 2016 03:43:14 -0800 Subject: audiopolicy: Defer release of output session effects * Some effects modules are racy and don't tolerate being destroyed and immediately resurrected on the same session. This is the common case when switching tracks, and the use of default output effects makes the problem even worse. Certain apps which handle gapless in a sloppy way are also to blame. * Instead of immediately nuking the entire descriptor with the stream, just decrease the refcount and defer it for 10 seconds. If it needs resurrected, the refcount will be increased and the delayed release command will not shoot it in the face. Change-Id: I068dd72c4180023a74eb9ccbe8a180f6f0683dbf --- .../audiopolicy/service/AudioPolicyService.cpp | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'services/audiopolicy/service/AudioPolicyService.cpp') diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index dbeed80..58cfe37 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -357,6 +357,13 @@ void AudioPolicyService::binderDied(const wp& who) { IPCThreadState::self()->getCallingPid()); } +void AudioPolicyService::releaseOutputSessionEffectsDelayed( + audio_io_handle_t output, audio_stream_type_t stream, + audio_unique_id_t sessionId, int delayMs) +{ + mAudioCommandThread->releaseOutputSessionEffectsCommand(output, stream, sessionId, delayMs); +} + static bool tryLock(Mutex& mutex) { bool locked = false; @@ -641,6 +648,21 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId, data->mAdded); mLock.lock(); } break; + case RELEASE_OUTPUT_SESSION_EFFECTS: { + ReleaseOutputSessionEffectsData *data = + (ReleaseOutputSessionEffectsData *)command->mParam.get(); + ALOGV("AudioCommandThread() processing release output session effects %d %d %d", + data->mOutput, data->mStream, data->mSessionId); + svc = mService.promote(); + if (svc == 0) { + break; + } + mLock.unlock(); + svc->mAudioPolicyEffects->doReleaseOutputSessionEffects( + data->mOutput, data->mStream, data->mSessionId); + mLock.lock(); + } break; + default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); @@ -929,6 +951,23 @@ void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand( sendCommand(command); } +void AudioPolicyService::AudioCommandThread::releaseOutputSessionEffectsCommand( + audio_io_handle_t output, audio_stream_type_t stream, + audio_unique_id_t sessionId, int delayMs) +{ + sp command = new AudioCommand(); + command->mCommand = RELEASE_OUTPUT_SESSION_EFFECTS; + ReleaseOutputSessionEffectsData *data = new ReleaseOutputSessionEffectsData(); + data->mOutput = output; + data->mStream = stream; + data->mSessionId = sessionId; + command->mParam = data; + ALOGV("AudioCommandThread() sending release output session effects (id=%d) for stream %d", + sessionId, stream); + sendCommand(command, delayMs); +} + + status_t AudioPolicyService::AudioCommandThread::sendCommand(sp& command, int delayMs) { { -- cgit v1.1