Loading media/libstagefright/timedtext/TextDescriptions.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -466,6 +466,10 @@ status_t TextDescriptions::extract3GPPGlobalDescriptions( if (subChunkType == FOURCC('f', 't', 'a', 'b')) { if(subChunkSize < 8) { return OK; } tmpData += 8; size_t subChunkRemaining = subChunkSize - 8; Loading services/camera/libcameraservice/device3/Camera3OutputStream.cpp +39 −11 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 #include <algorithm> #include <ctime> #include <fstream> Loading Loading @@ -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; } } } Loading @@ -1415,16 +1432,27 @@ nsecs_t Camera3OutputStream::syncTimestampToDisplayLocked(nsecs_t t) { int minVsyncs = (mMinExpectedDuration - vsyncEventData.frameInterval / 2) / vsyncEventData.frameInterval; if (minVsyncs < 0) minVsyncs = 0; nsecs_t minInterval = minVsyncs * vsyncEventData.frameInterval + kTimelineThresholdNs; // Find best timestamp in the vsync timeline: nsecs_t minInterval = minVsyncs * vsyncEventData.frameInterval; // Find best timestamp in the vsync timelines: // - Only use at most 3 timelines to avoid long latency // - closest to the ideal present time, // - deadline timestamp is greater than the current time, and // - the candidate present time is at least minInterval in the future // compared to last present time. for (const auto& vsyncTime : vsyncEventData.frameTimelines) { int maxTimelines = std::min(kMaxTimelines, (int)VsyncEventData::kFrameTimelinesLength); float biasForShortDelay = 1.0f; for (int i = 0; i < maxTimelines; i ++) { const auto& vsyncTime = vsyncEventData.frameTimelines[i]; if (minVsyncs > 0) { // Bias towards using smaller timeline index: // i = 0: bias = 1 // i = maxTimelines-1: bias = -1 biasForShortDelay = 1.0 - 2.0 * i / (maxTimelines - 1); } if (std::abs(vsyncTime.expectedPresentationTime - idealPresentT) < minDiff && vsyncTime.deadlineTimestamp >= currentTime && vsyncTime.expectedPresentationTime > mLastPresentTime + minInterval) { vsyncTime.expectedPresentationTime > mLastPresentTime + minInterval + biasForShortDelay * kTimelineThresholdNs) { expectedPresentT = vsyncTime.expectedPresentationTime; minDiff = std::abs(vsyncTime.expectedPresentationTime - idealPresentT); } Loading services/camera/libcameraservice/device3/Camera3OutputStream.h +3 −1 Original line number Diff line number Diff line Loading @@ -421,8 +421,10 @@ class Camera3OutputStream : nsecs_t mLastPresentTime = 0; nsecs_t mCaptureToPresentOffset = 0; static constexpr size_t kDisplaySyncExtraBuffer = 2; static constexpr nsecs_t kSpacingResetIntervalNs = 1000000000LL; // 1 second static constexpr nsecs_t kSpacingResetIntervalNs = 50000000LL; // 50 millisecond static constexpr nsecs_t kTimelineThresholdNs = 1000000LL; // 1 millisecond static constexpr float kMaxIntervalRatioDeviation = 0.05f; static constexpr int kMaxTimelines = 3; nsecs_t syncTimestampToDisplayLocked(nsecs_t t); // Re-space frames by delaying queueBuffer so that frame delivery has Loading Loading
media/libstagefright/timedtext/TextDescriptions.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -466,6 +466,10 @@ status_t TextDescriptions::extract3GPPGlobalDescriptions( if (subChunkType == FOURCC('f', 't', 'a', 'b')) { if(subChunkSize < 8) { return OK; } tmpData += 8; size_t subChunkRemaining = subChunkSize - 8; Loading
services/camera/libcameraservice/device3/Camera3OutputStream.cpp +39 −11 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 #include <algorithm> #include <ctime> #include <fstream> Loading Loading @@ -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; } } } Loading @@ -1415,16 +1432,27 @@ nsecs_t Camera3OutputStream::syncTimestampToDisplayLocked(nsecs_t t) { int minVsyncs = (mMinExpectedDuration - vsyncEventData.frameInterval / 2) / vsyncEventData.frameInterval; if (minVsyncs < 0) minVsyncs = 0; nsecs_t minInterval = minVsyncs * vsyncEventData.frameInterval + kTimelineThresholdNs; // Find best timestamp in the vsync timeline: nsecs_t minInterval = minVsyncs * vsyncEventData.frameInterval; // Find best timestamp in the vsync timelines: // - Only use at most 3 timelines to avoid long latency // - closest to the ideal present time, // - deadline timestamp is greater than the current time, and // - the candidate present time is at least minInterval in the future // compared to last present time. for (const auto& vsyncTime : vsyncEventData.frameTimelines) { int maxTimelines = std::min(kMaxTimelines, (int)VsyncEventData::kFrameTimelinesLength); float biasForShortDelay = 1.0f; for (int i = 0; i < maxTimelines; i ++) { const auto& vsyncTime = vsyncEventData.frameTimelines[i]; if (minVsyncs > 0) { // Bias towards using smaller timeline index: // i = 0: bias = 1 // i = maxTimelines-1: bias = -1 biasForShortDelay = 1.0 - 2.0 * i / (maxTimelines - 1); } if (std::abs(vsyncTime.expectedPresentationTime - idealPresentT) < minDiff && vsyncTime.deadlineTimestamp >= currentTime && vsyncTime.expectedPresentationTime > mLastPresentTime + minInterval) { vsyncTime.expectedPresentationTime > mLastPresentTime + minInterval + biasForShortDelay * kTimelineThresholdNs) { expectedPresentT = vsyncTime.expectedPresentationTime; minDiff = std::abs(vsyncTime.expectedPresentationTime - idealPresentT); } Loading
services/camera/libcameraservice/device3/Camera3OutputStream.h +3 −1 Original line number Diff line number Diff line Loading @@ -421,8 +421,10 @@ class Camera3OutputStream : nsecs_t mLastPresentTime = 0; nsecs_t mCaptureToPresentOffset = 0; static constexpr size_t kDisplaySyncExtraBuffer = 2; static constexpr nsecs_t kSpacingResetIntervalNs = 1000000000LL; // 1 second static constexpr nsecs_t kSpacingResetIntervalNs = 50000000LL; // 50 millisecond static constexpr nsecs_t kTimelineThresholdNs = 1000000LL; // 1 millisecond static constexpr float kMaxIntervalRatioDeviation = 0.05f; static constexpr int kMaxTimelines = 3; nsecs_t syncTimestampToDisplayLocked(nsecs_t t); // Re-space frames by delaying queueBuffer so that frame delivery has Loading