👕 refactor
							parent
							
								
									99bb54b26e
								
							
						
					
					
						commit
						b90c934242
					
				|  | @ -54,8 +54,6 @@ 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 (); | ||||
|  |  | |||
|  | @ -0,0 +1,124 @@ | |||
| use std:: | ||||
| { | ||||
|     time::Instant, | ||||
| }; | ||||
| 
 | ||||
| pub enum MsgFromController | ||||
| { | ||||
| 	RepaintGui (RgbaFrame), | ||||
| 	StartCapture, | ||||
| 	StartJpegDecoder (JpegFrame), | ||||
| } | ||||
| 
 | ||||
| #[derive (Clone)] | ||||
| pub struct JpegFrame | ||||
| { | ||||
|     pub data: Vec <u8>, | ||||
|     pub capture_time: Instant, | ||||
| } | ||||
| 
 | ||||
| #[derive (Clone)] | ||||
| pub struct RgbaFrame | ||||
| { | ||||
|     pub data: Vec <u8>, | ||||
|     pub capture_time: Instant, | ||||
| } | ||||
| 
 | ||||
| pub struct Controller | ||||
| { | ||||
|     gui_has_new_frame: bool, | ||||
|     gui_needs_frame: bool, | ||||
|     
 | ||||
|     capture_is_running: bool, | ||||
|     
 | ||||
|     jpeg_decoder_is_running: bool, | ||||
|     jpeg_decoder_has_new_frame: bool, | ||||
|     jpeg_decoder_needs_frame: bool, | ||||
|     
 | ||||
|     rgba_frame: RgbaFrame, | ||||
|     jpeg_frame: JpegFrame, | ||||
| } | ||||
| 
 | ||||
