use crate::gpu::video_stream_void::{self, VideoStreamConfig};
use crate::gpu::void::{CaptureKind, ParamDef, VoidRegistration};
pub const TYPE_ID: &str = "camera";
const PARAMS: &[ParamDef] = &[
ParamDef::Bool {
name: "freeze",
default: false,
},
ParamDef::Int {
name: "frame_divisor",
min: 1,
max: 60,
default: 4,
},
];
fn selfie_flip(canvas_w: u32, _canvas_h: u32) -> crate::transform::Transform {
crate::transform::Transform::from_affine([-1.0, 0.0, canvas_w as f32, 0.0, 1.0, 0.0])
}
static CONFIG: VideoStreamConfig = VideoStreamConfig {
type_id: TYPE_ID,
display_name: "Camera",
icon: "tabler:camera",
params: PARAMS,
capture_kind: CaptureKind::Camera,
default_transform: selfie_flip,
};
pub fn register() -> VoidRegistration {
video_stream_void::registration(&CONFIG, |params, shared| {
video_stream_void::build_void(&CONFIG, params, shared)
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::gpu::params::ParamValue;
#[test]
fn config_matches_type_id() {
assert_eq!(CONFIG.type_id, TYPE_ID);
assert_eq!(register().type_id, "camera");
}
#[test]
fn params_are_freeze_and_divisor() {
let names: Vec<_> = PARAMS.iter().map(|p| p.name()).collect();
assert_eq!(names, vec!["freeze", "frame_divisor"]);
}
#[test]
fn seeds_horizontal_flip() {
let t = selfie_flip(200, 100);
let m = t.to_affine();
assert_eq!(m, [-1.0, 0.0, 200.0, 0.0, 1.0, 0.0]);
assert_eq!(
crate::transform::affine_transform(&m, 0.0, 50.0),
(200.0, 50.0)
);
assert_eq!(
crate::transform::affine_transform(&m, 200.0, 50.0),
(0.0, 50.0)
);
}
#[test]
fn default_divisor_round_trips_through_registration() {
let reg = register();
let defaults: Vec<ParamValue> = reg.params.iter().map(|d| d.default_value()).collect();
assert_eq!(defaults[0], ParamValue::Bool(false));
assert_eq!(defaults[1], ParamValue::Int(4));
}
}