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

Commit f8ec8390 authored by Atneya Nair's avatar Atneya Nair Committed by Android (Google) Code Review
Browse files

Merge "Allow frame count regress in AudioStreamOut" into tm-dev

parents ba81ad85 0cae043f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ AudioStreamOut::AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags)
        , mRateMultiplier(1)
        , mHalFormatHasProportionalFrames(false)
        , mHalFrameSize(0)
        , mExpectRetrograde(false)
{
}

@@ -69,8 +70,12 @@ status_t AudioStreamOut::getRenderPosition(uint64_t *frames)
    const uint32_t truncatedPosition = (uint32_t)mRenderPosition;
    int32_t deltaHalPosition; // initialization not needed, overwitten by __builtin_sub_overflow()
    (void) __builtin_sub_overflow(halPosition, truncatedPosition, &deltaHalPosition);

    if (deltaHalPosition > 0) {
        mRenderPosition += deltaHalPosition;
    } else if (mExpectRetrograde) {
        mExpectRetrograde = false;
        mRenderPosition -= static_cast<uint64_t>(-deltaHalPosition);
    }
    // Scale from HAL sample rate to application rate.
    *frames = mRenderPosition / mRateMultiplier;
@@ -187,6 +192,7 @@ audio_config_base_t AudioStreamOut::getAudioProperties() const
int AudioStreamOut::flush()
{
    mRenderPosition = 0;
    mExpectRetrograde = false;
    mFramesWritten = 0;
    mFramesWrittenAtStandby = 0;
    status_t result = stream->flush();
@@ -196,6 +202,7 @@ int AudioStreamOut::flush()
int AudioStreamOut::standby()
{
    mRenderPosition = 0;
    mExpectRetrograde = false;
    mFramesWrittenAtStandby = mFramesWritten;
    return stream->standby();
}
+9 −1
Original line number Diff line number Diff line
@@ -93,13 +93,21 @@ public:
    virtual status_t flush();
    virtual status_t standby();

    // Avoid suppressing retrograde motion in mRenderPosition for gapless offload/direct when
    // transitioning between tracks.
    // The HAL resets the frame position without flush/stop being called, but calls back prior to
    // this event. So, on the next occurrence of retrograde motion, we permit backwards movement of
    // mRenderPosition.
    virtual void presentationComplete() { mExpectRetrograde = true; }

protected:
    uint64_t             mFramesWritten; // reset by flush
    uint64_t             mFramesWrittenAtStandby;
    uint64_t             mRenderPosition; // reset by flush or standby
    uint64_t             mRenderPosition; // reset by flush, standby, or presentation complete
    int                  mRateMultiplier;
    bool                 mHalFormatHasProportionalFrames;
    size_t               mHalFrameSize;
    bool                 mExpectRetrograde; // see presentationComplete
};

} // namespace android
+7 −2
Original line number Diff line number Diff line
@@ -6316,9 +6316,13 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
                    track->isStopping_2() || track->isPaused()) {
                // We have consumed all the buffers of this track.
                // Remove it from the list of active tracks.
                bool presComplete = false;
                if (mStandby || !last ||
                        track->presentationComplete(latency_l()) ||
                        (presComplete = track->presentationComplete(latency_l())) ||
                        track->isPaused() || mHwPaused) {
                    if (presComplete) {
                        mOutput->presentationComplete();
                    }
                    if (track->isStopping_2()) {
                        track->mState = TrackBase::STOPPED;
                    }
@@ -6897,7 +6901,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr
                // Drain has completed or we are in standby, signal presentation complete
                if (!(mDrainSequence & 1) || !last || mStandby) {
                    track->mState = TrackBase::STOPPED;
                    track->presentationComplete(latency_l());
                    mOutput->presentationComplete();
                    track->presentationComplete(latency_l()); // always returns true
                    track->reset();
                    tracksToRemove->add(track);
                    // OFFLOADED stop resets frame counts.