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

Commit ad9ef61e authored by Phil Burk's avatar Phil Burk Committed by Android (Google) Code Review
Browse files

Merge "AudioFlinger: flush stream when switching tracks" into mnc-dev

parents cd644a3f 43b4dcc6
Loading
Loading
Loading
Loading
+40 −22
Original line number Diff line number Diff line
@@ -4459,6 +4459,17 @@ void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTr
    }
}

void AudioFlinger::DirectOutputThread::onAddNewTrack_l()
{
    sp<Track> previousTrack = mPreviousTrack.promote();
    sp<Track> latestTrack = mLatestActiveTrack.promote();

    if (previousTrack != 0 && latestTrack != 0 &&
        (previousTrack->sessionId() != latestTrack->sessionId())) {
        mFlushPending = true;
    }
    PlaybackThread::onAddNewTrack_l();
}

AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l(
    Vector< sp<Track> > *tracksToRemove
@@ -4468,7 +4479,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
    mixer_state mixerStatus = MIXER_IDLE;
    bool doHwPause = false;
    bool doHwResume = false;
    bool flushPending = false;

    // find out which tracks need to be processed
    for (size_t i = 0; i < count; i++) {
@@ -4478,6 +4488,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
            continue;
        }

        if (t->isInvalid()) {
            ALOGW("An invalidated track shouldn't be in active list");
            tracksToRemove->add(t);
            continue;
        }

        Track* const track = t.get();
        audio_track_cblk_t* cblk = track->cblk();
        // Only consider last track started for volume and mixer state control.
@@ -4497,7 +4513,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
        } else if (track->isFlushPending()) {
            track->flushAck();
            if (last) {
                flushPending = true;
                mFlushPending = true;
            }
        } else if (track->isResumePending()) {
            track->resumeAck();
@@ -4538,6 +4554,21 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
            // compute volume for this track
            processVolume_l(track, last);
            if (last) {
                sp<Track> previousTrack = mPreviousTrack.promote();
                if (previousTrack != 0) {
                    if (track != previousTrack.get()) {
                        // Flush any data still being written from last track
                        mBytesRemaining = 0;
                        // flush data already sent if changing audio session as audio
                        // comes from a different source. Also invalidate previous track to force a
                        // seek when resuming.
                        if (previousTrack->sessionId() != track->sessionId()) {
                            previousTrack->invalidate();
                        }
                    }
                }
                mPreviousTrack = track;

                // reset retry count
                track->mRetryCount = kMaxTrackRetriesDirect;
                mActiveTrack = t;
@@ -4604,11 +4635,11 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
    }

    // if an active track did not command a flush, check for pending flush on stopped tracks
    if (!flushPending) {
    if (!mFlushPending) {
        for (size_t i = 0; i < mTracks.size(); i++) {
            if (mTracks[i]->isFlushPending()) {
                mTracks[i]->flushAck();
                flushPending = true;
                mFlushPending = true;
            }
        }
    }
@@ -4618,10 +4649,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
    // before flush and then resume HW. This can happen in case of pause/flush/resume
    // if resume is received before pause is executed.
    if (mHwSupportsPause && !mStandby &&
            (doHwPause || (flushPending && !mHwPaused && (count != 0)))) {
            (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) {
        mOutput->stream->pause(mOutput->stream);
    }
    if (flushPending) {
    if (mFlushPending) {
        flushHw_l();
    }
    if (mHwSupportsPause && !mStandby && doHwResume) {
@@ -4680,14 +4711,13 @@ void AudioFlinger::DirectOutputThread::threadLoop_exit()
{
    {
        Mutex::Autolock _l(mLock);
        bool flushPending = false;
        for (size_t i = 0; i < mTracks.size(); i++) {
            if (mTracks[i]->isFlushPending()) {
                mTracks[i]->flushAck();
                flushPending = true;
                mFlushPending = true;
            }
        }
        if (flushPending) {
        if (mFlushPending) {
            flushHw_l();
        }
    }
@@ -4825,6 +4855,7 @@ void AudioFlinger::DirectOutputThread::flushHw_l()
{
    mOutput->flush();
    mHwPaused = false;
    mFlushPending = false;
}

// ----------------------------------------------------------------------------
@@ -5146,7 +5177,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr
    }
    if (mFlushPending) {
        flushHw_l();
        mFlushPending = false;
    }
    if (!mStandby && doHwResume) {
        mOutput->stream->resume(mOutput->stream);
@@ -5194,18 +5224,6 @@ void AudioFlinger::OffloadThread::flushHw_l()
    }
}

void AudioFlinger::OffloadThread::onAddNewTrack_l()
{
    sp<Track> previousTrack = mPreviousTrack.promote();
    sp<Track> latestTrack = mLatestActiveTrack.promote();

    if (previousTrack != 0 && latestTrack != 0 &&
        (previousTrack->sessionId() != latestTrack->sessionId())) {
        mFlushPending = true;
    }
    PlaybackThread::onAddNewTrack_l();
}

// ----------------------------------------------------------------------------

AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
+5 −2
Original line number Diff line number Diff line
@@ -941,6 +941,8 @@ protected:
    virtual     void        threadLoop_exit();
    virtual     bool        shouldStandby_l();

    virtual     void        onAddNewTrack_l();

    // volumes last sent to audio HAL with stream->set_volume()
    float mLeftVolFloat;
    float mRightVolFloat;
@@ -952,6 +954,9 @@ protected:

    // prepareTracks_l() tells threadLoop_mix() the name of the single active track
    sp<Track>               mActiveTrack;

    wp<Track>               mPreviousTrack;         // used to detect track switch

public:
    virtual     bool        hasFastMixer() const { return false; }
};
@@ -971,12 +976,10 @@ protected:

    virtual     bool        waitingAsyncCallback();
    virtual     bool        waitingAsyncCallback_l();
    virtual     void        onAddNewTrack_l();

private:
    size_t      mPausedWriteLength;     // length in bytes of write interrupted by pause
    size_t      mPausedBytesRemaining;  // bytes still waiting in mixbuffer after resume
    wp<Track>   mPreviousTrack;         // used to detect track switch
};

class AsyncCallbackThread : public Thread {