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

Commit 32b396b4 authored by Abdul Khalik Shaik's avatar Abdul Khalik Shaik
Browse files

nuplayer: ensure using video ts as anchor when really has no

audio and clearAnchor must be followed by updateAnchor in video only case

For video only clips AnchorTime is zero since it is updated only in the start. Due to this there is a delay in rendering the buffers. Video should clear and update anchor at the same time  while playback rate change. Because video postDrainVideoQueue set message kWhatDrainVideoQueue into MediaClock timer, if anchor in MediaClock is cleared, timer post message will be blocked. This will cause video stuck. So, in video only case, clearAnchor must be followed by updateAnchor immediately

Author: JiaJia Cong

Bug: 263545819

Change-Id: I58a3835aa08dfb57faf791103c8b9add0a6c502f
parent 51f16cbd
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -157,7 +157,8 @@ NuPlayer::Renderer::Renderer(
      mTotalBuffersQueued(0),
      mLastAudioBufferDrained(0),
      mUseAudioCallback(false),
      mWakeLock(new AWakeLock()) {
      mWakeLock(new AWakeLock()),
      mNeedVideoClearAnchor(false) {
    CHECK(mediaClock != NULL);
    mPlaybackRate = mPlaybackSettings.mSpeed;
    mMediaClock->setPlaybackRate(mPlaybackRate);
@@ -234,6 +235,10 @@ status_t NuPlayer::Renderer::onConfigPlayback(const AudioPlaybackRate &rate /* s
            return err;
        }
    }

    if (!mHasAudio && mHasVideo) {
        mNeedVideoClearAnchor = true;
    }
    mPlaybackSettings = rate;
    mPlaybackRate = rate.mSpeed;
    mMediaClock->setPlaybackRate(mPlaybackRate);
@@ -327,7 +332,6 @@ void NuPlayer::Renderer::flush(bool audio, bool notifyComplete) {
            mNextVideoTimeMediaUs = -1;
        }

        mMediaClock->clearAnchor();
        mVideoLateByUs = 0;
        mSyncQueues = false;
    }
@@ -1346,6 +1350,10 @@ void NuPlayer::Renderer::postDrainVideoQueue() {

    {
        Mutex::Autolock autoLock(mLock);
        if (mNeedVideoClearAnchor && !mHasAudio) {
            mNeedVideoClearAnchor = false;
            clearAnchorTime();
        }
        if (mAnchorTimeMediaUs < 0) {
            mMediaClock->updateAnchor(mediaTimeUs, nowUs, mediaTimeUs);
            mAnchorTimeMediaUs = mediaTimeUs;
@@ -1500,6 +1508,8 @@ void NuPlayer::Renderer::notifyEOS_l(bool audio, status_t finalResult, int64_t d
                        mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
            }
        }
    } else {
        mHasVideo = false;
    }
}

@@ -1661,6 +1671,7 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
        } else {
            notifyComplete = mNotifyCompleteVideo;
            mNotifyCompleteVideo = false;
            mHasVideo = false;
        }

        // If we're currently syncing the queues, i.e. dropping audio while
@@ -1673,7 +1684,17 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
        // is flushed.
        syncQueuesDone_l();
    }

    if (audio && mDrainVideoQueuePending) {
        // Audio should not clear anchor(MediaClock) directly, because video
        // postDrainVideoQueue sets msg kWhatDrainVideoQueue into MediaClock
        // timer, clear anchor without update immediately may block msg posting.
        // So, postpone clear action to video to ensure anchor can be updated
        // immediately after clear
        mNeedVideoClearAnchor = true;
    } else {
        clearAnchorTime();
    }

    ALOGV("flushing %s", audio ? "audio" : "video");
    if (audio) {
+3 −0
Original line number Diff line number Diff line
@@ -304,6 +304,9 @@ private:
    int64_t getDurationUsIfPlayedAtSampleRate(uint32_t numFrames);

    DISALLOW_EVIL_CONSTRUCTORS(Renderer);

private:
    bool mNeedVideoClearAnchor;
};

} // namespace android