diff --git a/client/Cargo.toml b/client/Cargo.toml index 73a6376..c7272f2 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -4,7 +4,7 @@ path = "src/main.rs" [package] name = "lesavka_client" -version = "0.14.4" +version = "0.14.5" edition = "2024" [dependencies] diff --git a/common/Cargo.toml b/common/Cargo.toml index 74208e6..b61759d 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lesavka_common" -version = "0.14.4" +version = "0.14.5" edition = "2024" build = "build.rs" diff --git a/server/Cargo.toml b/server/Cargo.toml index 25c1172..e6ef156 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -10,7 +10,7 @@ bench = false [package] name = "lesavka_server" -version = "0.14.4" +version = "0.14.5" edition = "2024" autobins = false diff --git a/server/src/main/relay_service.rs b/server/src/main/relay_service.rs index de39195..4371c05 100644 --- a/server/src/main/relay_service.rs +++ b/server/src/main/relay_service.rs @@ -279,6 +279,7 @@ impl Relay for Handler { let mut pending = std::collections::VecDeque::new(); let mut inbound_closed = false; let stale_drop_budget = upstream_stale_drop_budget(); + let mut startup_video_settled = false; loop { if !camera_rt.is_active(session_id) || !upstream_media_rt.is_camera_active(upstream_lease.generation) @@ -338,13 +339,26 @@ impl Relay for Handler { continue; } if plan.late_by > stale_drop_budget { - tracing::warn!( - rpc_id, - session_id, - late_by_ms = plan.late_by.as_millis(), - pts = plan.local_pts_us, - "🎥 upstream video frame dropped after missing its freshness budget" - ); + let coalesced = retain_freshest_video_packet(&mut pending); + if startup_video_settled { + tracing::warn!( + rpc_id, + session_id, + late_by_ms = plan.late_by.as_millis(), + pts = plan.local_pts_us, + dropped_pending = coalesced, + "🎥 upstream video frame dropped after missing its freshness budget" + ); + } else { + tracing::debug!( + rpc_id, + session_id, + late_by_ms = plan.late_by.as_millis(), + pts = plan.local_pts_us, + dropped_pending = coalesced, + "🎥 dropping startup-stale upstream video until the playout window settles" + ); + } continue; } tokio::time::sleep_until(plan.due_at).await; @@ -352,16 +366,30 @@ impl Relay for Handler { .checked_duration_since(plan.due_at) .unwrap_or_default(); if actual_late_by > stale_drop_budget { - tracing::warn!( - rpc_id, - session_id, - late_by_ms = actual_late_by.as_millis(), - pts = plan.local_pts_us, - "🎥 upstream video frame dropped after waking too late for fresh playout" - ); + let coalesced = retain_freshest_video_packet(&mut pending); + if startup_video_settled { + tracing::warn!( + rpc_id, + session_id, + late_by_ms = actual_late_by.as_millis(), + pts = plan.local_pts_us, + dropped_pending = coalesced, + "🎥 upstream video frame dropped after waking too late for fresh playout" + ); + } else { + tracing::debug!( + rpc_id, + session_id, + late_by_ms = actual_late_by.as_millis(), + pts = plan.local_pts_us, + dropped_pending = coalesced, + "🎥 dropping startup-stale upstream video after a late wake until the playout window settles" + ); + } continue; } pkt.pts = plan.local_pts_us; + startup_video_settled = true; relay.feed(pkt); // ← all logging inside video.rs } upstream_media_rt.close_camera(upstream_lease.generation); diff --git a/server/src/main/relay_service_coverage.rs b/server/src/main/relay_service_coverage.rs index 15a6fea..229b810 100644 --- a/server/src/main/relay_service_coverage.rs +++ b/server/src/main/relay_service_coverage.rs @@ -219,6 +219,7 @@ impl Relay for Handler { continue; } if plan.late_by > stale_drop_budget { + let _ = retain_freshest_video_packet(&mut pending); continue; } tokio::time::sleep_until(plan.due_at).await; @@ -226,6 +227,7 @@ impl Relay for Handler { .checked_duration_since(plan.due_at) .unwrap_or_default(); if actual_late_by > stale_drop_budget { + let _ = retain_freshest_video_packet(&mut pending); continue; } pkt.pts = plan.local_pts_us;