From da8c1f3df90a205f1006fa552c442d3a96d0e952 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 25 Jan 2024 22:03:26 -0700 Subject: [PATCH] Improve frame skipping --- src/main.rs | 4 +++- src/player.rs | 32 ++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index cbfc567..f6ee7c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -308,7 +308,9 @@ impl Application for App { log::warn!("skipping video frame {:?}", old_frame.0.pts()); } // Frame is ready to be shown - video_frame_opt = Some(video_frame) + video_frame_opt = Some(video_frame); + //TODO: allow skipping? + break; } else { // Put frame back and exit loop video_frames.push_front(video_frame); diff --git a/src/player.rs b/src/player.rs index c80ce82..11a055b 100644 --- a/src/player.rs +++ b/src/player.rs @@ -185,12 +185,18 @@ fn ffmpeg_thread>( .unwrap(); loop { - let (mut cpu_frame, mut sync_time_opt) = cpu_frame_rx.recv().unwrap(); - while let Ok((extra_frame, time_opt)) = cpu_frame_rx.try_recv() { - log::warn!("skipping cpu video frame at {:?}", cpu_frame.pts()); - cpu_frame = extra_frame; - sync_time_opt = time_opt; + let mut recv_opt: Option<(Video, Option)> = None; + while let Ok(recv) = cpu_frame_rx.try_recv() { + if let Some((old_frame, _)) = recv_opt { + //TODO: only skip if behind (frames come in weird timing from codecs) + log::warn!("skipping cpu video frame at {:?}", old_frame.pts()); + } + recv_opt = Some(recv); } + let (cpu_frame, sync_time_opt) = match recv_opt { + Some(some) => some, + None => cpu_frame_rx.recv().unwrap(), + }; let pts_opt = cpu_frame.pts(); // Start count after blocking recv @@ -238,12 +244,18 @@ fn ffmpeg_thread>( .name("video_map_gpu_cpu".to_string()) .spawn(move || { loop { - let (mut gpu_frame, mut sync_time_opt) = gpu_frame_rx.recv().unwrap(); - while let Ok((extra_frame, time_opt)) = gpu_frame_rx.try_recv() { - log::warn!("skipping gpu video frame at {:?}", gpu_frame.pts()); - gpu_frame = extra_frame; - sync_time_opt = time_opt; + let mut recv_opt: Option<(Video, Option)> = None; + while let Ok(recv) = gpu_frame_rx.try_recv() { + if let Some((old_frame, _)) = recv_opt { + //TODO: only skip if behind (frames come in weird timing from codecs) + log::warn!("skipping gpu video frame at {:?}", old_frame.pts()); + } + recv_opt = Some(recv); } + let (gpu_frame, sync_time_opt) = match recv_opt { + Some(some) => some, + None => gpu_frame_rx.recv().unwrap(), + }; let pts = gpu_frame.pts(); // Start timer after blocking recv