1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
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(){
frlock = cv.wait(frlock).map_err(|e| anyhow!("{}", e))?;
}
if let Some(fr) = frlock.take(){
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))?;
*frlock = Some(OwnedFrame::from_ref(&fr));
Ok(())
})??;
cv.notify_all();
if iothread.is_finished(){
iothread.join().unwrap()?;
break;
}
}
panic!()
})
}
|