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

Commit cd6828e8 authored by Andreas Huber's avatar Andreas Huber Committed by Android Git Automerger
Browse files

am 2332cd8c: Merge "DO NOT MERGE: Cherry picked hacks to better hide A/V sync...

am 2332cd8c: Merge "DO NOT MERGE: Cherry picked hacks to better hide A/V sync issues." into honeycomb

* commit '2332cd8c':
  DO NOT MERGE: Cherry picked hacks to better hide A/V sync issues.
parents 350799b7 2332cd8c
Loading
Loading
Loading
Loading
+141 −60
Original line number Original line Diff line number Diff line
@@ -52,7 +52,7 @@
#include "include/LiveSession.h"
#include "include/LiveSession.h"


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


namespace android {
namespace android {


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


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


@@ -783,10 +783,19 @@ status_t AwesomePlayer::play_l() {
                mAudioPlayer = new AudioPlayer(mAudioSink, this);
                mAudioPlayer = new AudioPlayer(mAudioSink, this);
                mAudioPlayer->setSource(mAudioSource);
                mAudioPlayer->setSource(mAudioSource);


                // We've already started the MediaSource in order to enable
                mTimeSource = mAudioPlayer;
                // the prefetcher to read its data.

                status_t err = mAudioPlayer->start(
                deferredAudioSeek = true;
                        true /* sourceAlreadyStarted */);

                mWatchForAudioSeekComplete = false;
                mWatchForAudioEOS = true;
            }
        }

        CHECK(!(mFlags & AUDIO_RUNNING));

        if (mVideoSource == NULL) {
            status_t err = startAudioPlayer_l();


            if (err != OK) {
            if (err != OK) {
                delete mAudioPlayer;
                delete mAudioPlayer;
@@ -795,22 +804,12 @@ status_t AwesomePlayer::play_l() {
                mFlags &= ~(PLAYING | FIRST_FRAME);
                mFlags &= ~(PLAYING | FIRST_FRAME);


                if (mDecryptHandle != NULL) {
                if (mDecryptHandle != NULL) {
                        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
                    mDrmManagerClient->setPlaybackStatus(
                                 Playback::STOP, 0);
                            mDecryptHandle, Playback::STOP, 0);
                }
                }


                return err;
                return err;
            }
            }

                mTimeSource = mAudioPlayer;

                deferredAudioSeek = true;

                mWatchForAudioSeekComplete = false;
                mWatchForAudioEOS = true;
            }
        } else {
            mAudioPlayer->resume();
        }
        }
    }
    }


@@ -842,6 +841,36 @@ status_t AwesomePlayer::play_l() {
    return OK;
    return OK;
}
}


status_t AwesomePlayer::startAudioPlayer_l() {
    CHECK(!(mFlags & AUDIO_RUNNING));

    if (mAudioSource == NULL || mAudioPlayer == NULL) {
        return OK;
    }

    if (!(mFlags & AUDIOPLAYER_STARTED)) {
        mFlags |= AUDIOPLAYER_STARTED;

        // We've already started the MediaSource in order to enable
        // the prefetcher to read its data.
        status_t err = mAudioPlayer->start(
                true /* sourceAlreadyStarted */);

        if (err != OK) {
            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
            return err;
        }
    } else {
        mAudioPlayer->resume();
    }

    mFlags |= AUDIO_RUNNING;

    mWatchForAudioEOS = true;

    return OK;
}

