diff options
author | Eric Laurent <elaurent@google.com> | 2013-10-04 16:23:48 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2013-10-04 16:37:07 -0700 |
commit | ea0fadeb5d81ef3cb7f9db458c9033d628bdb86a (patch) | |
tree | 1650f71cf339cd9d561377e239e2a12f7b08cffc /services | |
parent | 026c5b07fefd36e0e2dd7035c2898d0e28596d0f (diff) | |
download | frameworks_av-ea0fadeb5d81ef3cb7f9db458c9033d628bdb86a.zip frameworks_av-ea0fadeb5d81ef3cb7f9db458c9033d628bdb86a.tar.gz frameworks_av-ea0fadeb5d81ef3cb7f9db458c9033d628bdb86a.tar.bz2 |
audioflinger: offload: fix pause/flush/resume
If a pause/flush/resume sequence is fast enough, resume is received while
we are still in PAUSING state in which case it is a NOP. If this happens,
flush is still forwarded to the audio HAL but is not preceeded by a pause
which can cause problems to the audio DSP.
It is necessary to preserve the flush as this sequence is typical to a seek.
The fix consists in forcing a pause/resume when a flush request must be
executed and the audio HAL has not been paused previously.
Bug: 11081559.
Change-Id: Ib84ed26d503a61c05933b923ec556b10cedfe140
Diffstat (limited to 'services')
-rw-r--r-- | services/audioflinger/Threads.cpp | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 943a70e..b618eff 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -3864,6 +3864,7 @@ AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, uint32_t device) : DirectOutputThread(audioFlinger, output, id, device, OFFLOAD), mHwPaused(false), + mFlushPending(false), mPausedBytesRemaining(0) { } @@ -4029,9 +4030,15 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr processVolume_l(track, last); } - // make sure the pause/flush/resume sequence is executed in the right order - if (doHwPause) { + // make sure the pause/flush/resume sequence is executed in the right order. + // If a flush is pending and a track is active but the HW is not paused, force a HW pause + // before flush and then resume HW. This can happen in case of pause/flush/resume + // if resume is received before pause is executed. + if (doHwPause || (mFlushPending && !mHwPaused && (count != 0))) { mOutput->stream->pause(mOutput->stream); + if (!doHwPause) { + doHwResume = true; + } } if (mFlushPending) { flushHw_l(); |