Camera: Avoid latency accumulation when syncing preview to vsync
Currently if the capture intervals deviate from vsync intervals by more
than 5%, reset the captureToPresent offset. This could be problematic
when the camera capture intervals switches frequently between within 5%
threshold and outside 5% thread, because each time we reset the offset,
it could increase resulting in the overall latency become larger
and larger.
- Distinguish between fixed FPS and variable FPS
- For fixed FPS, if the frame duration is roughly aligned with display
refresh rate, use the current logic by enforcing a minimum frame
interval.
- For variable FPS, or fixed FPS deviating from display refresh rate,
simply find the closest timestamp in the vsync timeline.
- If we fail to find a presentation timestamp larger than the
previous frame, manually increase one vsync interval so that we don't
drop frame.
Test: Visually observe GoogleCamera 30/60/variable-fps video preview
Test: Visually observe OpenCamera photo and video preview,
Test: Camera CTS, PerformanceTest#testPreviewJitter*
Bug: 245629333
Change-Id: I4529b4fb5d2d5efd2dc8acf64f74412fbcafd67f
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index f4e3fad..e16982b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -858,12 +858,14 @@
r.resultExtras.hasReadoutTimestamp = true;
r.resultExtras.readoutTimestamp = msg.readout_timestamp;
}
- if (r.minExpectedDuration != states.minFrameDuration) {
+ if (r.minExpectedDuration != states.minFrameDuration ||
+ r.isFixedFps != states.isFixedFps) {
for (size_t i = 0; i < states.outputStreams.size(); i++) {
auto outputStream = states.outputStreams[i];
- outputStream->onMinDurationChanged(r.minExpectedDuration);
+ outputStream->onMinDurationChanged(r.minExpectedDuration, r.isFixedFps);
}
states.minFrameDuration = r.minExpectedDuration;
+ states.isFixedFps = r.isFixedFps;
}
if (r.hasCallback) {
ALOGVV("Camera %s: %s: Shutter fired for frame %d (id %d) at %" PRId64,