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

Commit 4ecbea3a authored by Wei Jia's avatar Wei Jia
Browse files

MediaClock: prevent media time from going backwards.

Media Clock is started only when AudioSink has rendered some frames.

Bug: 25074321
Change-Id: Ic09fc666eed019e24f5b6a4b8929021eab87ca41
parent 422bf879
Loading
Loading
Loading
Loading
+34 −4
Original line number Diff line number Diff line
@@ -313,8 +313,33 @@ void NuPlayer::Renderer::setVideoFrameRate(float fps) {
    msg->post();
}

// Called on any threads.
// Called on any threads without mLock acquired.
status_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) {
    status_t result = mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
    if (result == OK) {
        return result;
    }

    // MediaClock has not started yet. Try to start it if possible.
    {
        Mutex::Autolock autoLock(mLock);
        if (mAudioFirstAnchorTimeMediaUs == -1) {
            return result;
        }

        AudioTimestamp ts;
        status_t res = mAudioSink->getTimestamp(ts);
        if (res != OK) {
            return result;
        }

        // AudioSink has rendered some frames.
        int64_t nowUs = ALooper::GetNowUs();
        int64_t nowMediaUs = getPlayedOutAudioDurationUs(nowUs)
                + mAudioFirstAnchorTimeMediaUs;
        mMediaClock->updateAnchor(nowMediaUs, nowUs, -1);
    }

    return mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
}

@@ -1010,9 +1035,14 @@ void NuPlayer::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) {
        return;
    }
    setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);

    AudioTimestamp ts;
    status_t res = mAudioSink->getTimestamp(ts);
    if (res == OK) {
        int64_t nowUs = ALooper::GetNowUs();
        int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs);
        mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs);
    }
    mAnchorNumFramesWritten = mNumFramesWritten;
    mAnchorTimeMediaUs = mediaTimeUs;
}
+16 −1
Original line number Diff line number Diff line
@@ -25,6 +25,10 @@

namespace android {

// Maximum allowed time backwards from anchor change.
// If larger than this threshold, it's treated as discontinuity.
static const int64_t kAnchorFluctuationAllowedUs = 10000ll;

MediaClock::MediaClock()
    : mAnchorTimeMediaUs(-1),
      mAnchorTimeRealUs(-1),
@@ -64,9 +68,20 @@ void MediaClock::updateAnchor(
        ALOGW("reject anchor time since it leads to negative media time.");
        return;
    }

    if (maxTimeMediaUs != -1) {
        mMaxTimeMediaUs = maxTimeMediaUs;
    }
    if (mAnchorTimeRealUs != -1) {
        int64_t oldNowMediaUs =
            mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
        if (nowMediaUs < oldNowMediaUs
                && nowMediaUs > oldNowMediaUs - kAnchorFluctuationAllowedUs) {
            return;
        }
    }
    mAnchorTimeRealUs = nowUs;
    mAnchorTimeMediaUs = nowMediaUs;
    mMaxTimeMediaUs = maxTimeMediaUs;
}

void MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) {