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

Commit 1375ac6d authored by Lajos Molnar's avatar Lajos Molnar Committed by Android (Google) Code Review
Browse files

Merge "NuPlayer: query current position from NuPlayerRenderer." into lmp-dev

parents 2edda09a a73d9e0b
Loading
Loading
Loading
Loading
+20 −28
Original line number Diff line number Diff line
@@ -151,7 +151,6 @@ private:
NuPlayer::NuPlayer()
    : mUIDValid(false),
      mSourceFlags(0),
      mCurrentPositionUs(0),
      mVideoIsAVC(false),
      mOffloadAudio(false),
      mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
@@ -169,7 +168,6 @@ NuPlayer::NuPlayer()
      mFlushingVideo(NONE),
      mSkipRenderingAudioUntilMediaTimeUs(-1ll),
      mSkipRenderingVideoUntilMediaTimeUs(-1ll),
      mVideoLateByUs(0ll),
      mNumFramesTotal(0ll),
      mNumFramesDropped(0ll),
      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
@@ -546,8 +544,11 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                    // the extractor may not yet be started and will assert.
                    // If the video decoder is not set (perhaps audio only in this case)
                    // do not perform a seek as it is not needed.
                    int64_t currentPositionUs = 0;
                    if (getCurrentPosition(&currentPositionUs) == OK) {
                        mDeferredActions.push_back(
                            new SeekAction(mCurrentPositionUs, false /* needNotify */));
                                new SeekAction(currentPositionUs, false /* needNotify */));
                    }
                }

                // If there is a new surface texture, instantiate decoders
@@ -581,7 +582,6 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
            mVideoEOS = false;
            mSkipRenderingAudioUntilMediaTimeUs = -1;
            mSkipRenderingVideoUntilMediaTimeUs = -1;
            mVideoLateByUs = 0;
            mNumFramesTotal = 0;
            mNumFramesDropped = 0;
            mStarted = true;
