obscura_getframes/
obscura_getframes.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
 * SPDX-FileCopyrightText: 2023 Purism, SPC <https://puri.sm>
 * SPDX-FileCopyrightText: 2025 DorotaC
 * SPDX-License-Identifier: MPL-2.0 OR LGPL-2.1-or-later
 */

/*! Fetches a YUV frame from a camera and saves it to file */

use clap::Parser;
use std::fs;
use std::io;
use std::io::Write;
use vidi;
use vidi::CaptureStream;
use vidi::config::ConfigRequest;
use vidi_tools::select_camera;

#[derive(Parser)]
#[clap(about, verbatim_doc_comment)]
struct Args {
    /// Name of the camera device
    device: Option<String>,
}

fn main() -> io::Result<()> {
    tracing_subscriber::fmt::init();
    let args = Args::parse();
    let cameras_list = vidi::actors::camera_list::spawn()?;
    
    select_camera(
        cameras_list,
        args.device,
        |camera| {
            let camera = camera.unwrap();
            let mut camera = camera.acquire();
            if let Ok(ref mut camera) = camera {
                let configs = camera.get_supported_configs().expect("No useable configs found");
                let device_config = configs.query_configs(ConfigRequest::default()).iter().next().unwrap();
                let config = device_config.as_config().clone();
                println!("Capturing res {}×{}, format {}", config.width, config.height, config.fourcc.to_string());
                let mut stream = camera.start(device_config, 4).unwrap();
                let (buf, meta, _next) = stream.next().unwrap();
                let mmap = buf.memory_map_ro().unwrap();
                let data = mmap.as_slice();

                println!(
                    "Buffer size: {}, seq: {}, timestamp: {}",
                    data.len(),
                    meta.sequence,
                    meta.timestamp
                );
                let filename = format!(
                    "frame.{}",
                    match config.fourcc.repr.as_slice() {
                        b"YUYV" => "yuyv",
                        _ => config.fourcc.str().unwrap_or("raw"),
                    },
                );
                println!("Writing to {}", filename);
                        
                fs::File::create(filename).unwrap().write_all(&data).unwrap();
            }

            Ok(())
        },
    )
}