From 9d5451f58811e476509db8dae37a237a649d6fd5 Mon Sep 17 00:00:00 2001 From: mofeng Date: Tue, 27 Jan 2026 17:32:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=20rustdsk=20=E4=B8=A2?= =?UTF-8?q?=E5=B8=A7=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/rustdesk/connection.rs | 36 ++++++++++++++++++++++++++---- src/video/shared_video_pipeline.rs | 1 + 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/rustdesk/connection.rs b/src/rustdesk/connection.rs index 7c3b3fbf..39a90a67 100644 --- a/src/rustdesk/connection.rs +++ b/src/rustdesk/connection.rs @@ -1557,6 +1557,9 @@ async fn run_video_streaming( let mut shutdown_rx = shutdown_tx.subscribe(); let mut encoded_count: u64 = 0; let mut last_log_time = Instant::now(); + let mut waiting_for_keyframe = true; + let mut last_sequence: Option = None; + let mut last_keyframe_request = Instant::now() - Duration::from_secs(1); info!( "Started shared video streaming for connection {} (codec: {:?})", @@ -1626,6 +1629,30 @@ async fn run_video_streaming( } }; + let gap_detected = if let Some(prev) = last_sequence { + frame.sequence > prev.saturating_add(1) + } else { + false + }; + + if waiting_for_keyframe || gap_detected { + if frame.is_keyframe { + waiting_for_keyframe = false; + } else { + if gap_detected { + waiting_for_keyframe = true; + } + let now = Instant::now(); + if now.duration_since(last_keyframe_request) >= Duration::from_millis(200) { + if let Err(e) = video_manager.request_keyframe().await { + debug!("Failed to request keyframe for connection {}: {}", conn_id, e); + } + last_keyframe_request = now; + } + continue; + } + } + // Convert EncodedVideoFrame to RustDesk VideoFrame message // Use zero-copy version: Bytes.clone() only increments refcount let msg_bytes = video_adapter.encode_frame_bytes_zero_copy( @@ -1634,12 +1661,13 @@ async fn run_video_streaming( frame.pts_ms as u64, ); - // Send to connection (blocks if channel is full, providing backpressure) - if video_tx.try_send(msg_bytes).is_err() { - // Drop when channel is full to avoid backpressure - continue; + // Send to connection (backpressure instead of dropping) + if video_tx.send(msg_bytes).await.is_err() { + debug!("Video channel closed for connection {}", conn_id); + break 'subscribe_loop; } + last_sequence = Some(frame.sequence); encoded_count += 1; // Log stats periodically diff --git a/src/video/shared_video_pipeline.rs b/src/video/shared_video_pipeline.rs index eb6c8be3..6ab721ff 100644 --- a/src/video/shared_video_pipeline.rs +++ b/src/video/shared_video_pipeline.rs @@ -506,6 +506,7 @@ impl SharedVideoPipeline { } }; + #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] let is_rkmpp_encoder = selected_codec_name.contains("rkmpp"); #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] if needs_mjpeg_decode