@@ -889,22 +889,6 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                        && (mVideoEOS || mVideoDecoder == NULL)) {
                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
                }
            } else if (what == Renderer::kWhatPosition) {
                int64_t positionUs;
                CHECK(msg->findInt64("positionUs", &positionUs));
                mCurrentPositionUs = positionUs;

                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));

                if (mDriver != NULL) {
                    sp<NuPlayerDriver> driver = mDriver.promote();
                    if (driver != NULL) {
                        driver->notifyPosition(positionUs);

                        driver->notifyFrameStats(
                                mNumFramesTotal, mNumFramesDropped);
                    }
                }
            } else if (what == Renderer::kWhatFlushComplete) {
                int32_t audio;
                CHECK(msg->findInt32("audio", &audio));
@@ -1053,10 +1037,6 @@ void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
        case FLUSHING_DECODER:
        {
            *state = FLUSHED;

            if (!audio) {
                mVideoLateByUs = 0;
            }
            break;
        }

@@ -1066,7 +1046,6 @@ void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {

            ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
            if (!audio) {
                mVideoLateByUs = 0;
                // Widevine source reads must stop before releasing the video decoder.
                if (mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
                    mSource->stop();
@@ -1487,7 +1466,7 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
        dropAccessUnit = false;
        if (!audio
                && !(mSourceFlags & Source::FLAG_SECURE)
                && mVideoLateByUs > 100000ll
                && mRenderer->getVideoLateByUs() > 100000ll
                && mVideoIsAVC
                && !IsAVCReferenceFrame(accessUnit)) {
            dropAccessUnit = true;
@@ -1822,6 +1801,20 @@ status_t NuPlayer::selectTrack(size_t trackIndex, bool select) {
    return err;
}

status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
    sp<Renderer> renderer = mRenderer;
    if (renderer == NULL) {
        return NO_INIT;
    }

    return renderer->getCurrentPosition(mediaUs);
}

void NuPlayer::getStats(int64_t *numFramesTotal, int64_t *numFramesDropped) {
    *numFramesTotal = mNumFramesTotal;
    *numFramesDropped = mNumFramesDropped;
}

sp<MetaData> NuPlayer::getFileMeta() {
    return mSource->getFileFormatMeta();
}
@@ -1879,7 +1872,6 @@ void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) {
    if (mDriver != NULL) {
        sp<NuPlayerDriver> driver = mDriver.promote();
        if (driver != NULL) {
            driver->notifyPosition(seekTimeUs);
            if (needNotify) {
                driver->notifySeekComplete();
            }
+2 −2
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ struct NuPlayer : public AHandler {
    status_t getTrackInfo(Parcel* reply) const;
    status_t getSelectedTrack(int32_t type, Parcel* reply) const;
    status_t selectTrack(size_t trackIndex, bool select);
    status_t getCurrentPosition(int64_t *mediaUs);
    void getStats(int64_t *mNumFramesTotal, int64_t *mNumFramesDropped);

    sp<MetaData> getFileMeta();

@@ -126,7 +128,6 @@ private:
    sp<Source> mSource;
    uint32_t mSourceFlags;
    sp<NativeWindowWrapper> mNativeWindow;
    int64_t mCurrentPositionUs;
    sp<MediaPlayerBase::AudioSink> mAudioSink;
    sp<Decoder> mVideoDecoder;
    bool mVideoIsAVC;
@@ -179,7 +180,6 @@ private:
    int64_t mSkipRenderingAudioUntilMediaTimeUs;
    int64_t mSkipRenderingVideoUntilMediaTimeUs;

    int64_t mVideoLateByUs;
    int64_t mNumFramesTotal, mNumFramesDropped;

    int32_t mVideoScalingMode;
+21 −73
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>

@@ -38,10 +39,7 @@ NuPlayerDriver::NuPlayerDriver()
      mSetSurfaceInProgress(false),
      mDurationUs(-1),
      mPositionUs(-1),
      mNotifyTimeRealUs(-1),
      mPauseStartedTimeUs(-1),
      mNumFramesTotal(0),
      mNumFramesDropped(0),
      mSeekInProgress(false),
      mLooper(new ALooper),
      mPlayerFlags(0),
      mAtEOS(false),
@@ -276,14 +274,6 @@ status_t NuPlayerDriver::start() {
                mPositionUs = -1;
            } else {
                mPlayer->resume();
                if (mNotifyTimeRealUs != -1) {
                    // Pause time must be set if here by setPauseStartedTimeIfNeeded().
                    //CHECK(mPauseStartedTimeUs != -1);

                    // if no seek occurs, adjust our notify time so that getCurrentPosition()
                    // is continuous if read immediately after calling start().
                    mNotifyTimeRealUs += ALooper::GetNowUs() - mPauseStartedTimeUs;
                }
            }
            break;
        }
@@ -293,7 +283,6 @@ status_t NuPlayerDriver::start() {
    }

    mState = STATE_RUNNING;
    mPauseStartedTimeUs = -1;

    return OK;
}
@@ -322,7 +311,6 @@ status_t NuPlayerDriver::stop() {
        default:
            return INVALID_OPERATION;
    }
    setPauseStartedTimeIfNeeded();

    return OK;
}
@@ -336,7 +324,6 @@ status_t NuPlayerDriver::pause() {
            return OK;

        case STATE_RUNNING:
            setPauseStartedTimeIfNeeded();
            mState = STATE_PAUSED;
            notifyListener_l(MEDIA_PAUSED);
            mPlayer->pause();
@@ -374,6 +361,7 @@ status_t NuPlayerDriver::seekTo(int msec) {
        case STATE_PAUSED:
        {
            mAtEOS = false;
            mSeekInProgress = true;
            // seeks can take a while, so we essentially paused
            notifyListener_l(MEDIA_PAUSED);
            mPlayer->seekToAsync(seekTimeUs, true /* needNotify */);
@@ -385,44 +373,23 @@ status_t NuPlayerDriver::seekTo(int msec) {
    }

    mPositionUs = seekTimeUs;
    mNotifyTimeRealUs = -1;
    return OK;
}

status_t NuPlayerDriver::getCurrentPosition(int *msec) {
    Mutex::Autolock autoLock(mLock);
    int64_t tempUs = 0;
    status_t ret = mPlayer->getCurrentPosition(&tempUs);

    if (mPositionUs < 0) {
        // mPositionUs is the media time.
        // It is negative under these cases
        // (1) == -1 after reset, or very first playback, no stream notification yet.
        // (2) == -1 start after end of stream, no stream notification yet.
        // (3) == large negative # after ~292,471 years of continuous playback.

        //CHECK_EQ(mPositionUs, -1);
        *msec = 0;
    } else if (mNotifyTimeRealUs == -1) {
        // A seek has occurred just occurred, no stream notification yet.
        // mPositionUs (>= 0) is the new media position.
        *msec = mPositionUs / 1000;
    Mutex::Autolock autoLock(mLock);
    // We need to check mSeekInProgress here because mPlayer->seekToAsync is an async call, which
    // means getCurrentPosition can be called before seek is completed. Iow, renderer may return a
    // position value that's different the seek to position.
    if (ret != OK || mSeekInProgress) {
        tempUs = (mPositionUs <= 0) ? 0 : mPositionUs;
    } else {
        // mPosition must be valid (i.e. >= 0) by the first check above.
        // We're either playing or have pause time set: mPauseStartedTimeUs is >= 0
        //LOG_ALWAYS_FATAL_IF(
        //        !isPlaying() && mPauseStartedTimeUs < 0,
        //        "Player in non-playing mState(%d) and mPauseStartedTimeUs(%lld) < 0",
        //        mState, (long long)mPauseStartedTimeUs);
        ALOG_ASSERT(mNotifyTimeRealUs >= 0);
        int64_t nowUs =
                (isPlaying() ?  ALooper::GetNowUs() : mPauseStartedTimeUs);
        *msec = (mPositionUs + nowUs - mNotifyTimeRealUs + 500ll) / 1000;
        // It is possible for *msec to be negative if the media position is > 596 hours.
        // but we turn on this checking in NDEBUG == 0 mode.
        ALOG_ASSERT(*msec >= 0);
        ALOGV("getCurrentPosition nowUs(%lld)", (long long)nowUs);
    }
    ALOGV("getCurrentPosition returning(%d) mPositionUs(%lld) mNotifyRealTimeUs(%lld)",
            *msec, (long long)mPositionUs, (long long)mNotifyTimeRealUs);
        mPositionUs = tempUs;
    }
    *msec = (int)divRound(tempUs, (int64_t)(1000));
    return OK;
}

@@ -605,17 +572,10 @@ void NuPlayerDriver::notifyDuration(int64_t durationUs) {
    mDurationUs = durationUs;
}

void NuPlayerDriver::notifyPosition(int64_t positionUs) {
    Mutex::Autolock autoLock(mLock);
    if (isPlaying()) {
        mPositionUs = positionUs;
        mNotifyTimeRealUs = ALooper::GetNowUs();
    }
}

void NuPlayerDriver::notifySeekComplete() {
    ALOGV("notifySeekComplete(%p)", this);
    Mutex::Autolock autoLock(mLock);
    mSeekInProgress = false;
    notifySeekComplete_l();
}

@@ -636,26 +596,21 @@ void NuPlayerDriver::notifySeekComplete_l() {
    notifyListener_l(wasSeeking ? MEDIA_SEEK_COMPLETE : MEDIA_PREPARED);
}

void NuPlayerDriver::notifyFrameStats(
        int64_t numFramesTotal, int64_t numFramesDropped) {
    Mutex::Autolock autoLock(mLock);
    mNumFramesTotal = numFramesTotal;
    mNumFramesDropped = numFramesDropped;
}

status_t NuPlayerDriver::dump(
        int fd, const Vector<String16> & /* args */) const {
    Mutex::Autolock autoLock(mLock);
    int64_t numFramesTotal;
    int64_t numFramesDropped;
    mPlayer->getStats(&numFramesTotal, &numFramesDropped);

    FILE *out = fdopen(dup(fd), "w");

    fprintf(out, " NuPlayer\n");
    fprintf(out, "  numFramesTotal(%" PRId64 "), numFramesDropped(%" PRId64 "), "
                 "percentageDropped(%.2f)\n",
                 mNumFramesTotal,
                 mNumFramesDropped,
                 mNumFramesTotal == 0
                    ? 0.0 : (double)mNumFramesDropped / mNumFramesTotal);
                 numFramesTotal,
                 numFramesDropped,
                 numFramesTotal == 0
                    ? 0.0 : (double)numFramesDropped / numFramesTotal);

    fclose(out);
    out = NULL;
@@ -690,7 +645,6 @@ void NuPlayerDriver::notifyListener_l(
        case MEDIA_ERROR:
        {
            mAtEOS = true;
            setPauseStartedTimeIfNeeded();
            break;
        }

@@ -758,10 +712,4 @@ void NuPlayerDriver::notifyFlagsChanged(uint32_t flags) {
    mPlayerFlags = flags;
}

void NuPlayerDriver::setPauseStartedTimeIfNeeded() {
    if (mPauseStartedTimeUs == -1) {
        mPauseStartedTimeUs = ALooper::GetNowUs();
    }
}

}  // namespace android
+1 −7
Original line number Diff line number Diff line
@@ -68,10 +68,8 @@ struct NuPlayerDriver : public MediaPlayerInterface {
    void notifyResetComplete();
    void notifySetSurfaceComplete();
    void notifyDuration(int64_t durationUs);
    void notifyPosition(int64_t positionUs);
    void notifySeekComplete();
    void notifySeekComplete_l();
    void notifyFrameStats(int64_t numFramesTotal, int64_t numFramesDropped);
    void notifyListener(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
    void notifyFlagsChanged(uint32_t flags);

@@ -106,10 +104,7 @@ private:
    bool mSetSurfaceInProgress;
    int64_t mDurationUs;
    int64_t mPositionUs;
    int64_t mNotifyTimeRealUs;
    int64_t mPauseStartedTimeUs;
    int64_t mNumFramesTotal;
    int64_t mNumFramesDropped;
    bool mSeekInProgress;
    // <<<

    sp<ALooper> mLooper;
@@ -125,7 +120,6 @@ private:

    status_t prepare_l();
    void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
    void setPauseStartedTimeIfNeeded();

    DISALLOW_EVIL_CONSTRUCTORS(NuPlayerDriver);
};
+124 −108
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>

@@ -63,22 +64,21 @@ NuPlayer::Renderer::Renderer(
      mDrainVideoQueuePending(false),
      mAudioQueueGeneration(0),
      mVideoQueueGeneration(0),
      mFirstAnchorTimeMediaUs(-1),
      mAnchorTimeMediaUs(-1),
      mAnchorTimeRealUs(-1),
      mFlushingAudio(false),
      mFlushingVideo(false),
      mAudioFirstAnchorTimeMediaUs(-1),
      mVideoAnchorTimeMediaUs(-1),
      mVideoAnchorTimeRealUs(-1),
      mVideoLateByUs(0ll),
      mHasAudio(false),
      mHasVideo(false),
      mPauseStartedTimeRealUs(-1),
      mFlushingAudio(false),
      mFlushingVideo(false),
      mSyncQueues(false),
      mPaused(false),
      mPauseStartedTimeRealUs(-1),
      mVideoSampleReceived(false),
      mVideoRenderingStarted(false),
      mVideoRenderingStartGeneration(0),
      mAudioRenderingStartGeneration(0),
      mLastPositionUpdateUs(-1ll),
      mVideoLateByUs(0ll),
      mAudioOffloadPauseTimeoutGeneration(0),
      mAudioOffloadTornDown(false) {
    readProperties();
@@ -137,9 +137,9 @@ void NuPlayer::Renderer::signalTimeDiscontinuity() {
    Mutex::Autolock autoLock(mLock);
    // CHECK(mAudioQueue.empty());
    // CHECK(mVideoQueue.empty());
    mFirstAnchorTimeMediaUs = -1;
    mAnchorTimeMediaUs = -1;
    mAnchorTimeRealUs = -1;
    setAudioFirstAnchorTime(-1);
    setVideoAnchorTime(-1, -1);
    setVideoLateByUs(0);
    mSyncQueues = false;
}

@@ -165,6 +165,78 @@ void NuPlayer::Renderer::setVideoFrameRate(float fps) {
    msg->post();
}

status_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) {
    return getCurrentPosition(mediaUs, ALooper::GetNowUs());
}

status_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs, int64_t nowUs) {
    Mutex::Autolock autoLock(mTimeLock);
    if (!mHasAudio && !mHasVideo) {
        return NO_INIT;
    }

    int64_t positionUs = 0;
    if (!mHasAudio) {
        if (mVideoAnchorTimeMediaUs < 0) {
            return NO_INIT;
        }
        positionUs = (nowUs - mVideoAnchorTimeRealUs) + mVideoAnchorTimeMediaUs;

        if (mPauseStartedTimeRealUs != -1) {
            positionUs -= (nowUs - mPauseStartedTimeRealUs);
        }
    } else {
        if (mAudioFirstAnchorTimeMediaUs < 0) {
            return NO_INIT;
        }
        positionUs = mAudioFirstAnchorTimeMediaUs + getPlayedOutAudioDurationUs(nowUs);
    }
    *mediaUs = (positionUs <= 0) ? 0 : positionUs;
    return OK;
}

void NuPlayer::Renderer::setHasMedia(bool audio) {
    Mutex::Autolock autoLock(mTimeLock);
    if (audio) {
        mHasAudio = true;
    } else {
        mHasVideo = true;
    }
}

void NuPlayer::Renderer::setAudioFirstAnchorTime(int64_t mediaUs) {
    Mutex::Autolock autoLock(mTimeLock);
    mAudioFirstAnchorTimeMediaUs = mediaUs;
}

void NuPlayer::Renderer::setAudioFirstAnchorTimeIfNeeded(int64_t mediaUs) {
    Mutex::Autolock autoLock(mTimeLock);
    if (mAudioFirstAnchorTimeMediaUs == -1) {
        mAudioFirstAnchorTimeMediaUs = mediaUs;
    }
}

void NuPlayer::Renderer::setVideoAnchorTime(int64_t mediaUs, int64_t realUs) {
    Mutex::Autolock autoLock(mTimeLock);
    mVideoAnchorTimeMediaUs = mediaUs;
    mVideoAnchorTimeRealUs = realUs;
}

void NuPlayer::Renderer::setVideoLateByUs(int64_t lateUs) {
    Mutex::Autolock autoLock(mTimeLock);
    mVideoLateByUs = lateUs;
}

int64_t NuPlayer::Renderer::getVideoLateByUs() {
    Mutex::Autolock autoLock(mTimeLock);
    return mVideoLateByUs;
}

void NuPlayer::Renderer::setPauseStartedTimeRealUs(int64_t realUs) {
    Mutex::Autolock autoLock(mTimeLock);
    mPauseStartedTimeRealUs = realUs;
}

void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatStopAudioSink:
@@ -388,16 +460,7 @@ size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) {
            int64_t mediaTimeUs;
            CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
            ALOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6);
            if (mFirstAnchorTimeMediaUs == -1) {
                mFirstAnchorTimeMediaUs = mediaTimeUs;
            }

            int64_t nowUs = ALooper::GetNowUs();
            mAnchorTimeMediaUs =
                mFirstAnchorTimeMediaUs + getPlayedOutAudioDurationUs(nowUs);
            mAnchorTimeRealUs = nowUs;

            notifyPosition();
            setAudioFirstAnchorTimeIfNeeded(mediaTimeUs);
        }

        size_t copy = entry->mBuffer->size() - entry->mOffset;
@@ -468,15 +531,8 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
            int64_t mediaTimeUs;
            CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
            ALOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6);
            if (mFirstAnchorTimeMediaUs == -1) {
                mFirstAnchorTimeMediaUs = mediaTimeUs;
            }
            mAnchorTimeMediaUs = mediaTimeUs;

            int64_t nowUs = ALooper::GetNowUs();
            mAnchorTimeRealUs = nowUs + getPendingAudioPlayoutDurationUs(nowUs);

            notifyPosition();
            setAudioFirstAnchorTimeIfNeeded(mediaTimeUs);
        }

        size_t copy = entry->mBuffer->size() - entry->mOffset;
@@ -534,6 +590,14 @@ int64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) {
    return writtenAudioDurationUs - getPlayedOutAudioDurationUs(nowUs);
}

int64_t NuPlayer::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) {
    int64_t currentPositionUs;
    if (getCurrentPosition(&currentPositionUs, nowUs) != OK) {
        currentPositionUs = 0;
    }
    return (mediaTimeUs - currentPositionUs) + nowUs;
}

void NuPlayer::Renderer::postDrainVideoQueue() {
    if (mDrainVideoQueuePending
            || mSyncQueues
@@ -568,21 +632,11 @@ void NuPlayer::Renderer::postDrainVideoQueue() {
        int64_t mediaTimeUs;
        CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));

        if (mFirstAnchorTimeMediaUs == -1 && !mHasAudio) {
            mFirstAnchorTimeMediaUs = mediaTimeUs;
        }
        if (mAnchorTimeMediaUs < 0) {
            if (!mHasAudio) {
                mAnchorTimeMediaUs = mediaTimeUs;
                mAnchorTimeRealUs = nowUs;
                if (!mPaused || mVideoSampleReceived) {
                    notifyPosition();
                }
            }
        if (mVideoAnchorTimeMediaUs < 0) {
            setVideoAnchorTime(mediaTimeUs, nowUs);
            realTimeUs = nowUs;
        } else {
            realTimeUs =
                (mediaTimeUs - mAnchorTimeMediaUs) + mAnchorTimeRealUs;
            realTimeUs = getRealTimeUs(mediaTimeUs, nowUs);
        }
    }

@@ -618,10 +672,11 @@ void NuPlayer::Renderer::onDrainVideoQueue() {
        mVideoQueue.erase(mVideoQueue.begin());
        entry = NULL;

        mVideoLateByUs = 0ll;
        setVideoLateByUs(0);
        return;
    }

    int64_t nowUs = -1;
    int64_t realTimeUs;
    if (mFlags & FLAG_REAL_TIME) {
        CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs));
@@ -629,13 +684,17 @@ void NuPlayer::Renderer::onDrainVideoQueue() {
        int64_t mediaTimeUs;
        CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));

        realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs;
        nowUs = ALooper::GetNowUs();
        realTimeUs = getRealTimeUs(mediaTimeUs, nowUs);
    }

    bool tooLate = false;

    if (!mPaused) {
        mVideoLateByUs = ALooper::GetNowUs() - realTimeUs;
        if (nowUs == -1) {
            nowUs = ALooper::GetNowUs();
        }
        setVideoLateByUs(nowUs - realTimeUs);
        tooLate = (mVideoLateByUs > 40000);

        if (tooLate) {
@@ -644,13 +703,14 @@ void NuPlayer::Renderer::onDrainVideoQueue() {
        } else {
            ALOGV("rendering video at media time %.2f secs",
                    (mFlags & FLAG_REAL_TIME ? realTimeUs :
                    (realTimeUs + mAnchorTimeMediaUs - mAnchorTimeRealUs)) / 1E6);
                    (realTimeUs + mVideoAnchorTimeMediaUs - mVideoAnchorTimeRealUs)) / 1E6);
        }
    } else {
        mVideoLateByUs = 0ll;
        if (!mHasAudio && !mVideoSampleReceived) {
            mAnchorTimeMediaUs = -1;
            mAnchorTimeRealUs = -1;
        setVideoLateByUs(0);
        if (!mVideoSampleReceived) {
            // This will ensure that the first frame after a flush won't be used as anchor
            // when renderer is in paused state, because resume can happen any time after seek.
            setVideoAnchorTime(-1, -1);
        }
    }

@@ -693,10 +753,9 @@ void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
    int32_t audio;
    CHECK(msg->findInt32("audio", &audio));

    if (audio) {
        mHasAudio = true;
    } else {
        mHasVideo = true;
    setHasMedia(audio);

    if (mHasVideo) {
        if (mVideoScheduler == NULL) {
            mVideoScheduler = new VideoFrameScheduler();
            mVideoScheduler->init();
@@ -837,9 +896,7 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
    {
         Mutex::Autolock autoLock(mLock);
         syncQueuesDone_l();
         if (!mHasAudio) {
             mPauseStartedTimeRealUs = -1;
         }
         setPauseStartedTimeRealUs(-1);
    }

    ALOGV("flushing %s", audio ? "audio" : "video");
@@ -852,7 +909,7 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
            prepareForMediaRenderingStart();

            if (offloadingAudio()) {
                mFirstAnchorTimeMediaUs = -1;
                setAudioFirstAnchorTime(-1);
            }
        }

@@ -943,42 +1000,6 @@ void NuPlayer::Renderer::onDisableOffloadAudio() {
    ++mAudioQueueGeneration;
}

void NuPlayer::Renderer::notifyPosition() {
    // notifyPosition() must be called only after setting mAnchorTimeRealUs
    // and mAnchorTimeMediaUs, and must not be paused as it extrapolates position.
    //CHECK_GE(mAnchorTimeRealUs, 0);
    //CHECK_GE(mAnchorTimeMediaUs, 0);
    //CHECK(!mPaused || !mHasAudio);  // video-only does display in paused mode.

    int64_t nowUs = ALooper::GetNowUs();

    if (mLastPositionUpdateUs >= 0
            && nowUs < mLastPositionUpdateUs + kMinPositionUpdateDelayUs) {
        return;
    }
    mLastPositionUpdateUs = nowUs;

    int64_t positionUs = (nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs;

    //ALOGD("notifyPosition: positionUs(%lld) nowUs(%lld) mAnchorTimeRealUs(%lld)"
    //        " mAnchorTimeMediaUs(%lld) mFirstAnchorTimeMediaUs(%lld)",
    //        (long long)positionUs, (long long)nowUs, (long long)mAnchorTimeRealUs,
    //        (long long)mAnchorTimeMediaUs, (long long)mFirstAnchorTimeMediaUs);

    // Due to adding the latency to mAnchorTimeRealUs in onDrainAudioQueue(),
    // positionUs may be less than the first media time.  This is avoided
    // here to prevent potential retrograde motion of the position bar
    // when starting up after a seek.
    if (positionUs < mFirstAnchorTimeMediaUs) {
        positionUs = mFirstAnchorTimeMediaUs;
    }
    sp<AMessage> notify = mNotify->dup();
    notify->setInt32("what", kWhatPosition);
    notify->setInt64("positionUs", positionUs);
    notify->setInt64("videoLateByUs", mVideoLateByUs);
    notify->post();
}

void NuPlayer::Renderer::onPause() {
    if (mPaused) {
        ALOGW("Renderer::onPause() called while already paused!");
@@ -990,9 +1011,7 @@ void NuPlayer::Renderer::onPause() {
        ++mVideoQueueGeneration;
        prepareForMediaRenderingStart();
        mPaused = true;
        if (!mHasAudio) {
            mPauseStartedTimeRealUs = ALooper::GetNowUs();
        }
        setPauseStartedTimeRealUs(ALooper::GetNowUs());
    }

    mDrainAudioQueuePending = false;
@@ -1021,9 +1040,11 @@ void NuPlayer::Renderer::onResume() {

    Mutex::Autolock autoLock(mLock);
    mPaused = false;
    if (!mHasAudio && mPauseStartedTimeRealUs != -1) {
        mAnchorTimeRealUs += ALooper::GetNowUs() - mPauseStartedTimeRealUs;
        mPauseStartedTimeRealUs = -1;
    if (mPauseStartedTimeRealUs != -1) {
        int64_t newAnchorRealUs =
            mVideoAnchorTimeRealUs + ALooper::GetNowUs() - mPauseStartedTimeRealUs;
        setVideoAnchorTime(mVideoAnchorTimeMediaUs, newAnchorRealUs);
        setPauseStartedTimeRealUs(-1);
    }

    if (!mAudioQueue.empty()) {
@@ -1045,7 +1066,6 @@ void NuPlayer::Renderer::onSetVideoFrameRate(float fps) {
// TODO: Remove unnecessary calls to getPlayedOutAudioDurationUs()
// as it acquires locks and may query the audio driver.
//
// Some calls are not needed since notifyPosition() doesn't always deliver a message.
// Some calls could conceivably retrieve extrapolated data instead of
// accessing getTimestamp() or getPosition() every time a data buffer with
// a media time is received.
@@ -1113,15 +1133,11 @@ void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reaso
    }
    mAudioOffloadTornDown = true;

    int64_t firstAudioTimeUs;
    {
        Mutex::Autolock autoLock(mLock);
        firstAudioTimeUs = mFirstAnchorTimeMediaUs;
    int64_t currentPositionUs;
    if (getCurrentPosition(&currentPositionUs) != OK) {
        currentPositionUs = 0;
    }

    int64_t currentPositionUs =
        firstAudioTimeUs + getPlayedOutAudioDurationUs(ALooper::GetNowUs());

    mAudioSink->stop();
    mAudioSink->flush();

Loading