lesavka/common/src/eye_source.rs

115 lines
2.8 KiB
Rust
Raw Normal View History

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EyeSourceMode {
pub width: u32,
pub height: u32,
pub fps: u32,
}
2026-04-19 22:41:20 -03:00
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 {
2026-04-19 22:41:20 -03:00
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)
);
}
}