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

Commit 4dc482da authored by Andreas Huber's avatar Andreas Huber
Browse files

Delay signaling the end of audio playback until all frames have actually played.

Change-Id: I1fa07358a885a818fd0a5d7da425740f86095e10
related-to-bug: 3404000
parent 66044c17
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -108,6 +108,8 @@ private:

    void reset();

    uint32_t getNumFramesPendingPlayout() const;

    AudioPlayer(const AudioPlayer &);
    AudioPlayer &operator=(const AudioPlayer &);
};
+48 −1
Original line number Diff line number Diff line
@@ -280,6 +280,26 @@ void AudioPlayer::AudioCallback(int event, void *info) {
    buffer->size = numBytesWritten;
}

uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
    uint32_t numFramesPlayedOut;
    status_t err;

    if (mAudioSink != NULL) {
        err = mAudioSink->getPosition(&numFramesPlayedOut);
    } else {
        err = mAudioTrack->getPosition(&numFramesPlayedOut);
    }

    if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
        return 0;
    }

    // mNumFramesPlayed is the number of frames submitted
    // to the audio sink for playback, but not all of them
    // may have played out by now.
    return mNumFramesPlayed - numFramesPlayedOut;
}

size_t AudioPlayer::fillBuffer(void *data, size_t size) {
    if (mNumFramesPlayed == 0) {
        LOGV("AudioCallback");
@@ -342,7 +362,34 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {

            if (err != OK) {
                if (mObserver && !mReachedEOS) {
                    mObserver->postAudioEOS();
                    // We don't want to post EOS right away but only
                    // after all frames have actually been played out.

                    // These are the number of frames submitted to the
                    // AudioTrack that you haven't heard yet.
                    uint32_t numFramesPendingPlayout =
                        getNumFramesPendingPlayout();

                    // These are the number of frames we're going to
                    // submit to the AudioTrack by returning from this
                    // callback.
                    uint32_t numAdditionalFrames = size_done / mFrameSize;

                    numFramesPendingPlayout += numAdditionalFrames;

                    int64_t timeToCompletionUs =
                        (1000000ll * numFramesPendingPlayout) / mSampleRate;

                    LOGV("total number of frames played: %lld (%lld us)",
                            (mNumFramesPlayed + numAdditionalFrames),
                            1000000ll * (mNumFramesPlayed + numAdditionalFrames)
                                / mSampleRate);

                    LOGV("%d frames left to play, %lld us (%.2f secs)",
                         numFramesPendingPlayout,
                         timeToCompletionUs, timeToCompletionUs / 1E6);

                    mObserver->postAudioEOS(timeToCompletionUs + mLatencyUs);
                }

                mReachedEOS = true;
+5 −5
Original line number Diff line number Diff line
@@ -1513,12 +1513,12 @@ void AwesomePlayer::postVideoLagEvent_l() {
    mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
}

void AwesomePlayer::postCheckAudioStatusEvent_l() {
void AwesomePlayer::postCheckAudioStatusEvent_l(int64_t delayUs) {
    if (mAudioStatusEventPending) {
        return;
    }
    mAudioStatusEventPending = true;
    mQueue.postEvent(mCheckAudioStatusEvent);
    mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
}

void AwesomePlayer::onCheckAudioStatus() {
@@ -1810,12 +1810,12 @@ uint32_t AwesomePlayer::flags() const {
    return mExtractorFlags;
}

void AwesomePlayer::postAudioEOS() {
    postCheckAudioStatusEvent_l();
void AwesomePlayer::postAudioEOS(int64_t delayUs) {
    postCheckAudioStatusEvent_l(delayUs);
}

void AwesomePlayer::postAudioSeekComplete() {
    postCheckAudioStatusEvent_l();
    postCheckAudioStatusEvent_l(0 /* delayUs */);
}

}  // namespace android
+2 −2
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ struct AwesomePlayer {
    // This is a mask of MediaExtractor::Flags.
    uint32_t flags() const;

    void postAudioEOS();
    void postAudioEOS(int64_t delayUs = 0ll);
    void postAudioSeekComplete();

private:
@@ -203,7 +203,7 @@ private:
    void postVideoEvent_l(int64_t delayUs = -1);
    void postBufferingEvent_l();
    void postStreamDoneEvent_l(status_t status);
    void postCheckAudioStatusEvent_l();
    void postCheckAudioStatusEvent_l(int64_t delayUs);
    void postVideoLagEvent_l();
    status_t play_l();