fix(sync): pace webcam timestamps by frame duration
This commit is contained in:
parent
71b44521ef
commit
38ead8c1e9
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1642,7 +1642,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.14.2"
|
version = "0.14.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-stream",
|
"async-stream",
|
||||||
@ -1676,7 +1676,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.14.2"
|
version = "0.14.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
@ -1688,7 +1688,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.14.2"
|
version = "0.14.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
|||||||
@ -4,7 +4,7 @@ path = "src/main.rs"
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.14.2"
|
version = "0.14.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -50,7 +50,8 @@ pub struct CameraCapture {
|
|||||||
pipeline: gst::Pipeline,
|
pipeline: gst::Pipeline,
|
||||||
sink: gst_app::AppSink,
|
sink: gst_app::AppSink,
|
||||||
preview_tap_running: Option<Arc<AtomicBool>>,
|
preview_tap_running: Option<Arc<AtomicBool>>,
|
||||||
pts_rebaser: crate::live_capture_clock::SourcePtsRebaser,
|
pts_rebaser: crate::live_capture_clock::DurationPacedSourcePtsRebaser,
|
||||||
|
frame_duration_us: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
include!("camera/capture_pipeline.rs");
|
include!("camera/capture_pipeline.rs");
|
||||||
|
|||||||
@ -227,7 +227,8 @@ impl CameraCapture {
|
|||||||
pipeline,
|
pipeline,
|
||||||
sink,
|
sink,
|
||||||
preview_tap_running,
|
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 buf = sample.buffer()?;
|
||||||
let map = buf.map_readable().ok()?;
|
let map = buf.map_readable().ok()?;
|
||||||
let source_pts_us = buf.pts().map(|ts| ts.nseconds() / 1_000);
|
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;
|
let pts = timing.packet_pts_us;
|
||||||
static CAMERA_PACKET_COUNT: std::sync::atomic::AtomicU64 =
|
static CAMERA_PACKET_COUNT: std::sync::atomic::AtomicU64 =
|
||||||
std::sync::atomic::AtomicU64::new(0);
|
std::sync::atomic::AtomicU64::new(0);
|
||||||
@ -278,6 +287,7 @@ fn log_camera_timing_sample(
|
|||||||
packet_pts_us = timing.packet_pts_us,
|
packet_pts_us = timing.packet_pts_us,
|
||||||
pull_path_delay_us = timing.capture_now_us as i128 - timing.packet_pts_us as i128,
|
pull_path_delay_us = timing.capture_now_us as i128 - timing.packet_pts_us as i128,
|
||||||
used_source_pts = timing.used_source_pts,
|
used_source_pts = timing.used_source_pts,
|
||||||
|
lag_clamped = timing.lag_clamped,
|
||||||
bytes,
|
bytes,
|
||||||
"📸 upstream webcam timing sample"
|
"📸 upstream webcam timing sample"
|
||||||
);
|
);
|
||||||
|
|||||||
@ -94,7 +94,8 @@ impl CameraCapture {
|
|||||||
pipeline,
|
pipeline,
|
||||||
sink,
|
sink,
|
||||||
preview_tap_running: None,
|
preview_tap_running: None,
|
||||||
pts_rebaser: crate::live_capture_clock::SourcePtsRebaser::default(),
|
pts_rebaser: crate::live_capture_clock::DurationPacedSourcePtsRebaser::default(),
|
||||||
|
frame_duration_us: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.14.2"
|
version = "0.14.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ bench = false
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.14.2"
|
version = "0.14.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
autobins = false
|
autobins = false
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user