Dequeue the next frame (blocking). 出队下一帧(阻塞)。 Blocks until AVFoundation delivers a frame, then copies BGRA32 pixel data into `self.frame_buf`. Returns a `RawFrame<'_>` borrowing that buffer. 阻塞直到 AVFoundation 投递一帧,然后将 BGRA32 像素数据拷贝到 `self.frame_buf`。返回借用该缓冲区的 `RawFrame<'_>`。
(&mut self)
| 207 | /// 阻塞直到 AVFoundation 投递一帧,然后将 BGRA32 像素数据拷贝到 |
| 208 | /// `self.frame_buf`。返回借用该缓冲区的 `RawFrame<'_>`。 |
| 209 | pub fn dequeue(&mut self) -> Result<RawFrame<'_>> { |
| 210 | let buf_cap = self.frame_buf.len() as c_uint; |
| 211 | let mut out_len: c_uint = 0; |
| 212 | let mut out_w: c_uint = 0; |
| 213 | let mut out_h: c_uint = 0; |
| 214 | let mut out_seq: u64 = 0; |
| 215 | let mut out_ts: u64 = 0; |
| 216 | |
| 217 | let ret = unsafe { |
| 218 | sys::avf_camera_dequeue_blocking( |
| 219 | self.cam, |
| 220 | self.frame_buf.as_mut_ptr(), |
| 221 | buf_cap, |
| 222 | &mut out_len, |
| 223 | &mut out_w, |
| 224 | &mut out_h, |
| 225 | &mut out_seq, |
| 226 | &mut out_ts, |
| 227 | ) |
| 228 | }; |
| 229 | |
| 230 | if ret == AVF_ERR_STOPPED { |
| 231 | return Err(CameraError::Io(std::io::Error::new( |
| 232 | std::io::ErrorKind::BrokenPipe, |
| 233 | "camera session stopped", |
| 234 | ))); |
| 235 | } |
| 236 | if ret != AVF_OK { |
| 237 | return Err(CameraError::Io(std::io::Error::other(format!( |
| 238 | "dequeue error (code {})", |
| 239 | ret |
| 240 | )))); |
| 241 | } |
| 242 | |
| 243 | // If the camera reported dimensions larger than our buffer, grow it for |
| 244 | // the next frame. This frame's data is already truncated but avoids UB. |
| 245 | // 如果摄像头报告的尺寸大于缓冲区,为下一帧扩容。 |
| 246 | // 本帧数据已截断,但避免了未定义行为。 |
| 247 | let expected = (out_w * out_h * 4) as usize; |
| 248 | if self.frame_buf.len() < expected { |
| 249 | self.frame_buf.resize(expected, 0); |
| 250 | } |
| 251 | |
| 252 | Ok(RawFrame { |
| 253 | index: 0, // AVFoundation manages buffers internally |
| 254 | data: &self.frame_buf[..out_len as usize], |
| 255 | width: out_w, |
| 256 | height: out_h, |
| 257 | pixel_format: PixelFormat::Bgra32, |
| 258 | sequence: out_seq, |
| 259 | timestamp_us: out_ts, |
| 260 | }) |
| 261 | } |
| 262 | } |
| 263 | |
| 264 | impl Drop for AvfBackend { |