| impl Controller | ||||
| { | ||||
|     pub fn new (now: Instant) -> Self | ||||
|     { | ||||
|         Self | ||||
|         { | ||||
|             gui_has_new_frame: false, | ||||
|             gui_needs_frame: false, | ||||
|             
 | ||||
|             capture_is_running: false, | ||||
|             jpeg_decoder_has_new_frame: false, | ||||
|             jpeg_decoder_is_running: false, | ||||
|             jpeg_decoder_needs_frame: false, | ||||
|             
 | ||||
|             rgba_frame: RgbaFrame | ||||
|             { | ||||
|                 data: Default::default (), 
 | ||||
|                 capture_time: now, | ||||
|             }, | ||||
|             jpeg_frame: JpegFrame | ||||
|             { | ||||
|                 data: Default::default (), | ||||
|                 capture_time: now, | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
| 	pub 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.jpeg_decoder_has_new_frame = false; | ||||
| 		self.rgba_frame = frame; | ||||
| 	} | ||||
| 	
 | ||||
| 	pub 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; | ||||
| 	} | ||||
| 	
 | ||||
| 	pub fn handle_gui_needs_frame (&mut self) | ||||
| 	{ | ||||
|         // println! ("handle_gui_needs_frame");
 | ||||
| 		self.gui_needs_frame = true; | ||||
| 	} | ||||
| 	
 | ||||
| 	pub fn poll (&mut self) -> Option <MsgFromController> | ||||
| 	{ | ||||
| 		if self.gui_needs_frame && self.gui_has_new_frame | ||||
| 		{ | ||||
|             self.gui_has_new_frame = false; | ||||
|             self.gui_needs_frame = false; | ||||
|             // println! ("RepaintGui");
 | ||||
| 			Some (MsgFromController::RepaintGui (self.rgba_frame.clone ())) | ||||
| 		} | ||||
| 		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_decoder_needs_frame = false; | ||||
| 			// println! ("StartJpegDecoder");
 | ||||
| 			Some (MsgFromController::StartJpegDecoder (self.jpeg_frame.clone ())) | ||||
| 		} | ||||
| 		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.gui_has_new_frame | ||||
| 		{ | ||||
| 			self.jpeg_decoder_needs_frame = true; | ||||
| 			None | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			None | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,148 @@ | |||
| use std:: | ||||
| { | ||||
|     sync::mpsc, | ||||
|     time::Instant, | ||||
| }; | ||||
| 
 | ||||
| use eframe::egui; | ||||
| 
 | ||||
| use crate:: | ||||
| { | ||||
|     capture::Capture, | ||||
|     controller:: | ||||
|     { | ||||
|         Controller, | ||||
|         MsgFromController, | ||||
|         JpegFrame, | ||||
|         RgbaFrame, | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| pub enum MsgToDriver | ||||
| { | ||||
|     GuiNeedsRgbaFrame, | ||||
|     GotCapture ((Capture, JpegFrame)), | ||||
|     DecodedJpegToRgba (RgbaFrame), | ||||
| } | ||||
| 
 | ||||
| pub enum MsgToGui | ||||
| { | ||||
|     NewRgbaFrame (RgbaFrame), | ||||
| } | ||||
| 
 | ||||
| pub struct Driver | ||||
| { | ||||
|     send: mpsc::SyncSender <MsgToDriver>, | ||||
|     recv: mpsc::Receiver <MsgToDriver>, | ||||
|     
 | ||||
|     gui_ctx: egui::Context, | ||||
|     send_to_gui: mpsc::SyncSender <MsgToGui>, | ||||
|     
 | ||||
|     capture: Option <Capture>, | ||||
|     
 | ||||
|     ctl: Controller, | ||||
| } | ||||
| 
 | ||||
| fn sleep_ms (ms: u64) | ||||
| { | ||||
|     std::thread::sleep (std::time::Duration::from_millis (ms)); | ||||
| } | ||||
| 
 | ||||
| impl Driver | ||||
| { | ||||
|     pub fn new ( | ||||
|         send: mpsc::SyncSender <MsgToDriver>, | ||||
|         recv: mpsc::Receiver <MsgToDriver>, | ||||
|         gui_ctx: egui::Context, | ||||
|         send_to_gui: mpsc::SyncSender <MsgToGui>, | ||||
|     ) -> Self | ||||
|     { | ||||
|         Self { | ||||
|             send, | ||||
|             recv, | ||||
|             gui_ctx, | ||||
|             send_to_gui, | ||||
|             capture: Some (Capture::new ().unwrap ()), | ||||
|             ctl: Controller::new (Instant::now ()), | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn run (&mut self) | ||||
|     { | ||||
|         let pool = rayon::ThreadPoolBuilder::new().build().unwrap (); | ||||
|         
 | ||||
|         loop | ||||
|         { | ||||
|             match self.recv.recv().unwrap () | ||||
|             { | ||||
|                 MsgToDriver::DecodedJpegToRgba (frame) => | ||||
|                 { | ||||
|                     self.ctl.handle_rgba_frame (frame); | ||||
|                 }, | ||||
|                 MsgToDriver::GotCapture ((capture, jpeg)) => | ||||
|                 { | ||||
|                     self.ctl.handle_capture (jpeg); | ||||
|                     self.capture = Some (capture); | ||||
|                 }, | ||||
|                 MsgToDriver::GuiNeedsRgbaFrame => | ||||
|                 { | ||||
|                     self.ctl.handle_gui_needs_frame (); | ||||
|                 }, | ||||
|             } | ||||
|             
 | ||||
|             while let Some (msg) = self.ctl.poll () | ||||
|             { | ||||
|                 match msg | ||||
|                 { | ||||
|                     MsgFromController::RepaintGui (rgba_frame) => | ||||
|                     { | ||||
|                         self.send_to_gui.send (MsgToGui::NewRgbaFrame (rgba_frame)).unwrap (); | ||||
|                         self.gui_ctx.request_repaint(); | ||||
|                     }, | ||||
|                     MsgFromController::StartJpegDecoder (jpeg_frame) => | ||||
|                     { | ||||
|                         let send = self.send.clone (); | ||||
|                         pool.spawn (move || | ||||
|                         { | ||||
|                             // sleep_ms (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 (); | ||||
|                             
 | ||||
|                             let rgba = RgbaFrame | ||||
|                             { | ||||
|                                 data: rgba, | ||||
|                                 capture_time: jpeg_frame.capture_time, | ||||
|                             }; | ||||
|                             
 | ||||
|                             send.send (MsgToDriver::DecodedJpegToRgba (rgba)).unwrap (); | ||||
|                         }); | ||||
|                     }, | ||||
|                     MsgFromController::StartCapture => | ||||
|                     { | ||||
|                         let mut capture = self.capture.take ().unwrap (); | ||||
|                         let send = self.send.clone (); | ||||
|                         
 | ||||
|                         pool.spawn (move || | ||||
|                         { | ||||
|                             let mut data = vec! [0u8; capture.size_image()]; | ||||
|                             capture.wait_for_frame(&mut data).unwrap (); | ||||
|                             
 | ||||
|                             let frame = JpegFrame | ||||
|                             { | ||||
|                                 data, | ||||
|                                 capture_time: Instant::now (), | ||||
|                             }; | ||||
|                             
 | ||||
|                             // sleep_ms (500);
 | ||||
|                             
 | ||||
|                             send.send (MsgToDriver::GotCapture ((capture, frame))).unwrap (); | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										255
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										255
									
								
								src/main.rs
								
								
								
								
							|  | @ -10,6 +10,15 @@ use std::{ | |||
| use eframe::egui; | ||||
| 
 | ||||
| mod capture; | ||||
| mod controller; | ||||
| mod driver; | ||||
| 
 | ||||
| use driver:: | ||||
| { | ||||
|     Driver, | ||||
|     MsgToDriver, | ||||
|     MsgToGui, | ||||
| }; | ||||
| 
 | ||||
| fn main() -> Result <(), Error> | ||||
| { | ||||
|  | @ -56,7 +65,7 @@ struct App { | |||
|     camera_fps: u64, | ||||
|     latency: Duration, | ||||
|     
 | ||||
|     send_to_ctl: mpsc::SyncSender <MsgToController>, | ||||
|     send_to_ctl: mpsc::SyncSender <MsgToDriver>, | ||||
|     recv_at_gui: mpsc::Receiver <MsgToGui>, | ||||
|     driver_thread: thread::JoinHandle <()>, | ||||
|     
 | ||||
|  | @ -114,7 +123,7 @@ impl eframe::App for App { | |||
|             
 | ||||
|             if self.requesting_frames | ||||
|             { | ||||
|                 self.send_to_ctl.send (MsgToController::GuiNeedsRgbaFrame).unwrap (); | ||||
|                 self.send_to_ctl.send (MsgToDriver::GuiNeedsRgbaFrame).unwrap (); | ||||
|             } | ||||
|             
 | ||||
|             while let Ok (msg) = self.recv_at_gui.try_recv() | ||||
|  | @ -165,248 +174,6 @@ impl eframe::App for App { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| enum MsgToController | ||||
| { | ||||
|     GuiNeedsRgbaFrame, | ||||
|     GotCapture ((capture::Capture, JpegFrame)), | ||||
|     DecodedJpegToRgba (RgbaFrame), | ||||
| } | ||||
| 
 | ||||
| enum MsgToGui | ||||
| { | ||||
|     NewRgbaFrame (RgbaFrame), | ||||
| } | ||||
| 
 | ||||
| enum MsgFromController | ||||
| { | ||||
| 	RepaintGui (RgbaFrame), | ||||
| 	StartCapture, | ||||
| 	StartJpegDecoder (JpegFrame), | ||||
| } | ||||
| 
 | ||||
| #[derive (Clone)] | ||||
| struct JpegFrame | ||||
| { | ||||
|     data: Vec <u8>, | ||||
|     capture_time: Instant, | ||||
| } | ||||
| 
 | ||||
| #[derive (Clone)] | ||||
| struct RgbaFrame | ||||
| { | ||||
|     data: Vec <u8>, | ||||
|     capture_time: Instant, | ||||
| } | ||||
| 
 | ||||
| struct Controller | ||||
| { | ||||
|     gui_has_new_frame: bool, | ||||
|     gui_needs_frame: bool, | ||||
|     
 | ||||
|     capture_is_running: bool, | ||||
|     
 | ||||
|     jpeg_decoder_is_running: bool, | ||||
|     jpeg_decoder_has_new_frame: bool, | ||||
|     jpeg_decoder_needs_frame: bool, | ||||
|     
 | ||||
|     rgba_frame: RgbaFrame, | ||||
|     jpeg_frame: JpegFrame, | ||||
| } | ||||
| 
 | ||||
| impl Controller | ||||
| { | ||||
|     fn new (now: Instant) -> Self | ||||
|     { | ||||
|         Self | ||||
|         { | ||||
|             gui_has_new_frame: false, | ||||
|             gui_needs_frame: false, | ||||
|             
 | ||||
|             capture_is_running: false, | ||||
|             jpeg_decoder_has_new_frame: false, | ||||
|             jpeg_decoder_is_running: false, | ||||
|             jpeg_decoder_needs_frame: false, | ||||
|             
 | ||||
|             rgba_frame: RgbaFrame | ||||
|             { | ||||
|                 data: Default::default (), 
 | ||||
|                 capture_time: now, | ||||
|             }, | ||||
|             jpeg_frame: JpegFrame | ||||
|             { | ||||
|                 data: Default::default (), | ||||
|                 capture_time: now, | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
| 	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.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 <MsgFromController> | ||||
| 	{ | ||||
| 		if self.gui_needs_frame && self.gui_has_new_frame | ||||
| 		{ | ||||
|             self.gui_has_new_frame = false; | ||||
|             self.gui_needs_frame = false; | ||||
|             println! ("RepaintGui"); | ||||
| 			Some (MsgFromController::RepaintGui (self.rgba_frame.clone ())) | ||||
| 		} | ||||
| 		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_decoder_needs_frame = false; | ||||
| 			println! ("StartJpegDecoder"); | ||||
| 			Some (MsgFromController::StartJpegDecoder (self.jpeg_frame.clone ())) | ||||
| 		} | ||||
| 		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.gui_has_new_frame | ||||
| 		{ | ||||
| 			self.jpeg_decoder_needs_frame = true; | ||||
| 			None | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			None | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct Driver | ||||
| { | ||||
|     send: mpsc::SyncSender <MsgToController>, | ||||
|     recv: mpsc::Receiver <MsgToController>, | ||||
|     
 | ||||
|     gui_ctx: egui::Context, | ||||
|     send_to_gui: mpsc::SyncSender <MsgToGui>, | ||||
|     
 | ||||
|     capture: Option <capture::Capture>, | ||||
|     
 | ||||
|     ctl: Controller, | ||||
| } | ||||
| 
 | ||||
| impl Driver | ||||
| { | ||||
|     fn new ( | ||||
|         send: mpsc::SyncSender <MsgToController>, | ||||
|         recv: mpsc::Receiver <MsgToController>, | ||||
|         gui_ctx: egui::Context, | ||||
|         send_to_gui: mpsc::SyncSender <MsgToGui>, | ||||
|     ) -> Self | ||||
|     { | ||||
|         Self { | ||||
|             send, | ||||
|             recv, | ||||
|             gui_ctx, | ||||
|             send_to_gui, | ||||
|             capture: Some (capture::Capture::new ().unwrap ()), | ||||
|             ctl: Controller::new (Instant::now ()), | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     fn run (&mut self) | ||||
|     { | ||||
|         let pool = rayon::ThreadPoolBuilder::new().build().unwrap (); | ||||
|         
 | ||||
|         loop | ||||
|         { | ||||
|             match self.recv.recv().unwrap () | ||||
|             { | ||||
|                 MsgToController::DecodedJpegToRgba (frame) => | ||||
|                 { | ||||
|                     self.ctl.handle_rgba_frame (frame); | ||||
|                 }, | ||||
|                 MsgToController::GotCapture ((capture, jpeg)) => | ||||
|                 { | ||||
|                     self.ctl.handle_capture (jpeg); | ||||
|                     self.capture = Some (capture); | ||||
|                 }, | ||||
|                 MsgToController::GuiNeedsRgbaFrame => | ||||
|                 { | ||||
|                     self.ctl.handle_gui_needs_frame (); | ||||
|                 }, | ||||
|             } | ||||
|             
 | ||||
|             while let Some (msg) = self.ctl.poll () | ||||
|             { | ||||
|                 match msg | ||||
|                 { | ||||
|                     MsgFromController::RepaintGui (rgba_frame) => | ||||
|                     { | ||||
|                         self.send_to_gui.send (MsgToGui::NewRgbaFrame (rgba_frame)).unwrap (); | ||||
|                         self.gui_ctx.request_repaint(); | ||||
|                     }, | ||||
|                     MsgFromController::StartJpegDecoder (jpeg_frame) => | ||||
|                     { | ||||
|                         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 (); | ||||
|                             
 | ||||
|                             let rgba = RgbaFrame | ||||
|                             { | ||||
|                                 data: rgba, | ||||
|                                 capture_time: jpeg_frame.capture_time, | ||||
|                             }; | ||||
|                             
 | ||||
|                             send.send (MsgToController::DecodedJpegToRgba (rgba)).unwrap (); | ||||
|                         }); | ||||
|                     }, | ||||
|                     MsgFromController::StartCapture => | ||||
|                     { | ||||
|                         let mut capture = self.capture.take ().unwrap (); | ||||
|                         let send = self.send.clone (); | ||||
|                         
 | ||||
|                         pool.spawn (move || | ||||
|                         { | ||||
|                             let mut data = vec! [0u8; capture.size_image()]; | ||||
|                             capture.wait_for_frame(&mut data).unwrap (); | ||||
|                             
 | ||||
|                             let frame = JpegFrame | ||||
|                             { | ||||
|                                 data, | ||||
|                                 capture_time: Instant::now (), | ||||
|                             }; | ||||
|                             
 | ||||
|                             send.send (MsgToController::GotCapture ((capture, frame))).unwrap (); | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn main_egui () | ||||
| { | ||||
|     let native_options = eframe::NativeOptions::default(); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 _
						_