#[cfg(not(coverage))] fn upstream_stale_drop_budget() -> Duration { let drop_ms = std::env::var("LESAVKA_UPSTREAM_STALE_DROP_MS") .ok() .and_then(|value| value.trim().parse::().ok()) .unwrap_or(80); Duration::from_millis(drop_ms) } #[cfg(not(coverage))] /// Keeps only the newest webcam packet when the host path is already behind. fn retain_freshest_video_packet( pending: &mut std::collections::VecDeque, ) -> usize { if pending.len() <= 1 { return 0; } let newest = pending.pop_back().expect("non-empty pending video queue"); let dropped = pending.len(); pending.clear(); pending.push_back(newest); dropped } #[cfg(not(coverage))] const AUDIO_PENDING_LIVE_WINDOW_PACKETS: usize = 8; #[cfg(not(coverage))] /// Keeps a tiny newest microphone window so playout can stay smooth without /// draining old audio. fn retain_freshest_audio_packet( pending: &mut std::collections::VecDeque, ) -> usize { if pending.len() <= AUDIO_PENDING_LIVE_WINDOW_PACKETS { return 0; } let dropped = pending.len() - AUDIO_PENDING_LIVE_WINDOW_PACKETS; pending.drain(..dropped); dropped } #[cfg(not(coverage))] /// Extract client-side timing facts from an upstream microphone packet. fn audio_client_timing(pkt: &AudioPacket) -> UpstreamClientTiming { let capture_pts_us = if pkt.client_capture_pts_us == 0 { pkt.pts } else { pkt.client_capture_pts_us }; let send_pts_us = if pkt.client_send_pts_us == 0 { capture_pts_us } else { pkt.client_send_pts_us }; UpstreamClientTiming { capture_pts_us, send_pts_us, queue_depth: pkt.client_queue_depth, queue_age_ms: pkt.client_queue_age_ms, } } #[cfg(not(coverage))] /// Extract client-side timing facts from an upstream camera packet. fn video_client_timing(pkt: &VideoPacket) -> UpstreamClientTiming { let capture_pts_us = if pkt.client_capture_pts_us == 0 { pkt.pts } else { pkt.client_capture_pts_us }; let send_pts_us = if pkt.client_send_pts_us == 0 { capture_pts_us } else { pkt.client_send_pts_us }; UpstreamClientTiming { capture_pts_us, send_pts_us, queue_depth: pkt.client_queue_depth, queue_age_ms: pkt.client_queue_age_ms, } } #[cfg(not(coverage))] #[derive(Clone, Copy, Debug)] enum UpstreamStreamCleanupKind { Microphone, Camera, } #[cfg(not(coverage))] struct UpstreamStreamCleanup { runtime: Arc, kind: UpstreamStreamCleanupKind, generation: u64, rpc_id: u64, session_id: u64, camera_session_id: Option, outcome: &'static str, } #[cfg(not(coverage))] impl UpstreamStreamCleanup { fn microphone( runtime: Arc, generation: u64, rpc_id: u64, session_id: u64, ) -> Self { Self { runtime, kind: UpstreamStreamCleanupKind::Microphone, generation, rpc_id, session_id, camera_session_id: None, outcome: "aborted", } } fn camera( runtime: Arc, generation: u64, rpc_id: u64, session_id: u64, camera_session_id: u64, ) -> Self { Self { runtime, kind: UpstreamStreamCleanupKind::Camera, generation, rpc_id, session_id, camera_session_id: Some(camera_session_id), outcome: "aborted", } } fn mark_closed(&mut self) { self.outcome = "closed"; } fn mark_superseded(&mut self) { self.outcome = "superseded"; } fn mark_aborted(&mut self) { self.outcome = "aborted"; } } #[cfg(not(coverage))] impl Drop for UpstreamStreamCleanup { /// Closes only the stream generation owned by this RPC lifecycle guard. fn drop(&mut self) { match self.kind { UpstreamStreamCleanupKind::Microphone => { self.runtime.close_microphone(self.generation); info!( rpc_id = self.rpc_id, session_id = self.session_id, generation = self.generation, outcome = self.outcome, "🎤 stream_microphone lifecycle ended" ); } UpstreamStreamCleanupKind::Camera => { self.runtime.close_camera(self.generation); info!( rpc_id = self.rpc_id, session_id = self.session_id, camera_session_id = self.camera_session_id.unwrap_or_default(), generation = self.generation, outcome = self.outcome, "🎥 stream_camera lifecycle ended" ); } } } } /// Maps expected remote-audio availability failures onto retryable gRPC status codes. fn remote_audio_status(message: String) -> Status { if message.contains("remote USB gadget is not attached") { Status::unavailable(message) } else { Status::internal(message) } }