diff --git a/src/capture.rs b/src/capture.rs index 62d7b0a..8e19c63 100644 --- a/src/capture.rs +++ b/src/capture.rs @@ -54,6 +54,8 @@ impl Capture return Err (Error::OutputBufferTooSmall); } + // std::thread::sleep (std::time::Duration::from_millis (500)); + Ok (self.stream.dequeue (|view| { let bytesused = usize::try_from (view.bytesused ()).unwrap (); diff --git a/src/main.rs b/src/main.rs index 6369296..e8ed03c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,4 @@ use std::{ - fmt, - marker::Send, sync::mpsc, thread, time::{ @@ -12,7 +10,6 @@ use std::{ use eframe::egui; mod capture; -mod task; fn main() -> Result <(), Error> { @@ -124,11 +121,11 @@ impl eframe::App for App { { match msg { - MsgToGui::NewRgbaFrame ((data, gen)) => + MsgToGui::NewRgbaFrame (frame) => { - self.latency = Instant::now () - gen; + texture.set (egui::ColorImage::from_rgba_premultiplied([1280,720], &frame.data), Default::default ()); + self.latency = Instant::now () - frame.capture_time; self.camera_frames += 1; - texture.set (egui::ColorImage::from_rgba_premultiplied([1280,720], &data), Default::default ()); }, } } @@ -172,17 +169,17 @@ enum MsgToController { GuiNeedsRgbaFrame, GotCapture ((capture::Capture, JpegFrame)), - DecodedJpegToRgba ((Vec , Instant)), + DecodedJpegToRgba (RgbaFrame), } enum MsgToGui { - NewRgbaFrame ((Vec , Instant)), + NewRgbaFrame (RgbaFrame), } enum MsgFromController { - RepaintGui ((Vec , Instant)), + RepaintGui (RgbaFrame), StartCapture, StartJpegDecoder (JpegFrame), } @@ -191,20 +188,28 @@ enum MsgFromController struct JpegFrame { data: Vec , - time: Instant, + capture_time: Instant, +} + +#[derive (Clone)] +struct RgbaFrame +{ + data: Vec , + capture_time: Instant, } struct Controller { - gui_rgba_gen: Instant, + gui_has_new_frame: bool, gui_needs_frame: bool, capture_is_running: bool, jpeg_decoder_is_running: bool, - jpeg_needs_frame: bool, + jpeg_decoder_has_new_frame: bool, + jpeg_decoder_needs_frame: bool, - rgba_frame: (Vec , Instant), + rgba_frame: RgbaFrame, jpeg_frame: JpegFrame, } @@ -214,62 +219,75 @@ impl Controller { Self { + gui_has_new_frame: false, gui_needs_frame: false, - gui_rgba_gen: now, capture_is_running: false, + jpeg_decoder_has_new_frame: false, jpeg_decoder_is_running: false, - jpeg_needs_frame: false, + jpeg_decoder_needs_frame: false, - rgba_frame: (Default::default (), now), + rgba_frame: RgbaFrame + { + data: Default::default (), + capture_time: now, + }, jpeg_frame: JpegFrame { data: Default::default (), - time: now, + capture_time: now, }, } } - fn handle_rgba_frame (&mut self, data: Vec , gen: Instant) + fn handle_rgba_frame (&mut self, frame: RgbaFrame) { + // println! ("handle_rgba_frame"); + self.gui_has_new_frame = true; self.jpeg_decoder_is_running = false; - self.rgba_frame = (data, gen); + self.jpeg_decoder_has_new_frame = false; + self.rgba_frame = frame; } fn handle_capture (&mut self, jpeg: JpegFrame) { + // println! ("handle_capture"); self.capture_is_running = false; self.jpeg_frame = jpeg; + self.jpeg_decoder_has_new_frame = true; } fn handle_gui_needs_frame (&mut self) { + // println! ("handle_gui_needs_frame"); self.gui_needs_frame = true; } fn poll (&mut self) -> Option { - if self.gui_needs_frame && self.rgba_frame.1 > self.gui_rgba_gen + if self.gui_needs_frame && self.gui_has_new_frame { + self.gui_has_new_frame = false; self.gui_needs_frame = false; - self.gui_rgba_gen = self.rgba_frame.1; - + println! ("RepaintGui"); Some (MsgFromController::RepaintGui (self.rgba_frame.clone ())) } - else if self.gui_needs_frame && ! self.jpeg_decoder_is_running && self.jpeg_frame.time > self.rgba_frame.1 + else if self.jpeg_decoder_has_new_frame && ! self.jpeg_decoder_is_running && self.jpeg_decoder_needs_frame { self.jpeg_decoder_is_running = true; - self.jpeg_needs_frame = false; + self.jpeg_decoder_needs_frame = false; + println! ("StartJpegDecoder"); Some (MsgFromController::StartJpegDecoder (self.jpeg_frame.clone ())) } - else if self.jpeg_needs_frame && ! self.capture_is_running + else if self.jpeg_decoder_needs_frame && ! self.jpeg_decoder_has_new_frame && ! self.capture_is_running { self.capture_is_running = true; + println! ("StartCapture"); Some (MsgFromController::StartCapture) } - else if self.gui_needs_frame && self.jpeg_frame.time == self.rgba_frame.1 + else if self.gui_needs_frame && ! self.gui_has_new_frame { - self.jpeg_needs_frame = true; + self.jpeg_decoder_needs_frame = true; None } else @@ -319,9 +337,9 @@ impl Driver { match self.recv.recv().unwrap () { - MsgToController::DecodedJpegToRgba ((data, gen)) => + MsgToController::DecodedJpegToRgba (frame) => { - self.ctl.handle_rgba_frame (data, gen); + self.ctl.handle_rgba_frame (frame); }, MsgToController::GotCapture ((capture, jpeg)) => { @@ -348,13 +366,20 @@ impl Driver let send = self.send.clone (); pool.spawn (move || { + // std::thread::sleep (std::time::Duration::from_millis (500)); let mut decoder = zune_jpeg::JpegDecoder::new_with_options (&jpeg_frame.data, zune_core::options::DecoderOptions::new_fast().jpeg_set_out_colorspace(zune_core::colorspace::ColorSpace::RGBA)); decoder.decode_headers().unwrap (); let mut rgba = vec![0u8;decoder.output_buffer_size().unwrap ()]; decoder.decode_into(&mut rgba).unwrap (); - send.send (MsgToController::DecodedJpegToRgba ((rgba, jpeg_frame.time))).unwrap (); + let rgba = RgbaFrame + { + data: rgba, + capture_time: jpeg_frame.capture_time, + }; + + send.send (MsgToController::DecodedJpegToRgba (rgba)).unwrap (); }); }, MsgFromController::StartCapture => @@ -370,7 +395,7 @@ impl Driver let frame = JpegFrame { data, - time: Instant::now (), + capture_time: Instant::now (), }; send.send (MsgToController::GotCapture ((capture, frame))).unwrap (); @@ -394,6 +419,4 @@ enum Error { #[error ("capture")] Capture (#[from] capture::Error), - #[error ("task")] - Task (#[from] task::Error), } diff --git a/src/task.rs b/src/task.rs deleted file mode 100644 index dffde0a..0000000 --- a/src/task.rs +++ /dev/null @@ -1,74 +0,0 @@ -/// This is probably just a fancy Cell or something. - -pub enum Task -{ - Stopped (S), - Running (R), -} - -#[derive (Debug, thiserror::Error)] -pub enum Error -{ - #[error ("tried to start already-running task")] - AlreadyRunning, - #[error ("tried to stop already-stopped task")] - AlreadyStopped, - #[error ("cannot access a task's inner object while it's running")] - CantAccessWhileRunning, -} - -impl From for Task -{ - fn from (x: S) -> Self - { - Self::Stopped (x) - } -} - -impl Task -{ - pub fn is_running (&self) -> bool - { - match self - { - Self::Running (_) => true, - Self::Stopped (_) => false, - } - } - - pub fn try_inner (&self) -> Result <&S, Error> - { - match self - { - Self::Running (_) => Err (Error::CantAccessWhileRunning), - Self::Stopped (x) => Ok (x), - } - } - - pub fn try_inner_mut (&mut self) -> Result <&mut S, Error> - { - match self - { - Self::Running (_) => Err (Error::CantAccessWhileRunning), - Self::Stopped (x) => Ok (x), - } - } - - pub fn start (&mut self, x: R) -> Result - { - match std::mem::replace (self, Self::Running (x)) - { - Self::Running (_) => Err (Error::AlreadyRunning), - Self::Stopped (x) => Ok (x), - } - } - - pub fn stop (&mut self, x: S) -> Result - { - match std::mem::replace (self, Self::Stopped (x)) - { - Self::Stopped (_) => Err (Error::AlreadyStopped), - Self::Running (x) => Ok (x), - } - } -}