👕 refactor

main
_ 2023-09-12 22:24:48 -05:00
parent 99bb54b26e
commit b90c934242
4 changed files with 283 additions and 246 deletions

View File

@ -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 ();

124
src/controller.rs Normal file
View File

@ -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
}
}
}

148
src/driver.rs Normal file
View File

@ -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 ();
});
}
}
}
}
}
}

View File

@ -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();