From 38ead8c1e9667afa981b7c5a43eb5646c04bf769 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Sun, 26 Apr 2026 13:22:52 -0300 Subject: [PATCH] fix(sync): pace webcam timestamps by frame duration --- Cargo.lock | 6 +++--- client/Cargo.toml | 2 +- client/src/input/camera.rs | 3 ++- client/src/input/camera/capture_pipeline.rs | 14 ++++++++++++-- client/src/input/camera/device_selection.rs | 3 ++- common/Cargo.toml | 2 +- server/Cargo.toml | 2 +- 7 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d4b999..36194ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1642,7 +1642,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "lesavka_client" -version = "0.14.2" +version = "0.14.3" dependencies = [ "anyhow", "async-stream", @@ -1676,7 +1676,7 @@ dependencies = [ [[package]] name = "lesavka_common" -version = "0.14.2" +version = "0.14.3" dependencies = [ "anyhow", "base64", @@ -1688,7 +1688,7 @@ dependencies = [ [[package]] name = "lesavka_server" -version = "0.14.2" +version = "0.14.3" dependencies = [ "anyhow", "base64", diff --git a/client/Cargo.toml b/client/Cargo.toml index 53f79cb..d179765 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -4,7 +4,7 @@ path = "src/main.rs" [package] name = "lesavka_client" -version = "0.14.2" +version = "0.14.3" edition = "2024" [dependencies] diff --git a/client/src/input/camera.rs b/client/src/input/camera.rs index 8c75911..657db91 100644 --- a/client/src/input/camera.rs +++ b/client/src/input/camera.rs @@ -50,7 +50,8 @@ pub struct CameraCapture { pipeline: gst::Pipeline, sink: gst_app::AppSink, preview_tap_running: Option>, - pts_rebaser: crate::live_capture_clock::SourcePtsRebaser, + pts_rebaser: crate::live_capture_clock::DurationPacedSourcePtsRebaser, + frame_duration_us: u64, } include!("camera/capture_pipeline.rs"); diff --git a/client/src/input/camera/capture_pipeline.rs b/client/src/input/camera/capture_pipeline.rs index 3185b73..d5ee5ba 100644 --- a/client/src/input/camera/capture_pipeline.rs +++ b/client/src/input/camera/capture_pipeline.rs @@ -227,7 +227,8 @@ impl CameraCapture { pipeline, sink, preview_tap_running, - pts_rebaser: crate::live_capture_clock::SourcePtsRebaser::default(), + pts_rebaser: crate::live_capture_clock::DurationPacedSourcePtsRebaser::default(), + frame_duration_us: (1_000_000u64 / u64::from(fps.max(1))).max(1), }) } @@ -236,7 +237,15 @@ impl CameraCapture { let buf = sample.buffer()?; let map = buf.map_readable().ok()?; let source_pts_us = buf.pts().map(|ts| ts.nseconds() / 1_000); - let timing = self.pts_rebaser.rebase_or_now(source_pts_us, 1); + let packet_duration_us = buf + .duration() + .map(|ts| (ts.nseconds() / 1_000).max(1)) + .unwrap_or(self.frame_duration_us); + let timing = self.pts_rebaser.rebase_with_packet_duration( + source_pts_us, + packet_duration_us, + crate::live_capture_clock::upstream_source_lag_cap(), + ); let pts = timing.packet_pts_us; static CAMERA_PACKET_COUNT: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0); @@ -278,6 +287,7 @@ fn log_camera_timing_sample( packet_pts_us = timing.packet_pts_us, pull_path_delay_us = timing.capture_now_us as i128 - timing.packet_pts_us as i128, used_source_pts = timing.used_source_pts, + lag_clamped = timing.lag_clamped, bytes, "📸 upstream webcam timing sample" ); diff --git a/client/src/input/camera/device_selection.rs b/client/src/input/camera/device_selection.rs index c407239..1c95c05 100644 --- a/client/src/input/camera/device_selection.rs +++ b/client/src/input/camera/device_selection.rs @@ -94,7 +94,8 @@ impl CameraCapture { pipeline, sink, preview_tap_running: None, - pts_rebaser: crate::live_capture_clock::SourcePtsRebaser::default(), + pts_rebaser: crate::live_capture_clock::DurationPacedSourcePtsRebaser::default(), + frame_duration_us: 1, } } diff --git a/common/Cargo.toml b/common/Cargo.toml index 2a2473e..5a8e6eb 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lesavka_common" -version = "0.14.2" +version = "0.14.3" edition = "2024" build = "build.rs" diff --git a/server/Cargo.toml b/server/Cargo.toml index c57ee84..5adff37 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -10,7 +10,7 @@ bench = false [package] name = "lesavka_server" -version = "0.14.2" +version = "0.14.3" edition = "2024" autobins = false