void AwesomePlayer::notifyVideoSize_l() {
void AwesomePlayer::notifyVideoSize_l() {
    sp<MetaData> meta = mVideoSource->getFormat();
    sp<MetaData> meta = mVideoSource->getFormat();


@@ -943,7 +972,7 @@ status_t AwesomePlayer::pause_l(bool at_eos) {


    cancelPlayerEvents(true /* keepBufferingGoing */);
    cancelPlayerEvents(true /* keepBufferingGoing */);


    if (mAudioPlayer != NULL) {
    if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
        if (at_eos) {
        if (at_eos) {
            // If we played the audio stream to completion we
            // If we played the audio stream to completion we
            // want to make sure that all samples remaining in the audio
            // want to make sure that all samples remaining in the audio
@@ -952,6 +981,8 @@ status_t AwesomePlayer::pause_l(bool at_eos) {
        } else {
        } else {
            mAudioPlayer->pause();
            mAudioPlayer->pause();
        }
        }

        mFlags &= ~AUDIO_RUNNING;
    }
    }


    mFlags &= ~PLAYING;
    mFlags &= ~PLAYING;
@@ -1009,7 +1040,7 @@ status_t AwesomePlayer::getPosition(int64_t *positionUs) {
    if (mRTSPController != NULL) {
    if (mRTSPController != NULL) {
        *positionUs = mRTSPController->getNormalPlayTimeUs();
        *positionUs = mRTSPController->getNormalPlayTimeUs();
    }
    }
    else if (mSeeking) {
    else if (mSeeking != NO_SEEK) {
        *positionUs = mSeekTimeUs;
        *positionUs = mSeekTimeUs;
    } else if (mVideoSource != NULL) {
    } else if (mVideoSource != NULL) {
        Mutex::Autolock autoLock(mMiscStateLock);
        Mutex::Autolock autoLock(mMiscStateLock);
@@ -1053,7 +1084,7 @@ status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
        play_l();
        play_l();
    }
    }


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


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


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


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

    if (mSeeking == NO_SEEK) {
        return;
        return;
    }
    }


@@ -1179,9 +1215,7 @@ void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
        // requested seek time instead.
        // requested seek time instead.


        mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
        mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
        mAudioPlayer->resume();
        mWatchForAudioSeekComplete = true;
        mWatchForAudioSeekComplete = true;
        mWatchForAudioEOS = true;
    } else if (!mSeekNotificationSent) {
    } else if (!mSeekNotificationSent) {
        // If we're playing video only, report seek complete now,
        // If we're playing video only, report seek complete now,
        // otherwise audio player will notify us later.
        // otherwise audio player will notify us later.
@@ -1189,7 +1223,7 @@ void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
    }
    }


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


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


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


        if (mCachedSource != NULL && mAudioSource != NULL) {
        if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL) {
            // We're going to seek the video source first, followed by
            // We're going to seek the video source first, followed by
            // the audio source.
            // the audio source.
            // In order to avoid jumps in the DataSource offset caused by
            // In order to avoid jumps in the DataSource offset caused by
@@ -1224,8 +1258,10 @@ void AwesomePlayer::onVideoEvent() {
            // locations, we'll "pause" the audio source, causing it to
            // locations, we'll "pause" the audio source, causing it to
            // stop reading input data until a subsequent seek.
            // stop reading input data until a subsequent seek.


            if (mAudioPlayer != NULL) {
            if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
                mAudioPlayer->pause();
                mAudioPlayer->pause();

                mFlags &= ~AUDIO_RUNNING;
            }
            }
            mAudioSource->pause();
            mAudioSource->pause();
        }
        }
