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

Commit e2e5be00 authored by Brian Lindahl's avatar Brian Lindahl Committed by Automerger Merge Worker
Browse files

Merge "Fix frame duration computations after discontinuities" into udc-dev am:...

Merge "Fix frame duration computations after discontinuities" into udc-dev am: 03ac6df7 am: 899452a7

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/23476322



Change-Id: I70c0ad11be53733c918d20e06021d606c97c424d
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 85ab4353 899452a7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6130,7 +6130,7 @@ status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
            ALOGI("rendring output error %d", err);
        }
    } else {
        if (mIsSurfaceToDisplay) {
        if (mIsSurfaceToDisplay && buffer->size() != 0) {
            int64_t mediaTimeUs = INT64_MIN;
            if (buffer->meta()->findInt64("timeUs", &mediaTimeUs)) {
                mVideoRenderQualityTracker.onFrameSkipped(mediaTimeUs);
+16 −7
Original line number Diff line number Diff line
@@ -228,6 +228,9 @@ void VideoRenderQualityTracker::onFrameSkipped(int64_t contentTimeUs) {
    if (mLastRenderTimeUs == -1) {
        return;
    }

    resetIfDiscontinuity(contentTimeUs, -1);

    // Frames skipped at the end of playback shouldn't be counted as skipped frames, since the
    // app could be terminating the playback. The pending count will be added to the metrics if and
    // when the next frame is rendered.
@@ -374,6 +377,9 @@ void VideoRenderQualityTracker::resetForDiscontinuity() {
        mDesiredFrameDurationUs[i] = -1;
        mContentFrameDurationUs[i] = -1;
    }
    mActualFrameDurationUs.priorTimestampUs = -1;
    mDesiredFrameDurationUs.priorTimestampUs = -1;
    mContentFrameDurationUs.priorTimestampUs = -1;
}

bool VideoRenderQualityTracker::resetIfDiscontinuity(int64_t contentTimeUs,
@@ -397,11 +403,14 @@ bool VideoRenderQualityTracker::resetIfDiscontinuity(int64_t contentTimeUs,
        // occur if the time the user spends seeking is equal to the duration of the seek. This is
        // very unlikely to occur in practice but CAN occur - the user starts seeking forward, gets
        // distracted, and then returns to seeking forward.
        bool skippedForwardDueToLiveContentFrameDrops = false;
        if (desiredRenderTimeUs != -1) {
            int64_t contentFrameDurationUs = contentTimeUs - mLastContentTimeUs;
            int64_t desiredFrameDurationUs = desiredRenderTimeUs - mLastRenderTimeUs;
        bool skippedForwardDueToLiveContentFrameDrops =
            skippedForwardDueToLiveContentFrameDrops =
                    abs(contentFrameDurationUs - desiredFrameDurationUs) <
                    mConfiguration.liveContentFrameDropToleranceUs;
        }
        if (!skippedForwardDueToLiveContentFrameDrops) {
            ALOGI("Video playback jumped %d ms forward in content time (%d -> %d) ",
                int((contentTimeUs - mLastContentTimeUs) / 1000), int(mLastContentTimeUs / 1000),
@@ -475,9 +484,9 @@ void VideoRenderQualityTracker::processMetricsForRenderedFrame(int64_t contentTi
    int64_t judderScore = computePreviousJudderScore(mActualFrameDurationUs,
                                                     mContentFrameDurationUs,
                                                     mConfiguration);
    if (judderScore != 0) {
        int64_t judderTimeUs = actualRenderTimeUs - mActualFrameDurationUs[0] -
                mActualFrameDurationUs[1];
    if (judderScore != 0) {
        processJudder(judderScore, judderTimeUs, mLastJudderEndTimeUs, mActualFrameDurationUs,
                      mContentFrameDurationUs, mJudderEvent, mMetrics, mConfiguration);
        mLastJudderEndTimeUs = judderTimeUs + mActualFrameDurationUs[1];
+74 −0
Original line number Diff line number Diff line
@@ -432,6 +432,80 @@ TEST_F(VideoRenderQualityTrackerTest, detectsFrameRate) {
    EXPECT_NEAR(h.getMetrics().actualFrameRate, 60.0, 0.5);
}

TEST_F(VideoRenderQualityTrackerTest, handlesSeeking) {
    Configuration c;
    c.maxExpectedContentFrameDurationUs = 30;
    VideoRenderQualityTracker v(c);
    v.onFrameReleased(0, 0);
    v.onFrameRendered(0, 0);
    v.onFrameReleased(20, 20);
    v.onFrameRendered(20, 20);
    v.onFrameReleased(40, 40);
    v.onFrameRendered(40, 40);
    v.onFrameReleased(60, 60);
    v.onFrameRendered(60, 60);
    v.onFrameReleased(80, 80);
    v.onFrameRendered(80, 80);
    v.onFrameReleased(7200000000, 100);
    v.onFrameRendered(7200000000, 100);
    v.onFrameReleased(7200000020, 120);
    v.onFrameRendered(7200000020, 120);
    v.onFrameReleased(7200000040, 140);
    v.onFrameRendered(7200000040, 140);
    v.onFrameReleased(7200000060, 160);
    v.onFrameRendered(7200000060, 160);
    v.onFrameReleased(7200000080, 180);
    v.onFrameRendered(7200000080, 180);
    v.onFrameReleased(0, 200);
    v.onFrameRendered(0, 200);
    v.onFrameReleased(20, 220);
    v.onFrameRendered(20, 220);
    v.onFrameReleased(40, 240);
    v.onFrameRendered(40, 240);
    v.onFrameReleased(60, 260);
    v.onFrameRendered(60, 260);
    const VideoRenderQualityMetrics &m = v.getMetrics();
    EXPECT_EQ(m.judderRate, 0); // frame durations can get messed up during discontinuities so if
                                // the discontinuity is not detected, judder is expected
    EXPECT_NE(m.contentFrameRate, FRAME_RATE_UNDETERMINED);
}

TEST_F(VideoRenderQualityTrackerTest, withSkipping_handlesSeeking) {
    Configuration c;
    c.maxExpectedContentFrameDurationUs = 30;
    VideoRenderQualityTracker v(c);
    v.onFrameReleased(0, 0);
    v.onFrameRendered(0, 0);
    v.onFrameReleased(20, 20);
    v.onFrameRendered(20, 20);
    v.onFrameReleased(40, 40);
    v.onFrameRendered(40, 40);
    v.onFrameReleased(60, 60);
    v.onFrameRendered(60, 60);
    v.onFrameReleased(80, 80);
    v.onFrameRendered(80, 80);
    v.onFrameSkipped(7200000000);
    v.onFrameSkipped(7200000020);
    v.onFrameReleased(7200000040, 100);
    v.onFrameRendered(7200000040, 100);
    v.onFrameReleased(7200000060, 120);
    v.onFrameRendered(7200000060, 120);
    v.onFrameReleased(7200000080, 140);
    v.onFrameSkipped(0);
    v.onFrameRendered(7200000080, 140);
    v.onFrameSkipped(20);
    v.onFrameReleased(40, 160);
    v.onFrameRendered(40, 160);
    v.onFrameReleased(60, 180);
    v.onFrameRendered(60, 180);
    v.onFrameReleased(80, 200);
    v.onFrameRendered(80, 200);
    const VideoRenderQualityMetrics &m = v.getMetrics();
    EXPECT_EQ(m.judderRate, 0); // frame durations can get messed up during discontinuities so if
                                // the discontinuity is not detected, judder is expected
    EXPECT_NE(m.contentFrameRate, FRAME_RATE_UNDETERMINED);
}

TEST_F(VideoRenderQualityTrackerTest, whenLowTolerance_doesntDetectFrameRate) {
    Configuration c;
    c.frameRateDetectionToleranceUs = 0;