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

Commit 03ac6df7 authored by Brian Lindahl's avatar Brian Lindahl Committed by Android (Google) Code Review
Browse files

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

parents d9e39c7a 544a22c0
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;