diff options
author | Krishnankutty Kolathappilly <kkolat@codeaurora.org> | 2014-02-04 16:23:42 -0800 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2014-03-17 18:30:13 -0700 |
commit | 8d6c292a0bed3d63b5b7297d09a604af6327c663 (patch) | |
tree | 344c2297ed00e1e10998490bc4e2f00358536133 | |
parent | 9ff25ced1404c896df9e6ed3a6ad289305559361 (diff) | |
download | frameworks_av-8d6c292a0bed3d63b5b7297d09a604af6327c663.zip frameworks_av-8d6c292a0bed3d63b5b7297d09a604af6327c663.tar.gz frameworks_av-8d6c292a0bed3d63b5b7297d09a604af6327c663.tar.bz2 |
audioflinger: Handle pause /resume in stopping state
-Pre-requisite:
Perform seek on the clip. After seek the data remaining till EOS
is little more than the driver and common block buffering.
-Framework state:
Offload thread is waiting for signal from the HAL for a free
buffer. Audio Player calls sink stop on reaching EOS. Audio
track is waiting on obtain buffer for a free space in common
block to send the last buffer. The track is moved to stopping
state as input EOS is reached.
-Issue:
Perform pause/ resume in this state(STOPPING), Audio playback
does not resume.
-Fix
Ensure resume is called in stopping state if frames ready is
greater than zero.
Bug: 12870871
Change-Id: Ib1378c4ee5ce4bea655691e93de0775f7b1d2804
Signed-off-by: Glenn Kasten <gkasten@google.com>
-rw-r--r-- | services/audioflinger/PlaybackTracks.h | 2 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 4 | ||||
-rw-r--r-- | services/audioflinger/Tracks.cpp | 35 |
3 files changed, 37 insertions, 4 deletions
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h index b5e763d..e9c6834 100644 --- a/services/audioflinger/PlaybackTracks.h +++ b/services/audioflinger/PlaybackTracks.h @@ -96,6 +96,8 @@ protected: void reset(); bool isFlushPending() const { return mFlushHwPending; } void flushAck(); + bool isResumePending(); + void resumeAck(); bool isOutputTrack() const { return (mStreamType == AUDIO_STREAM_CNT); diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 12d453e..e90ebd1 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -4230,8 +4230,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr track->mFillingUpStatus = Track::FS_ACTIVE; // make sure processVolume_l() will apply new volume even if 0 mLeftVolFloat = mRightVolFloat = -1.0; - if (track->mState == TrackBase::RESUMING) { - track->mState = TrackBase::ACTIVE; + if (track->isResumePending()) { + track->resumeAck(); if (last) { if (mPausedBytesRemaining) { // Need to continue write that was interrupted diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index f19cd88..c90bae0 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -567,7 +567,12 @@ size_t AudioFlinger::PlaybackThread::Track::framesReleased() const // Don't call for fast tracks; the framesReady() could result in priority inversion bool AudioFlinger::PlaybackThread::Track::isReady() const { - if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing() || isStopping()) { + if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) { + return true; + } + + if (isStopping() && framesReady() > 0) { + mFillingUpStatus = FS_FILLED; return true; } @@ -604,7 +609,10 @@ status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t ev // here the track could be either new, or restarted // in both cases "unstop" the track - if (state == PAUSED) { + // initial state-stopping. next state-pausing. + // What if resume is called ? + + if (state == PAUSED || state == PAUSING) { if (mResumeToStopping) { // happened we need to resume to STOPPING_1 mState = TrackBase::STOPPING_1; @@ -991,6 +999,29 @@ void AudioFlinger::PlaybackThread::Track::signal() } } +//To be called with thread lock held +bool AudioFlinger::PlaybackThread::Track::isResumePending() { + + if (mState == RESUMING) + return true; + /* Resume is pending if track was stopping before pause was called */ + if (mState == STOPPING_1 && + mResumeToStopping) + return true; + + return false; +} + +//To be called with thread lock held +void AudioFlinger::PlaybackThread::Track::resumeAck() { + + + if (mState == RESUMING) + mState = ACTIVE; + // Other possibility of pending resume is stopping_1 state + // Do not update the state from stopping as this prevents + //drain being called. +} // ---------------------------------------------------------------------------- sp<AudioFlinger::PlaybackThread::TimedTrack> |