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

Commit c54b1ffc authored by Andy Hung's avatar Andy Hung
Browse files

Fix AudioTrack presentationComplete regression

Bug: 27310929
Change-Id: Id52299660d90b07220a4fd9996da53fe755a41f1
parent af9c466b
Loading
Loading
Loading
Loading
+18 −17
Original line number Diff line number Diff line
@@ -1565,6 +1565,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
        mEffectBufferFormat(AUDIO_FORMAT_INVALID),
        mEffectBufferValid(false),
        mSuspended(0), mBytesWritten(0),
        mFramesWritten(0),
        mActiveTracksGeneration(0),
        // mStreamTypes[] initialized in constructor body
        mOutput(output),
@@ -2863,6 +2864,7 @@ bool AudioFlinger::PlaybackThread::threadLoop()
            // and associate with the sink frames written out.  We need
            // this to convert the sink timestamp to the track timestamp.
            if (mNormalSink != 0) {
                // Note: The DuplicatingThread may not have a mNormalSink.
                // We always fetch the timestamp here because often the downstream
                // sink will block whie writing.
                ExtendedTimestamp timestamp; // use private copy to fetch
@@ -2872,25 +2874,22 @@ bool AudioFlinger::PlaybackThread::threadLoop()
                        timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
                mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
                        timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];

                // sinkFramesWritten for non-offloaded tracks are contiguous
            }
            // mFramesWritten for non-offloaded tracks are contiguous
            // even after standby() is called. This is useful for the track frame
            // to sink frame mapping.
                const int64_t sinkFramesWritten = mNormalSink->framesWritten();
                mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = sinkFramesWritten;
            mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = mFramesWritten;
            mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime();

            const size_t size = mActiveTracks.size();
            for (size_t i = 0; i < size; ++i) {
                sp<Track> t = mActiveTracks[i].promote();
                if (t != 0 && !t->isFastTrack()) {
                    t->updateTrackFrameInfo(
                            t->mAudioTrackServerProxy->framesReleased(),
                                sinkFramesWritten,
                            mFramesWritten,
                            mTimestamp);
                }
            }
            }

            saveOutputTracks();
            if (mSignalPending) {
@@ -3026,6 +3025,7 @@ bool AudioFlinger::PlaybackThread::threadLoop()
                mSleepTimeUs = suspendSleepTimeUs();
                // simulate write to HAL when suspended
                mBytesWritten += mSinkBufferSize;
                mFramesWritten += mSinkBufferSize / mFrameSize;
                mBytesRemaining = 0;
            }

@@ -3076,6 +3076,7 @@ bool AudioFlinger::PlaybackThread::threadLoop()
                    } else {
                        mBytesWritten += ret;
                        mBytesRemaining -= ret;
                        mFramesWritten += ret / mFrameSize;
                    }
                } else if ((mMixerStatus == MIXER_DRAIN_TRACK) ||
                        (mMixerStatus == MIXER_DRAIN_ALL)) {
+1 −0
Original line number Diff line number Diff line
@@ -693,6 +693,7 @@ protected:
    volatile int32_t                mSuspended;

    int64_t                         mBytesWritten;
    int64_t                         mFramesWritten; // not reset on standby
private:
    // mMasterMute is in both PlaybackThread and in AudioFlinger.  When a
    // PlaybackThread needs to find out if master-muted, it checks it's local
+11 −3
Original line number Diff line number Diff line
@@ -960,9 +960,17 @@ bool AudioFlinger::PlaybackThread::Track::presentationComplete(
                (long long)mPresentationCompleteFrames, audioHalFrames);
    }

    if ((!isOffloaded() && !isDirect() && !isFastTrack()
            && framesWritten >= mPresentationCompleteFrames
            && mAudioTrackServerProxy->isDrained()) || isOffloaded()) {
    bool complete;
    if (isOffloaded()) {
        complete = true;
    } else if (isDirect() || isFastTrack()) { // these do not go through linear map
        complete = framesWritten >= mPresentationCompleteFrames;
    } else {  // Normal tracks, OutputTracks, and PatchTracks
        complete = framesWritten >= mPresentationCompleteFrames
                && mAudioTrackServerProxy->isDrained();
    }

    if (complete) {
        triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
        mAudioTrackServerProxy->setStreamEndDone();
        return true;