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/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 3587af4..1b4739c 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -247,9 +247,10 @@
     virtual status_t setBatchSize(size_t batchSize = 1) override;
 
     /**
-     * Notify the stream on change of min frame durations.
+     * Notify the stream on change of min frame durations or variable/fixed
+     * frame rate.
      */
-    virtual void onMinDurationChanged(nsecs_t duration) override;
+    virtual void onMinDurationChanged(nsecs_t duration, bool fixedFps) override;
 
     /**
      * Apply ZSL related consumer usage quirk.
@@ -419,6 +420,7 @@
 
     // Re-space frames by overriding timestamp to align with display Vsync.
     // Default is on for SurfaceView bound streams.
+    bool    mFixedFps = false;
     nsecs_t mMinExpectedDuration = 0;
     bool mSyncToDisplay = false;
     DisplayEventReceiver mDisplayEventReceiver;