MCPcopy Create free account
hub / github.com/RustCV/RustCV / negotiate_format

Method negotiate_format

rustcv-camera/src/backend/linux/mod.rs:285–390  ·  view source on GitHub ↗

Negotiate the best format based on user config and device capabilities. 根据用户配置和设备能力协商最佳格式。 Strategy: 1. If user specified pixel_format → use it (error if unsupported). 2. If user specified resolution → find formats supporting it. 3. Auto-select: prefer MJPEG for fps<60, YUYV for fps>=60. 4. If nothing specified → use device default. 策略: 1. 用户指定了 pixel_format → 直接使用(不支持则报错)。 2. 用户指定了分辨率 → 查找支持该分辨

(&mut self, config: &CameraConfig)

Source from the content-addressed store, hash-verified

283 /// 3. 自动选择:fps<60 优先 MJPEG,fps>=60 优先 YUYV。
284 /// 4. 都未指定 → 使用设备默认值。
285 fn negotiate_format(&mut self, config: &CameraConfig) -> Result<ResolvedConfig> {
286 let fd = self.fd;
287
288 // Collect all supported formats and their resolutions.
289 // 收集所有支持的格式及其分辨率。
290 let mut supported = Vec::new();
291 let mut fmt_idx = 0;
292 while let Ok(desc) = v4l2_sys::enum_formats(fd, fmt_idx) {
293 let pf = PixelFormat::from_fourcc(desc.pixelformat);
294 // Enumerate frame sizes for this format.
295 // 枚举此格式的帧尺寸。
296 let mut size_idx = 0;
297 while let Ok(size) = v4l2_sys::enum_frame_sizes(fd, desc.pixelformat, size_idx) {
298 // V4L2_FRMSIZE_TYPE_DISCRETE = 1
299 if size.type_ == 1 {
300 let discrete = unsafe { &size.__bindgen_anon_1.discrete };
301 supported.push((pf, discrete.width, discrete.height));
302 }
303 size_idx += 1;
304 }
305 fmt_idx += 1;
306 }
307
308 if supported.is_empty() {
309 return Err(CameraError::FormatNotSupported);
310 }
311
312 // Select the best match.
313 // 选择最佳匹配。
314 let target_w = config.width.unwrap_or(640);
315 let target_h = config.height.unwrap_or(480);
316 let target_fps = config.fps.unwrap_or(30);
317
318 let selected = if let Some(pf) = config.pixel_format {
319 // User specified format — find matching resolution.
320 // 用户指定了格式 —— 查找匹配的分辨率。
321 supported
322 .iter()
323 .filter(|(f, _, _)| *f == pf)
324 .min_by_key(|(_, w, h)| {
325 let dw = (*w as i64 - target_w as i64).abs();
326 let dh = (*h as i64 - target_h as i64).abs();
327 dw + dh
328 })
329 .copied()
330 .ok_or(CameraError::FormatNotSupported)?
331 } else {
332 // Auto-select: score each candidate.
333 // 自动选择:对每个候选项评分。
334 //
335 // Scoring:
336 // - Resolution match: lower distance = higher score
337 // - Format preference: MJPEG for low fps, YUYV for high fps
338 // 评分规则:
339 // - 分辨率匹配:距离越小得分越高
340 // - 格式偏好:低帧率优先 MJPEG,高帧率优先 YUYV
341 *supported
342 .iter()

Callers 1

openMethod · 0.80

Calls 5

enum_formatsFunction · 0.85
enum_frame_sizesFunction · 0.85
set_formatFunction · 0.85
to_fourccMethod · 0.80
is_emptyMethod · 0.45

Tested by

no test coverage detected