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

Commit c8e14bf5 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

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

parents 2e28aa89 4dc482da
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -108,6 +108,8 @@ private:


    void reset();
    void reset();


    uint32_t getNumFramesPendingPlayout() const;

    AudioPlayer(const AudioPlayer &);
    AudioPlayer(const AudioPlayer &);
    AudioPlayer &operator=(const AudioPlayer &);
    AudioPlayer &operator=(const AudioPlayer &);
};
};
+48 −1
Original line number Original line Diff line number Diff line
@@ -280,6 +280,26 @@ void AudioPlayer::AudioCallback(int event, void *info) {
    buffer->size = numBytesWritten;
    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) {
size_t AudioPlayer::fillBuffer(void *data, size_t size) {
    if (mNumFramesPlayed == 0) {
    if (mNumFramesPlayed == 0) {
        LOGV("AudioCallback");
        LOGV("AudioCallback");
@@ -342,7 +362,34 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {


            if (err != OK) {
            if (err != OK) {
                if (mObserver && !mReachedEOS) {
                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;
                mReachedEOS = true;
+5 −5
Original line number Original line Diff line number Diff line
@@ -1513,12 +1513,12 @@ void AwesomePlayer::postVideoLagEvent_l() {
    mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
    mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
}
}


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


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


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


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


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


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


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