summaryrefslogtreecommitdiff
path: root/src/source.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/source.rs')
-rw-r--r--src/source.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/source.rs b/src/source.rs
new file mode 100644
index 0000000..a99bcd2
--- /dev/null
+++ b/src/source.rs
@@ -0,0 +1,73 @@
+use anyhow::{anyhow, Result};
+use std::thread;
+use std::sync::{Mutex, Condvar};
+use crate::v4l2abst::{CaptStream, Frame};
+use std::io::{Read, Write};
+
+struct OwnedFrame(Frame<'static>, Vec<u8>);
+impl OwnedFrame{
+ fn borrow(&self) -> Frame<'_>{
+ Frame{
+ format: self.0.format,
+ width: self.0.width,
+ height: self.0.height,
+ stride: self.0.stride,
+ buf: &self.1,
+ timestamp: self.0.timestamp,
+ }
+ }
+ fn from_ref<'a>(src: &Frame<'a>) -> Self{
+ let r0 = Frame{
+ format: src.format,
+ width: src.width,
+ height: src.height,
+ stride: src.stride,
+ buf: &[],
+ timestamp: src.timestamp,
+ };
+ OwnedFrame(r0, src.buf.into())
+ }
+}
+
+pub fn main(mut cam: impl CaptStream, mut io: impl Read + Write + Send)
+-> Result<()>{
+ let frame: Mutex<Option<OwnedFrame>> = Mutex::new(None);
+ let cv = Condvar::new();
+ thread::scope(|scope|{
+ let iothread = scope.spawn(|| -> Result<()>{
+ 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()?;
+
+ let mut rb = [0];
+ io.read_exact(&mut rb)?;
+ if rb[0] != 0x2e{
+ return Err(anyhow!("protocol error"));
+ }
+ }
+ }
+ });
+ loop{
+ cam.next(|fr| -> Result<()>{
+ let mut frlock = frame.lock().map_err(|e| anyhow!("{}", e))?;
+ eprintln!("fset");
+ *frlock = Some(OwnedFrame::from_ref(&fr));
+ Ok(())
+ })??;
+ cv.notify_all();
+ if iothread.is_finished(){
+ iothread.join().unwrap()?;
+ break;
+ }
+ }
+ panic!()
+ })
+}