115 lines
2.8 KiB
Rust
115 lines
2.8 KiB
Rust
#[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)
|
|
);
|
|
}
|
|
}
|