@@ -1233,11 +1269,14 @@ void AwesomePlayer::onVideoEvent() {


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


            options.setSeekTo(
            options.setSeekTo(
                    mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
                    mSeekTimeUs,
                    mSeeking == SEEK_VIDEO_ONLY
                        ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
                        : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
        }
        }
        for (;;) {
        for (;;) {
            status_t err = mVideoSource->read(&mVideoBuffer, &options);
            status_t err = mVideoSource->read(&mVideoBuffer, &options);
@@ -1261,7 +1300,7 @@ void AwesomePlayer::onVideoEvent() {
                // So video playback is complete, but we may still have
                // So video playback is complete, but we may still have
                // a seek request pending that needs to be applied
                // a seek request pending that needs to be applied
                // to the audio track.
                // to the audio track.
                if (mSeeking) {
                if (mSeeking != NO_SEEK) {
                    LOGV("video stream ended while seeking!");
                    LOGV("video stream ended while seeking!");
                }
                }
                finishSeekIfNecessary(-1);
                finishSeekIfNecessary(-1);
@@ -1287,14 +1326,29 @@ void AwesomePlayer::onVideoEvent() {
    int64_t timeUs;
    int64_t timeUs;
    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &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);
        Mutex::Autolock autoLock(mMiscStateLock);
        mVideoTimeUs = timeUs;
        mVideoTimeUs = timeUs;
    }
    }


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


    if (mAudioPlayer != NULL && !(mFlags & AUDIO_RUNNING)) {
        status_t err = startAudioPlayer_l();
        if (err != OK) {
            LOGE("Startung the audio player failed w/ err %d", err);
            return;
        }
    }

    TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
    TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;


    if (mFlags & FIRST_FRAME) {
    if (mFlags & FIRST_FRAME) {
@@ -1309,27 +1363,53 @@ void AwesomePlayer::onVideoEvent() {
        mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
        mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
    }
    }


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


        int64_t latenessUs = nowUs - timeUs;
        int64_t latenessUs = nowUs - timeUs;


    if (wasSeeking) {
        if (latenessUs > 0) {
        // Let's display the first frame after seeking right away.
            LOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
        latenessUs = 0;
        }
        }
    }

    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);


    if (mRTPSession != NULL) {
            mVideoBuffer->release();
        // We'll completely ignore timestamps for gtalk videochat
            mVideoBuffer = NULL;
        // and we'll play incoming video as fast as we get it.

        latenessUs = 0;
            mSeeking = SEEK_VIDEO_ONLY;
            mSeekTimeUs = mediaTimeUs;

            postVideoEvent_l();
            return;
        }
        }


        if (latenessUs > 40000) {
        if (latenessUs > 40000) {
            // We're more than 40ms late.
            // We're more than 40ms late.
        LOGV("we're late by %lld us (%.2f secs)", latenessUs, latenessUs / 1E6);

            LOGV("we're late by %lld us (%.2f secs)",
                 latenessUs, latenessUs / 1E6);

            if ( mSinceLastDropped > FRAME_DROP_FREQ)
            if ( mSinceLastDropped > FRAME_DROP_FREQ)
            {
            {
            LOGV("we're late by %lld us (%.2f secs) dropping one after %d frames", latenessUs, latenessUs / 1E6, mSinceLastDropped);
                LOGV("we're late by %lld us (%.2f secs) dropping one "
                     "after %d frames",
                     latenessUs, latenessUs / 1E6, mSinceLastDropped);

                mSinceLastDropped = 0;
                mSinceLastDropped = 0;
                mVideoBuffer->release();
                mVideoBuffer->release();
                mVideoBuffer = NULL;
                mVideoBuffer = NULL;
@@ -1345,6 +1425,7 @@ void AwesomePlayer::onVideoEvent() {
            postVideoEvent_l(10000);
            postVideoEvent_l(10000);
            return;
            return;
        }
        }
    }


    if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
    if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
        mVideoRendererIsPreview = false;
        mVideoRendererIsPreview = false;
@@ -1424,7 +1505,7 @@ void AwesomePlayer::onCheckAudioStatus() {
            mSeekNotificationSent = true;
            mSeekNotificationSent = true;
        }
        }


        mSeeking = false;
        mSeeking = NO_SEEK;
    }
    }


    status_t finalStatus;
    status_t finalStatus;
+12 −1
Original line number Original line Diff line number Diff line
@@ -119,6 +119,9 @@ private:
        // sufficient data to begin playback and finish the preparation phase
        // sufficient data to begin playback and finish the preparation phase
        // for good.
        // for good.
        PREPARING_CONNECTED = 2048,
        PREPARING_CONNECTED = 2048,

        AUDIO_RUNNING       = 8192,
        AUDIOPLAYER_STARTED = 16384,
    };
    };


    mutable Mutex mLock;
    mutable Mutex mLock;
@@ -160,7 +163,13 @@ private:
    int64_t mTimeSourceDeltaUs;
    int64_t mTimeSourceDeltaUs;
    int64_t mVideoTimeUs;
    int64_t mVideoTimeUs;


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

    bool mSeekNotificationSent;
    bool mSeekNotificationSent;
    int64_t mSeekTimeUs;
    int64_t mSeekTimeUs;


@@ -256,6 +265,8 @@ private:
    void finishSeekIfNecessary(int64_t videoTimeUs);
    void finishSeekIfNecessary(int64_t videoTimeUs);
    void ensureCacheIsFetching_l();
    void ensureCacheIsFetching_l();


    status_t startAudioPlayer_l();

    AwesomePlayer(const AwesomePlayer &);
    AwesomePlayer(const AwesomePlayer &);
    AwesomePlayer &operator=(const AwesomePlayer &);
    AwesomePlayer &operator=(const AwesomePlayer &);
};
};