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

Commit 2a3af65a authored by Brian Lindahl's avatar Brian Lindahl
Browse files

Fix freeze rate calculations

Using the actual render duration to determine if the previous frame was
dropped is flawed at the beginning of playback because the first frame
never has a previous frame.

Bug: 234833109
Test: atest VideoRenderQualityTrackerTest#capturesFreezeRate
Change-Id: I6d3db5e662462ec802e368e5a611c0bbb2f463b3
parent ef881646
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -232,6 +232,7 @@ void VideoRenderQualityTracker::resetForDiscontinuity() {
    mLastContentTimeUs = -1;
    mLastRenderTimeUs = -1;
    mLastFreezeEndTimeUs = -1;
    mWasPreviousFrameDropped = false;

    // Don't worry about tracking frame rendering times from now up until playback catches up to the
    // discontinuity. While stuttering or freezing could be found in the next few frames, the impact
@@ -298,6 +299,7 @@ void VideoRenderQualityTracker::processMetricsForSkippedFrame(int64_t contentTim
    updateFrameDurations(mDesiredFrameDurationUs, -1);
    updateFrameDurations(mActualFrameDurationUs, -1);
    updateFrameRate(mMetrics.contentFrameRate, mContentFrameDurationUs, mConfiguration);
    mWasPreviousFrameDropped = false;
}

void VideoRenderQualityTracker::processMetricsForDroppedFrame(int64_t contentTimeUs,
@@ -308,6 +310,7 @@ void VideoRenderQualityTracker::processMetricsForDroppedFrame(int64_t contentTim
    updateFrameDurations(mActualFrameDurationUs, -1);
    updateFrameRate(mMetrics.contentFrameRate, mContentFrameDurationUs, mConfiguration);
    updateFrameRate(mMetrics.desiredFrameRate, mDesiredFrameDurationUs, mConfiguration);
    mWasPreviousFrameDropped = true;
}

void VideoRenderQualityTracker::processMetricsForRenderedFrame(int64_t contentTimeUs,
@@ -334,7 +337,7 @@ void VideoRenderQualityTracker::processMetricsForRenderedFrame(int64_t contentTi
    updateFrameRate(mMetrics.actualFrameRate, mActualFrameDurationUs, mConfiguration);

    // If the previous frame was dropped, there was a freeze if we've already rendered a frame
    if (mActualFrameDurationUs[1] == -1 && mLastRenderTimeUs != -1) {
    if (mWasPreviousFrameDropped && mLastRenderTimeUs != -1) {
        processFreeze(actualRenderTimeUs, mLastRenderTimeUs, mLastFreezeEndTimeUs, mMetrics);
        mLastFreezeEndTimeUs = actualRenderTimeUs;
    }
@@ -346,6 +349,8 @@ void VideoRenderQualityTracker::processMetricsForRenderedFrame(int64_t contentTi
    if (judderScore != 0) {
        mMetrics.judderScoreHistogram.insert(judderScore);
    }

    mWasPreviousFrameDropped = false;
}

void VideoRenderQualityTracker::processFreeze(int64_t actualRenderTimeUs, int64_t lastRenderTimeUs,
+3 −0
Original line number Diff line number Diff line
@@ -269,6 +269,9 @@ private:
    // The most recent timestamp of the first frame rendered after the freeze.
    int64_t mLastFreezeEndTimeUs;

    // The previous video frame was dropped.
    bool mWasPreviousFrameDropped;

    // The render duration of the playback.
    int64_t mRenderDurationMs;

+12 −0
Original line number Diff line number Diff line
@@ -232,6 +232,18 @@ TEST_F(VideoRenderQualityTrackerTest, whenFrameRateIsUnstable_doesntDetectFrameR
    EXPECT_EQ(h.getMetrics().actualFrameRate, FRAME_RATE_UNDETERMINED);
}

TEST_F(VideoRenderQualityTrackerTest, capturesFreezeRate) {
    Configuration c;
    Helper h(20, c);
    h.render(3);
    EXPECT_EQ(h.getMetrics().freezeRate, 0);
    h.drop(3);
    h.render(3);
    // +1 because the first frame before drops is considered frozen
    // and then -1 because the last frame has an unknown render duration
    EXPECT_EQ(h.getMetrics().freezeRate, 4.0 / 8.0);
}

TEST_F(VideoRenderQualityTrackerTest, capturesFreezeDurationHistogram) {
    Configuration c;
    // +17 because freeze durations include the render time of the previous frame