#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct EyeSourceMode { pub width: u32, pub height: u32, pub fps: u32, } const GC311_H264_SOURCE_MODES: [EyeSourceMode; 2] = [ EyeSourceMode { width: 1920, height: 1080, fps: 60, }, EyeSourceMode { width: 1280, height: 720, fps: 60, }, ]; pub fn native_eye_source_modes() -> &'static [EyeSourceMode] { &GC311_H264_SOURCE_MODES } pub fn default_eye_source_mode() -> EyeSourceMode { GC311_H264_SOURCE_MODES[0] } pub fn display_size_for_source_mode(mode: EyeSourceMode) -> (u32, u32) { match (mode.width, mode.height) { // GC311 exposes SD widescreen source modes with non-square pixels. Render them // into a square-pixel frame before the GTK preview consumes them. (720, 576) => (1024, 576), (720, 480) => (854, 480), _ => (mode.width, mode.height), } } pub fn eye_source_mode_for_request(requested_width: u32, requested_height: u32) -> EyeSourceMode { if requested_width == 0 || requested_height == 0 { return default_eye_source_mode(); } native_eye_source_modes() .iter() .copied() .find(|mode| mode.width <= requested_width && mode.height <= requested_height) .unwrap_or_else(|| *native_eye_source_modes().last().expect("source mode list")) } #[cfg(test)] mod tests { use super::*; #[test] fn defaults_to_1080p60() { assert_eq!( default_eye_source_mode(), EyeSourceMode { width: 1920, height: 1080, fps: 60, } ); } #[test] fn picks_the_highest_supported_mode_that_fits_the_request() { assert_eq!( eye_source_mode_for_request(1920, 1080), EyeSourceMode { width: 1920, height: 1080, fps: 60, } ); assert_eq!( eye_source_mode_for_request(1600, 900), EyeSourceMode { width: 1280, height: 720, fps: 60, } ); assert_eq!( eye_source_mode_for_request(960, 540), EyeSourceMode { width: 1280, height: 720, fps: 60, } ); } #[test] fn reports_square_pixel_display_size_for_each_native_mode() { assert_eq!( display_size_for_source_mode(EyeSourceMode { width: 1920, height: 1080, fps: 60, }), (1920, 1080) ); assert_eq!( display_size_for_source_mode(EyeSourceMode { width: 1280, height: 720, fps: 60, }), (1280, 720) ); } }