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