capture_callback/
capture_callback.rs

1use ccap::{LogLevel, PixelFormat, PropertyName, Provider, Result, Utils};
2use std::sync::{Arc, Mutex};
3use std::thread;
4use std::time::Duration;
5
6fn main() -> Result<()> {
7    // Enable verbose log to see debug information
8    Utils::set_log_level(LogLevel::Verbose);
9
10    // Set error callback to receive error notifications
11    Provider::set_error_callback(|error_code, description| {
12        eprintln!(
13            "Camera Error - Code: {}, Description: {}",
14            error_code, description
15        );
16    });
17
18    let temp_provider = Provider::new()?;
19    let devices = temp_provider.list_devices()?;
20    if devices.is_empty() {
21        eprintln!("No camera devices found!");
22        return Ok(());
23    }
24
25    for (i, device) in devices.iter().enumerate() {
26        println!("## Found video capture device: {}: {}", i, device);
27    }
28
29    // Select camera device (automatically use first device for testing)
30    let device_index = 0;
31
32    // Create provider with selected device
33    let mut provider = Provider::with_device(device_index)?;
34
35    // Set camera properties
36    let requested_width = 1920;
37    let requested_height = 1080;
38    let requested_fps = 60.0;
39
40    provider.set_property(PropertyName::Width, requested_width as f64)?;
41    provider.set_property(PropertyName::Height, requested_height as f64)?;
42    provider.set_property(
43        PropertyName::PixelFormatOutput,
44        PixelFormat::Bgra32 as u32 as f64,
45    )?;
46    provider.set_property(PropertyName::FrameRate, requested_fps)?;
47
48    // Open and start camera
49    provider.open()?;
50    provider.start()?;
51
52    if !provider.is_started() {
53        eprintln!("Failed to start camera!");
54        return Ok(());
55    }
56
57    // Get real camera properties
58    let real_width = provider.get_property(PropertyName::Width)? as i32;
59    let real_height = provider.get_property(PropertyName::Height)? as i32;
60    let real_fps = provider.get_property(PropertyName::FrameRate)?;
61
62    println!("Camera started successfully, requested resolution: {}x{}, real resolution: {}x{}, requested fps {}, real fps: {}",
63             requested_width, requested_height, real_width, real_height, requested_fps, real_fps);
64
65    // Create directory for captures (using std::fs)
66    std::fs::create_dir_all("./image_capture")
67        .map_err(|e| ccap::CcapError::FileOperationFailed(e.to_string()))?;
68
69    // Statistics tracking
70    let frame_count = Arc::new(Mutex::new(0u32));
71    let frame_count_clone = frame_count.clone();
72
73    // Set frame callback
74    provider.set_new_frame_callback(move |frame| {
75        let mut count = frame_count_clone.lock().unwrap();
76        *count += 1;
77
78        println!(
79            "VideoFrame {} grabbed: width = {}, height = {}, bytes: {}",
80            frame.index(),
81            frame.width(),
82            frame.height(),
83            frame.data_size()
84        );
85
86        // Try to save frame to directory
87        if let Ok(filename) = Utils::dump_frame_to_directory(frame, "./image_capture") {
88            println!("VideoFrame saved to: {}", filename);
89        } else {
90            eprintln!("Failed to save frame!");
91        }
92
93        true // no need to retain the frame
94    })?;
95
96    // Wait for 5 seconds to capture frames
97    println!("Capturing frames for 5 seconds...");
98    thread::sleep(Duration::from_secs(5));
99
100    // Get final count
101    let final_count = *frame_count.lock().unwrap();
102    println!("Captured {} frames, stopping...", final_count);
103
104    // Remove callback before dropping
105    let _ = provider.remove_new_frame_callback();
106
107    Ok(())
108}