1use libcamera::{
2 camera::{ActiveCamera, CameraConfiguration},
3 camera_manager::CameraManager,
4 framebuffer_allocator::{FrameBuffer, FrameBufferAllocator},
5 framebuffer_map::MemoryMappedFrameBuffer,
6 properties,
7 request::{Request, ReuseFlag},
8 stream::StreamRole,
9};
10
11#[cfg(feature = "rerun")]
12use re_types::archetypes::EncodedImage;
13use std::{error::Error, sync::Arc, time::Duration};
14use tokio::sync::watch;
15use yuvutils_rs::{yuv420_to_rgb, YuvPlanarImage, YuvRange, YuvStandardMatrix};
16
17#[cfg(feature = "rerun")]
18use crate::Rerun;
19pub fn load_cameras(frame_tx: watch::Sender<Arc<Vec<u8>>>) -> Result<(), Box<dyn Error>> {
20 let man = CameraManager::new()?;
21 let cameras = man.cameras();
22 assert!(cameras.len() > 0, "connect a camera");
24 let cam = cameras.get(0).unwrap();
25 info!("using camera '{}'", cam.id());
26 let cfgg = cam
27 .generate_configuration(&[StreamRole::VideoRecording])
28 .unwrap();
29 dbg!(&cfgg);
30
31 let active_cam = cam.acquire().unwrap();
32 let mut cw = CamWrapper::new(active_cam, cfgg, frame_tx);
33 cw.setup();
34 cw.run();
35
36 Ok(())
37}
38
39pub struct CamWrapper<'cam> {
40 cam: ActiveCamera<'cam>,
41 alloc: FrameBufferAllocator,
42 frame_tx: watch::Sender<Arc<Vec<u8>>>,
43 cam_tx: std::sync::mpsc::Sender<Request>,
44 cam_rx: std::sync::mpsc::Receiver<Request>,
45 configs: CameraConfiguration,
46}
47impl<'cam> CamWrapper<'cam> {
48 pub fn new(
50 mut cam: ActiveCamera<'cam>,
51 mut cfgg: CameraConfiguration,
52 frame_tx: watch::Sender<Arc<Vec<u8>>>,
53 ) -> Self {
54 let alloc = FrameBufferAllocator::new(&cam);
55 cam.configure(&mut cfgg).unwrap();
56 let (cam_tx, cam_rx) = std::sync::mpsc::channel();
57 Self {
58 cam,
59 alloc,
60 cam_tx,
61 cam_rx,
62 frame_tx,
63 configs: cfgg,
64 }
65 }
66
67 pub fn setup(&mut self) {
69 use libcamera::controls::*;
70 let stream = self.configs.get(0).unwrap();
71 let stream = stream.stream().unwrap();
72 let buffers = self
74 .alloc
75 .alloc(&stream)
76 .unwrap()
77 .into_iter()
78 .map(|buf| MemoryMappedFrameBuffer::new(buf).unwrap())
79 .collect::<Vec<_>>();
80 let reqs = buffers
81 .into_iter()
82 .enumerate()
83 .map(|(i, buf)| -> Result<Request, Box<dyn Error>> {
84 let mut req = self.cam.create_request(Some(i as u64)).unwrap();
86 {
88 let ctrl = &mut req.controls_mut();
89 (*ctrl).set(AfMode::Auto)?;
91 (*ctrl).set(AfSpeed::Fast)?;
92 }
101 req.add_buffer(&stream, buf)?;
103 Ok(req)
104 })
105 .map(|x| x.unwrap())
106 .collect::<Vec<_>>();
107 let tx = self.cam_tx.clone();
108 self.cam.on_request_completed(move |req| {
109 tx.send(req).unwrap();
110 });
111 self.cam.start(None).unwrap();
112 for req in reqs {
113 self.cam.queue_request(req).unwrap();
114 }
115 }
117
118 pub fn get_frame(&mut self) {
120 let stream = self.configs.get(0).unwrap().stream().unwrap();
121 let mut req = self
122 .cam_rx
123 .recv_timeout(Duration::from_millis(2000))
124 .expect("camera request failed");
125 let framebuffer: &MemoryMappedFrameBuffer<FrameBuffer> = req.buffer(&stream).unwrap();
126 let planes = framebuffer.data();
127 let y_plane = planes.get(0).unwrap();
128 let u_plane = planes.get(1).unwrap();
129 let v_plane = planes.get(2).unwrap();
130 let image = YuvPlanarImage {
131 width: 1920,
132 height: 1080,
133 y_plane,
134 u_plane,
135 v_plane,
136 y_stride: 1920,
137 u_stride: 960,
138 v_stride: 960,
139 };
140 let mut buff = vec![0u8; 6_220__800];
141 yuv420_to_rgb(
142 &image,
143 &mut buff,
144 5760,
145 YuvRange::Limited,
146 YuvStandardMatrix::Bt601,
147 )
148 .unwrap();
149 debug!("color converted. sending...");
150 self.frame_tx.send(Arc::new(buff.clone())).unwrap();
151 drop(buff);
152 req.reuse(ReuseFlag::REUSE_BUFFERS);
153 debug!("queueing another request");
154 self.cam.queue_request(req).unwrap();
155 }
156
157 pub fn run(mut self) {
159 loop {
160 self.get_frame();
161 }
162 }
163}