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/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 3c5cb78..bcb7695 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -967,8 +967,13 @@
// send request in mNextRequests to HAL in a batch. Return true = sucssess
bool sendRequestsBatch();
- // Calculate the expected (minimum, maximum) duration range for a request
- std::pair<nsecs_t, nsecs_t> calculateExpectedDurationRange(
+ // Calculate the expected (minimum, maximum, isFixedFps) duration info for a request
+ struct ExpectedDurationInfo {
+ nsecs_t minDuration;
+ nsecs_t maxDuration;
+ bool isFixedFps;
+ };
+ ExpectedDurationInfo calculateExpectedDurationRange(
const camera_metadata_t *request);
// Check and update latest session parameters based on the current request settings.
@@ -1087,7 +1092,7 @@
status_t registerInFlight(uint32_t frameNumber,
int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
bool callback, nsecs_t minExpectedDuration, nsecs_t maxExpectedDuration,
- const std::set<std::set<String8>>& physicalCameraIds,
+ bool isFixedFps, const std::set<std::set<String8>>& physicalCameraIds,
bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto,
const std::set<std::string>& cameraIdsWithZoom, const SurfaceMap& outputSurfaces,
nsecs_t requestTimeNs);
@@ -1339,6 +1344,9 @@
// The current minimum expected frame duration based on AE_TARGET_FPS_RANGE
nsecs_t mMinExpectedDuration = 0;
+ // Whether the camera device runs at fixed frame rate based on AE_MODE and
+ // AE_TARGET_FPS_RANGE
+ bool mIsFixedFps = false;
// Injection camera related methods.
class Camera3DeviceInjectionMethods : public virtual RefBase {