diff options
| author | dyknon dyknonr5fjp | 2025-03-02 03:24:49 +0900 |
|---|---|---|
| committer | dyknon dyknonr5fjp | 2025-03-02 03:24:49 +0900 |
| commit | 49fdc6dd7b1a166846df75f17f9902de5043b634 (patch) | |
| tree | fd5db0bedf98587c557ad7bc69fa3e51349267a0 /src | |
| parent | 55cae3e208dcc5579470f90d16a49ad7331b6b23 (diff) | |
show delay.
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/usshcamera.rs | 21 | ||||
| -rw-r--r-- | src/gtk.rs | 25 | ||||
| -rw-r--r-- | src/source.rs | 3 | ||||
| -rw-r--r-- | src/v4l2cairo.rs | 5 |
4 files changed, 28 insertions, 26 deletions
diff --git a/src/bin/usshcamera.rs b/src/bin/usshcamera.rs index 6d73e92..ea09a03 100644 --- a/src/bin/usshcamera.rs +++ b/src/bin/usshcamera.rs @@ -1,9 +1,9 @@ use anyhow::{anyhow, Result}; use sshcamera::v4l2::{Device as V4l2, Field}; -use sshcamera::v4l2abst::CaptStream; use sshcamera::io::RWBundle; +use sshcamera::source; use std::env; -use std::io::{self, Read as _, Write as _}; +use std::io; fn main() -> Result<()>{ let mut args = env::args(); @@ -20,7 +20,7 @@ fn main() -> Result<()>{ let v = V4l2::open(arg1)?; // TODO: It should be better. - let mut c = v.captstream_builder()? + let c = v.captstream_builder()? .set_pixelformat("MJPG".into()) //.set_pixelformat("YUYV".into()) .set_field(Field::None) @@ -28,17 +28,6 @@ fn main() -> Result<()>{ assert!(["YUYV", "MJPG"].contains(&c.pixelformat().as_str())); assert!(c.field() == Field::None); - let mut io = RWBundle(io::stdin(), io::stdout()); - loop{ - CaptStream::next(&mut c, |frame|{ - frame.serialize(&mut io)?; - io.flush()?; - let mut rb = [0]; - io.read_exact(&mut rb)?; - if rb[0] != 0x2e{ - return Err(anyhow!("protocol error")); - } - Ok(()) - })??; - } + let io = RWBundle(io::stdin(), io::stdout()); + source::main(c, io) } @@ -7,7 +7,7 @@ use glib::{clone, spawn_future_local}; use std::thread; use std::sync::{Arc, Mutex}; use std::rc::Rc; -use std::cell::RefCell; +use std::cell::Cell; use crate::sync::Signal; use std::future::poll_fn; use std::task::Poll; @@ -107,41 +107,54 @@ fn activate<Attr: Overlay>(app: >k::Application, apps: Arc<AppState<Attr>>){ let draw = gtk::DrawingArea::new(); let overlay = Attr::empty().unwrap(); - let frame_cache: Rc<RefCell<Option<cairo::ImageSurface>>> - = Rc::new(RefCell::new(None)); + let frame_cache: Rc<Cell<Option<cairo::ImageSurface>>> + = Rc::new(Cell::new(None)); + let attr_cache: Rc<Cell<Option<Attr>>> = Rc::new(Cell::new(None)); draw.set_draw_func(clone!{ #[strong] frame_cache, move |_draw, ctx, canvas_w, canvas_h|{ ctx.set_source_rgb(0., 0., 0.); ctx.paint().unwrap(); - if let Some(image) = frame_cache.borrow_mut().clone(){ + if let Some(image) = frame_cache.take(){ let ipat = cairo::SurfacePattern::create(&image); let scale = ((canvas_w as f64) / (image.width() as f64)).min( (canvas_h as f64) / (image.height() as f64)); ctx.scale(scale, scale); ctx.set_source(&ipat).unwrap(); ctx.paint().unwrap(); + frame_cache.replace(Some(image)); } } }); + overlay.add_tick_callback(clone!{ + #[strong] attr_cache, + move |overlay, _clock|{ + if let Some(attr) = attr_cache.take(){ + attr.update(overlay).unwrap(); + attr_cache.replace(Some(attr)); + } + glib::ControlFlow::Continue + } + }); spawn_future_local(poll_fn(clone!{ #[strong] apps, #[strong] draw, #[strong] frame_cache, + #[strong] attr_cache, #[strong] overlay, move |ctx|{ loop{ match apps.update.lock().unwrap().poll(ctx){ Poll::Ready(_) => { if let Some(newfb) = apps.next.lock().unwrap().take(){ - let mut frame_cache = frame_cache.borrow_mut(); if let Some(lastframe) = frame_cache.take(){ apps.fbpool.lock().unwrap() .put(lastframe.take_data().unwrap()); } - *frame_cache = Some(newfb.image.into_inner()); + frame_cache.replace(Some(newfb.image.into_inner())); newfb.attr.update(&overlay).unwrap(); + attr_cache.replace(Some(newfb.attr)); } draw.queue_draw(); }, diff --git a/src/source.rs b/src/source.rs index a99bcd2..2563a99 100644 --- a/src/source.rs +++ b/src/source.rs @@ -38,11 +38,9 @@ pub fn main(mut cam: impl CaptStream, mut io: impl Read + Write + Send) loop{ let mut frlock = frame.lock().map_err(|e| anyhow!("{}", e))?; while frlock.is_none(){ - eprintln!("is none"); frlock = cv.wait(frlock).map_err(|e| anyhow!("{}", e))?; } if let Some(fr) = frlock.take(){ - eprintln!("fgot"); drop(frlock); fr.borrow().serialize(&mut io)?; io.flush()?; @@ -58,7 +56,6 @@ pub fn main(mut cam: impl CaptStream, mut io: impl Read + Write + Send) loop{ cam.next(|fr| -> Result<()>{ let mut frlock = frame.lock().map_err(|e| anyhow!("{}", e))?; - eprintln!("fset"); *frlock = Some(OwnedFrame::from_ref(&fr)); Ok(()) })??; diff --git a/src/v4l2cairo.rs b/src/v4l2cairo.rs index de89df8..795575b 100644 --- a/src/v4l2cairo.rs +++ b/src/v4l2cairo.rs @@ -125,8 +125,11 @@ impl cgtk::Overlay for Overlay{ Ok(()) } fn update(&self, widget: >k::Label) -> Result<()>{ + let delay = Local::now() - &self.timestamp; widget.set_label( - &self.timestamp.format("%Y/%m/%d %H:%M:%S%.3f").to_string()); + &format!("{} (delay={}ms)", + self.timestamp.format("%Y/%m/%d %H:%M:%S%.3f"), + delay.num_milliseconds())); Ok(()) } } |
