等待并返回下一帧。 帧数据的生命周期绑定到 `self`(零拷贝借用语义)。
(&mut self)
| 225 | /// |
| 226 | /// 帧数据的生命周期绑定到 `self`(零拷贝借用语义)。 |
| 227 | async fn next_frame(&mut self) -> CvResult<Frame<'_>> { |
| 228 | use rustcv_core::error::CameraError; |
| 229 | |
| 230 | if !self.is_streaming { |
| 231 | return Err(CameraError::Io(std::io::Error::other( |
| 232 | "Stream not started — call start() first", |
| 233 | ))); |
| 234 | } |
| 235 | |
| 236 | // 阻塞等待直到 delegate 推送一帧(或 channel 关闭) |
| 237 | let frame_data = self.receiver.recv().await.ok_or_else(|| { |
| 238 | CameraError::Io(std::io::Error::new( |
| 239 | std::io::ErrorKind::BrokenPipe, |
| 240 | "Capture channel closed", |
| 241 | )) |
| 242 | })?; |
| 243 | |
| 244 | self.current_frame = Some(frame_data); |
| 245 | let f = self.current_frame.as_ref().unwrap(); |
| 246 | |
| 247 | Ok(Frame { |
| 248 | data: &f.data, |
| 249 | width: f.width as u32, |
| 250 | height: f.height as u32, |
| 251 | // 使用 CVPixelBuffer 报告的真实步长,而非估算值 |
| 252 | stride: f.bytes_per_row, |
| 253 | // 像素格式与上面请求的 BGRA 对应 |
| 254 | format: FourCC::new(b'B', b'G', b'R', b'A').into(), |
| 255 | sequence: 0, |
| 256 | timestamp: Timestamp { |
| 257 | hw_raw_ns: f.timestamp_ns, |
| 258 | system_synced: std::time::Duration::ZERO, |
| 259 | }, |
| 260 | metadata: FrameMetadata::default(), |
| 261 | backend_handle: &AVF_HANDLE, |
| 262 | }) |
| 263 | } |
| 264 | |
| 265 | #[cfg(feature = "simulation")] |
| 266 | async fn inject_frame(&mut self, _frame: Frame<'_>) -> CvResult<()> { |