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
diff --git a/media/libstagefright/VideoRenderQualityTracker.cpp b/media/libstagefright/VideoRenderQualityTracker.cpp
index df25ead..239aefc 100644
--- a/media/libstagefright/VideoRenderQualityTracker.cpp
+++ b/media/libstagefright/VideoRenderQualityTracker.cpp
@@ -232,6 +232,7 @@
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 @@
updateFrameDurations(mDesiredFrameDurationUs, -1);
updateFrameDurations(mActualFrameDurationUs, -1);
updateFrameRate(mMetrics.contentFrameRate, mContentFrameDurationUs, mConfiguration);
+ mWasPreviousFrameDropped = false;
}
void VideoRenderQualityTracker::processMetricsForDroppedFrame(int64_t contentTimeUs,
@@ -308,6 +310,7 @@
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 @@
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 @@
if (judderScore != 0) {
mMetrics.judderScoreHistogram.insert(judderScore);
}
+
+ mWasPreviousFrameDropped = false;
}
void VideoRenderQualityTracker::processFreeze(int64_t actualRenderTimeUs, int64_t lastRenderTimeUs,
diff --git a/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h b/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h
index 8bfead9..5cf674f 100644
--- a/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h
+++ b/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h
@@ -269,6 +269,9 @@
// 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;
diff --git a/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp b/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp
index 9f14663..aca31f2 100644
--- a/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp
+++ b/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp
@@ -232,6 +232,18 @@
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