Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d6c292a authored by Krishnankutty Kolathappilly's avatar Krishnankutty Kolathappilly Committed by Eric Laurent
Browse files

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: default avatarGlenn Kasten <gkasten@google.com>
parent 9ff25ced
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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
+33 −2
Original line number Diff line number Diff line
@@ -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>