(&mut self, mat: &mut Mat)
| 166 | } |
| 167 | |
| 168 | pub fn read(&mut self, mat: &mut Mat) -> Result<bool> { |
| 169 | if !self.is_opened { |
| 170 | return Ok(false); |
| 171 | } |
| 172 | if self.cmd_tx.send(Command::NextFrame).is_err() { |
| 173 | return Err(anyhow!("Background worker is dead")); |
| 174 | } |
| 175 | |
| 176 | let response = self |
| 177 | .res_rx |
| 178 | .recv() |
| 179 | .map_err(|_| anyhow!("Failed to receive response"))?; |
| 180 | |
| 181 | match response { |
| 182 | Response::FrameData { |
| 183 | width, |
| 184 | height, |
| 185 | data, |
| 186 | fourcc, |
| 187 | } => { |
| 188 | self.width = width as i32; |
| 189 | self.height = height as i32; |
| 190 | |
| 191 | // 确保 Mat 大小匹配 |
| 192 | let target_len = (width * height * 3) as usize; |
| 193 | if mat.data.len() != target_len { |
| 194 | mat.data = vec![0; target_len]; |
| 195 | } |
| 196 | mat.rows = height as i32; |
| 197 | mat.cols = width as i32; |
| 198 | mat.channels = 3; |
| 199 | mat.step = (width * 3) as usize; |
| 200 | |
| 201 | let fcc = FourCC(fourcc); |
| 202 | if fcc == FourCC::YUYV { |
| 203 | yuyv_to_bgr(&data, &mut mat.data, width as usize, height as usize); |
| 204 | } else if fcc == FourCC::BGRA { |
| 205 | bgra_to_bgr(&data, &mut mat.data, width as usize, height as usize); |
| 206 | } else if fcc == FourCC::NV12 { |
| 207 | nv12_to_bgr(&data, &mut mat.data, width as usize, height as usize); |
| 208 | } else if fcc == FourCC::MJPEG { |
| 209 | // === TurboJPEG v1.4.0 极速解码 === |
| 210 | #[cfg(feature = "turbojpeg")] |
| 211 | { |
| 212 | // 1. 创建解压器 |
| 213 | // v1.4.0 API: Decompressor::new() 返回 Result |
| 214 | let mut decompressor = Decompressor::new() |
| 215 | .map_err(|e| anyhow!("Failed to init TurboJPEG: {}", e))?; |
| 216 | |
| 217 | // 2. 读取头部信息 (可选,但为了保险起见,获取精确的图像尺寸) |
| 218 | let header = decompressor |
| 219 | .read_header(&data) |
| 220 | .map_err(|e| anyhow!("Failed to read JPEG header: {}", e))?; |
| 221 | |
| 222 | // 3. 构建 Image 视图,直接指向 Mat 的数据 |
| 223 | // 这是一个 Zero-Copy 操作,Image 只是 Mat.data 的一个借用封装 |
| 224 | let image = Image { |
| 225 | pixels: mat.data.as_mut_slice(), // 直接写入 Mat |
no test coverage detected