diff --git a/src/client.rs b/src/client.rs index 39703e55a..2f745b70c 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1661,8 +1661,9 @@ impl LoginConfigHandler { /// Media data. pub enum MediaData { - VideoFrame, - AudioFrame(AudioFrame), + VideoQueue, + VideoFrame(Box), + AudioFrame(Box), AudioFormat(AudioFormat), Reset, RecordScreen(bool, i32, i32, String), @@ -1692,7 +1693,12 @@ where loop { if let Ok(data) = video_receiver.recv() { match data { - MediaData::VideoFrame => { + MediaData::VideoFrame(vf) => { + if let Ok(true) = video_handler.handle_frame(*vf) { + video_callback(&mut video_handler.rgb); + } + } + MediaData::VideoQueue => { if let Some(vf) = video_queue.pop() { if let Ok(true) = video_handler.handle_frame(vf) { video_callback(&mut video_handler.rgb); @@ -1727,7 +1733,7 @@ pub fn start_audio_thread() -> MediaSender { if let Ok(data) = audio_receiver.recv() { match data { MediaData::AudioFrame(af) => { - audio_handler.handle_frame(af); + audio_handler.handle_frame(*af); } MediaData::AudioFormat(f) => { log::debug!("recved audio format, sample rate={}", f.sample_rate); diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index 6b0e139e2..b0bddc82e 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -816,6 +816,18 @@ impl Remote { } } + fn contains_key_frame(vf: &VideoFrame) -> bool { + match &vf.union { + Some(vf) => match vf { + video_frame::Union::Vp9s(f) => f.frames.iter().any(|e| e.key), + video_frame::Union::H264s(f) => f.frames.iter().any(|e| e.key), + video_frame::Union::H265s(f) => f.frames.iter().any(|e| e.key), + _ => false, + }, + None => false, + } + } + async fn handle_msg_from_peer(&mut self, data: &[u8], peer: &mut Stream) -> bool { if let Ok(msg_in) = Message::parse_from_bytes(&data) { match msg_in.union { @@ -834,8 +846,15 @@ impl Remote { ..Default::default() }) }; - self.video_queue.force_push(vf); - self.video_sender.send(MediaData::VideoFrame).ok(); + if Self::contains_key_frame(&vf) { + while let Some(_) = self.video_queue.pop() {} + self.video_sender + .send(MediaData::VideoFrame(Box::new(vf))) + .ok(); + } else { + self.video_queue.force_push(vf); + self.video_sender.send(MediaData::VideoQueue).ok(); + } } Some(message::Union::Hash(hash)) => { self.handler @@ -1222,7 +1241,9 @@ impl Remote { } Some(message::Union::AudioFrame(frame)) => { if !self.handler.lc.read().unwrap().disable_audio.v { - self.audio_sender.send(MediaData::AudioFrame(frame)).ok(); + self.audio_sender + .send(MediaData::AudioFrame(Box::new(frame))) + .ok(); } } Some(message::Union::FileAction(action)) => match action.union { diff --git a/src/server/connection.rs b/src/server/connection.rs index 6b0cbefc3..0c17fd176 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1669,7 +1669,7 @@ impl Connection { Some(message::Union::AudioFrame(frame)) => { if !self.disable_audio { if let Some(sender) = &self.audio_sender { - allow_err!(sender.send(MediaData::AudioFrame(frame))); + allow_err!(sender.send(MediaData::AudioFrame(Box::new(frame)))); } else { log::warn!( "Processing audio frame without the voice call audio sender."