Decode a [`Frame`] into a BGR [`Mat`]. 将 [`Frame`] 解码为 BGR [`Mat`]。 The `decompressor` parameter is for reusing a turbojpeg Decompressor across frames (avoiding per-frame allocation). Pass `None` to create a temporary one. `decompressor` 参数用于跨帧复用 turbojpeg Decompressor (避免每帧分配)。传入 `None` 则创建临时的。
(
frame: &Frame<'_>,
mat: &mut Mat,
#[cfg(feature = "turbojpeg")] _decompressor: Option<&mut turbojpeg::Decompressor>,
#[cfg(not(feature = "turbojpeg"))] _decompressor: Option<()>,
)
| 34 | /// `decompressor` 参数用于跨帧复用 turbojpeg Decompressor |
| 35 | /// (避免每帧分配)。传入 `None` 则创建临时的。 |
| 36 | pub fn decode_frame( |
| 37 | frame: &Frame<'_>, |
| 38 | mat: &mut Mat, |
| 39 | #[cfg(feature = "turbojpeg")] _decompressor: Option<&mut turbojpeg::Decompressor>, |
| 40 | #[cfg(not(feature = "turbojpeg"))] _decompressor: Option<()>, |
| 41 | ) -> Result<()> { |
| 42 | let w = frame.width(); |
| 43 | let h = frame.height(); |
| 44 | |
| 45 | match frame.pixel_format() { |
| 46 | PixelFormat::Mjpeg => { |
| 47 | mat.ensure_size(h, w, 3); |
| 48 | decode_mjpeg(frame.data(), mat)?; |
| 49 | } |
| 50 | PixelFormat::Yuyv => { |
| 51 | mat.ensure_size(h, w, 3); |
| 52 | yuyv_to_bgr(frame.data(), mat.data_mut(), w as usize, h as usize); |
| 53 | } |
| 54 | PixelFormat::Bgr24 => { |
| 55 | // Already BGR — just copy. |
| 56 | // 已经是 BGR —— 直接拷贝。 |
| 57 | mat.ensure_size(h, w, 3); |
| 58 | let expected = (w * h * 3) as usize; |
| 59 | if frame.data().len() >= expected { |
| 60 | mat.data_mut()[..expected].copy_from_slice(&frame.data()[..expected]); |
| 61 | } |
| 62 | } |
| 63 | PixelFormat::Rgb24 => { |
| 64 | // RGB → BGR: swap R and B channels. |
| 65 | // RGB → BGR:交换 R 和 B 通道。 |
| 66 | mat.ensure_size(h, w, 3); |
| 67 | rgb_to_bgr(frame.data(), mat.data_mut()); |
| 68 | } |
| 69 | PixelFormat::Bgra32 => { |
| 70 | // BGRA32 → BGR24: drop the alpha channel. |
| 71 | // macOS AVFoundation native format (kCVPixelFormatType_32BGRA). |
| 72 | // BGRA32 → BGR24:去掉 Alpha 通道。 |
| 73 | // macOS AVFoundation 原生格式(kCVPixelFormatType_32BGRA)。 |
| 74 | mat.ensure_size(h, w, 3); |
| 75 | bgra32_to_bgr(frame.data(), mat.data_mut()); |
| 76 | } |
| 77 | other => { |
| 78 | return Err(CameraError::DecodeError(format!( |
| 79 | "unsupported pixel format for decode: {:?}", |
| 80 | other |
| 81 | ))); |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | Ok(()) |
| 86 | } |
| 87 | |
| 88 | // ─── MJPEG decode ─────────────────────────────────────────────────────────── |
| 89 |
no test coverage detected