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

Commit a2c29973 authored by Andreas Huber's avatar Andreas Huber
Browse files

Alternate patch for late video issue: seek only the video ahead to the next

syncframe after the current audio media position, leave audio untouched.

Change-Id: Ia9fa8e205467e5460c8219afd396bddd09fcfb46
related-to-bug: 3375737
parent 7b76c8d3
Loading
Loading
Loading
Loading
+59 −16
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@
#include <media/stagefright/foundation/AMessage.h>

#define USE_SURFACE_ALLOC 1
#define FRAME_DROP_FREQ 7
#define FRAME_DROP_FREQ 0

namespace android {

@@ -478,7 +478,7 @@ void AwesomePlayer::reset_l() {
    mTimeSourceDeltaUs = 0;
    mVideoTimeUs = 0;

    mSeeking = false;
    mSeeking = NO_SEEK;
    mSeekNotificationSent = false;
    mSeekTimeUs = 0;

@@ -1023,7 +1023,7 @@ status_t AwesomePlayer::getPosition(int64_t *positionUs) {
    if (mRTSPController != NULL) {
        *positionUs = mRTSPController->getNormalPlayTimeUs();
    }
    else if (mSeeking) {
    else if (mSeeking != NO_SEEK) {
        *positionUs = mSeekTimeUs;
    } else if (mVideoSource != NULL) {
        Mutex::Autolock autoLock(mMiscStateLock);
@@ -1067,7 +1067,7 @@ status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
        play_l();
    }

    mSeeking = true;
    mSeeking = SEEK;
    mSeekNotificationSent = false;
    mSeekTimeUs = timeUs;
    mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
@@ -1091,7 +1091,7 @@ status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
}

void AwesomePlayer::seekAudioIfNecessary_l() {
    if (mSeeking && mVideoSource == NULL && mAudioPlayer != NULL) {
    if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
        mAudioPlayer->seekTo(mSeekTimeUs);

        mWatchForAudioSeekComplete = true;
@@ -1187,7 +1187,12 @@ status_t AwesomePlayer::initVideoDecoder(uint32_t flags) {
}

void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
    if (!mSeeking || (mFlags & SEEK_PREVIEW)) {
    if (mSeeking == SEEK_VIDEO_ONLY) {
        mSeeking = NO_SEEK;
        return;
    }

    if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
        return;
    }

@@ -1206,7 +1211,7 @@ void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
    }

    mFlags |= FIRST_FRAME;
    mSeeking = false;
    mSeeking = NO_SEEK;
    mSeekNotificationSent = false;

    if (mDecryptHandle != NULL) {
@@ -1226,13 +1231,13 @@ void AwesomePlayer::onVideoEvent() {
    }
    mVideoEventPending = false;

    if (mSeeking) {
    if (mSeeking != NO_SEEK) {
        if (mVideoBuffer) {
            mVideoBuffer->release();
            mVideoBuffer = NULL;
        }

        if (mCachedSource != NULL && mAudioSource != NULL
        if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL
                && !(mFlags & SEEK_PREVIEW)) {
            // We're going to seek the video source first, followed by
            // the audio source.
@@ -1253,11 +1258,14 @@ void AwesomePlayer::onVideoEvent() {

    if (!mVideoBuffer) {
        MediaSource::ReadOptions options;
        if (mSeeking) {
        if (mSeeking != NO_SEEK) {
            LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);

            options.setSeekTo(
                    mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
                    mSeekTimeUs,
                    mSeeking == SEEK_VIDEO_ONLY
                        ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
                        : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
        }
        for (;;) {
            status_t err = mVideoSource->read(&mVideoBuffer, &options);
@@ -1281,7 +1289,7 @@ void AwesomePlayer::onVideoEvent() {
                // So video playback is complete, but we may still have
                // a seek request pending that needs to be applied
                // to the audio track.
                if (mSeeking) {
                if (mSeeking != NO_SEEK) {
                    LOGV("video stream ended while seeking!");
                }
                finishSeekIfNecessary(-1);
@@ -1307,12 +1315,19 @@ void AwesomePlayer::onVideoEvent() {
    int64_t timeUs;
    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));

    if (mSeeking == SEEK_VIDEO_ONLY) {
        if (mSeekTimeUs > timeUs) {
            LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
                 mSeekTimeUs, timeUs);
        }
    }

    {
        Mutex::Autolock autoLock(mMiscStateLock);
        mVideoTimeUs = timeUs;
    }

    bool wasSeeking = mSeeking;
    SeekType wasSeeking = mSeeking;
    finishSeekIfNecessary(timeUs);

    if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
@@ -1337,13 +1352,41 @@ void AwesomePlayer::onVideoEvent() {
        mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
    }

    if (!wasSeeking) {
    if (wasSeeking == SEEK_VIDEO_ONLY) {
        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;

        int64_t latenessUs = nowUs - timeUs;

        if (latenessUs > 0) {
            LOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
        }
    }

    if (wasSeeking == NO_SEEK) {
        // Let's display the first frame after seeking right away.

        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;

        int64_t latenessUs = nowUs - timeUs;

        if (latenessUs > 500000ll
                && mRTSPController == NULL
                && mAudioPlayer != NULL
                && mAudioPlayer->getMediaTimeMapping(
                    &realTimeUs, &mediaTimeUs)) {
            LOGI("we're much too late (%.2f secs), video skipping ahead",
                 latenessUs / 1E6);

            mVideoBuffer->release();
            mVideoBuffer = NULL;

            mSeeking = SEEK_VIDEO_ONLY;
            mSeekTimeUs = mediaTimeUs;

            postVideoEvent_l();
            return;
        }

        if (latenessUs > 40000) {
            // We're more than 40ms late.
            LOGV("we're late by %lld us (%.2f secs)", latenessUs, latenessUs / 1E6);
@@ -1381,7 +1424,7 @@ void AwesomePlayer::onVideoEvent() {
    mVideoBuffer->release();
    mVideoBuffer = NULL;

    if (wasSeeking && (mFlags & SEEK_PREVIEW)) {
    if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
        mFlags &= ~SEEK_PREVIEW;
        return;
    }
@@ -1450,7 +1493,7 @@ void AwesomePlayer::onCheckAudioStatus() {
            mSeekNotificationSent = true;
        }

        mSeeking = false;
        mSeeking = NO_SEEK;
    }

    status_t finalStatus;
+7 −1
Original line number Diff line number Diff line
@@ -163,7 +163,13 @@ private:
    int64_t mTimeSourceDeltaUs;
    int64_t mVideoTimeUs;

    bool mSeeking;
    enum SeekType {
        NO_SEEK,
        SEEK,
        SEEK_VIDEO_ONLY
    };
    SeekType mSeeking;

    bool mSeekNotificationSent;
    int64_t mSeekTimeUs;