Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df29025a authored by Shuzhen Wang's avatar Shuzhen Wang Committed by Automerger Merge Worker
Browse files

Camera: Handle deviation between frame duration and vsync intervals am: 34a5e28c

parents f2f3e7ad 34a5e28c
Loading
Loading
Loading
Loading
+24 −7
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0

#include <algorithm>
#include <ctime>
#include <fstream>

@@ -1392,14 +1393,30 @@ nsecs_t Camera3OutputStream::syncTimestampToDisplayLocked(nsecs_t t) {
    const VsyncEventData& vsyncEventData = parcelableVsyncEventData.vsync;
    nsecs_t currentTime = systemTime();

    // Reset capture to present time offset if more than 1 second
    // between frames.
    if (t - mLastCaptureTime > kSpacingResetIntervalNs) {
    // Reset capture to present time offset if:
    // - More than 1 second between frames.
    // - The frame duration deviates from multiples of vsync frame intervals.
    nsecs_t captureInterval = t - mLastCaptureTime;
    float captureToVsyncIntervalRatio = 1.0f * captureInterval / vsyncEventData.frameInterval;
    float ratioDeviation = std::fabs(
            captureToVsyncIntervalRatio - std::roundf(captureToVsyncIntervalRatio));
    if (captureInterval > kSpacingResetIntervalNs ||
            ratioDeviation >= kMaxIntervalRatioDeviation) {
        nsecs_t minPresentT = mLastPresentTime + vsyncEventData.frameInterval / 2;
        for (size_t i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
            if (vsyncEventData.frameTimelines[i].deadlineTimestamp >= currentTime) {
                mCaptureToPresentOffset =
                    vsyncEventData.frameTimelines[i].expectedPresentationTime - t;
                break;
            const auto& timeline = vsyncEventData.frameTimelines[i];
            if (timeline.deadlineTimestamp >= currentTime &&
                    timeline.expectedPresentationTime > minPresentT) {
                nsecs_t presentT = vsyncEventData.frameTimelines[i].expectedPresentationTime;
                mCaptureToPresentOffset = presentT - t;
                mLastCaptureTime = t;
                mLastPresentTime = presentT;

                // 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 presentT - vsyncEventData.frameInterval/3;
            }
        }
    }
+1 −0
Original line number Diff line number Diff line
@@ -423,6 +423,7 @@ class Camera3OutputStream :
    static constexpr size_t kDisplaySyncExtraBuffer = 2;
    static constexpr nsecs_t kSpacingResetIntervalNs = 1000000000LL; // 1 second
    static constexpr nsecs_t kTimelineThresholdNs = 1000000LL; // 1 millisecond
    static constexpr float kMaxIntervalRatioDeviation = 0.05f;
    nsecs_t syncTimestampToDisplayLocked(nsecs_t t);

    // Re-space frames by delaying queueBuffer so that frame delivery has