Camera: Address time drift in presentation time
Consecutive expected presentation times returned from VsyncEventData
may fall into the same Vsync interval due to time drift. Mitigate the
problem by sutracting 1/3 of Vsync frame interval from the expected
presentation time.
Also added a varialbe initilization.
Frame miss+drop rates in 3 min tests:
60fps: 0.3%
30fps: 0.3%
60/30 dynamic frame rate: 1.7%
Test: Inspect the frame miss/drop rate via trace
Bug: 226242194
Change-Id: I93ecaeb72cf4520e1752c6ec948895af753c140b
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index b822178..37f9227 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -379,8 +379,6 @@
nsecs_t captureTime = (mSyncToDisplay ? readoutTimestamp : timestamp) - mTimestampOffset;
nsecs_t presentTime = mSyncToDisplay ?
syncTimestampToDisplayLocked(captureTime) : captureTime;
- mLastCaptureTime = captureTime;
- mLastPresentTime = presentTime;
setTransform(transform, true/*mayChangeMirror*/);
res = native_window_set_buffers_timestamp(mConsumer.get(), presentTime);
@@ -1267,6 +1265,8 @@
if (res != OK) {
ALOGE("%s: Stream %d: Error getting latest vsync event data: %s (%d)",
__FUNCTION__, mId, strerror(-res), res);
+ mLastCaptureTime = t;
+ mLastPresentTime = t;
return t;
}
@@ -1286,7 +1286,7 @@
}
nsecs_t idealPresentT = t + mCaptureToPresentOffset;
- nsecs_t expectedPresentT = 0;
+ nsecs_t expectedPresentT = mLastPresentTime;
nsecs_t minDiff = INT64_MAX;
// Derive minimum intervals between presentation times based on minimal
// expected duration.
@@ -1306,7 +1306,14 @@
minDiff = std::abs(vsyncTime.expectedPresentationTime - idealPresentT);
}
}
- return expectedPresentT;
+ mLastCaptureTime = t;
+ mLastPresentTime = expectedPresentT;
+
+ // Move the expected presentation time back by 1/3 of frame interval to
+ // mitigate the time drift. Due to time drift, if we directly use the
+ // expected presentation time, often times 2 expected presentation time
+ // falls into the same VSYNC interval.
+ return expectedPresentT - vsyncEventData.frameInterval/3;
}
}; // namespace camera3