diff --git a/src/include/dav1d/dav1d.rs b/src/include/dav1d/dav1d.rs index 8805c04f0..74505a786 100644 --- a/src/include/dav1d/dav1d.rs +++ b/src/include/dav1d/dav1d.rs @@ -5,10 +5,12 @@ use strum::FromRepr; use crate::c_arc::RawArc; use crate::error::Rav1dError; +use crate::in_range::InRange; use crate::include::dav1d::picture::{Dav1dPicAllocator, Rav1dPicAllocator}; use crate::internal::Rav1dContext; pub use crate::log::Dav1dLogger; use crate::log::Rav1dLogger; +use crate::validate_input; pub type Dav1dContext = RawArc; @@ -142,10 +144,10 @@ pub struct Dav1dSettings { #[repr(C)] pub(crate) struct Rav1dSettings { - pub n_threads: c_int, - pub max_frame_delay: c_int, + pub n_threads: InRange, + pub max_frame_delay: InRange, pub apply_grain: bool, - pub operating_point: u8, + pub operating_point: InRange, pub all_layers: bool, pub frame_size_limit: c_uint, pub allocator: Rav1dPicAllocator, @@ -175,11 +177,20 @@ impl TryFrom for Rav1dSettings { decode_frame_type, reserved: _, } = value; + validate_input!(((0..=256).contains(&n_threads), Rav1dError::InvalidArgument))?; + validate_input!(( + (0..=256).contains(&max_frame_delay), + Rav1dError::InvalidArgument + ))?; + validate_input!(( + (0..32).contains(&operating_point), + Rav1dError::InvalidArgument + ))?; Ok(Self { - n_threads, - max_frame_delay, + n_threads: InRange::new(n_threads.try_into().unwrap()).unwrap(), + max_frame_delay: InRange::new(max_frame_delay.try_into().unwrap()).unwrap(), apply_grain: apply_grain != 0, - operating_point: operating_point.try_into().unwrap(), + operating_point: InRange::new(operating_point.try_into().unwrap()).unwrap(), all_layers: all_layers != 0, frame_size_limit, allocator: allocator.try_into()?, @@ -209,10 +220,10 @@ impl From for Dav1dSettings { decode_frame_type, } = value; Self { - n_threads, - max_frame_delay, + n_threads: n_threads.get().into(), + max_frame_delay: max_frame_delay.get().into(), apply_grain: apply_grain as c_int, - operating_point: operating_point.into(), + operating_point: operating_point.get().into(), all_layers: all_layers as c_int, frame_size_limit, allocator: allocator.into(), diff --git a/src/lib.rs b/src/lib.rs index 99dded75a..f7b4083a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,6 +161,7 @@ use crate::decode::rav1d_decode_frame_exit; pub use crate::error::Dav1dResult; use crate::error::{Rav1dError, Rav1dResult}; use crate::extensions::OptionError as _; +use crate::in_range::InRange; #[cfg(feature = "bitdepth_16")] use crate::include::common::bitdepth::BitDepth16; #[cfg(feature = "bitdepth_8")] @@ -229,10 +230,10 @@ pub extern "C" fn dav1d_version_api() -> c_uint { impl Default for Rav1dSettings { fn default() -> Self { Self { - n_threads: 0, - max_frame_delay: 0, + n_threads: InRange::::new(0).unwrap(), + max_frame_delay: InRange::::new(0).unwrap(), apply_grain: true, - operating_point: 0, + operating_point: InRange::::new(0).unwrap(), all_layers: true, frame_size_limit: 0, allocator: Default::default(), @@ -264,13 +265,13 @@ struct NumThreads { #[cold] fn get_num_threads(s: &Rav1dSettings) -> NumThreads { - let n_tc = if s.n_threads != 0 { - s.n_threads as usize + let n_tc = if s.n_threads.get() != 0 { + s.n_threads.get() as usize // TODO propagate `InRange` } else { rav1d_num_logical_processors().get().clamp(1, 256) }; - let n_fc = if s.max_frame_delay != 0 { - cmp::min(s.max_frame_delay as usize, n_tc) + let n_fc = if s.max_frame_delay.get() != 0 { + cmp::min(s.max_frame_delay.get() as usize, n_tc) // TODO propagate `InRange` } else { cmp::min((n_tc as f64).sqrt().ceil() as usize, 8) }; @@ -279,14 +280,6 @@ fn get_num_threads(s: &Rav1dSettings) -> NumThreads { #[cold] pub(crate) fn rav1d_get_frame_delay(s: &Rav1dSettings) -> Rav1dResult { - validate_input!(( - s.n_threads >= 0 && s.n_threads <= 256, - Rav1dError::InvalidArgument - ))?; - validate_input!(( - s.max_frame_delay >= 0 && s.max_frame_delay <= 256, - Rav1dError::InvalidArgument - ))?; let NumThreads { n_tc: _, n_fc } = get_num_threads(s); Ok(n_fc) } @@ -312,15 +305,6 @@ pub(crate) fn rav1d_open(s: &Rav1dSettings) -> Rav1dResult> { static INITTED: Once = Once::new(); INITTED.call_once(|| init_internal()); - validate_input!(( - s.n_threads >= 0 && s.n_threads <= 256, - Rav1dError::InvalidArgument - ))?; - validate_input!(( - s.max_frame_delay >= 0 && s.max_frame_delay <= 256, - Rav1dError::InvalidArgument - ))?; - validate_input!((s.operating_point <= 31, Rav1dError::InvalidArgument))?; validate_input!(( !s.allocator.is_default() || s.allocator.cookie.is_none(), Rav1dError::InvalidArgument @@ -405,7 +389,7 @@ pub(crate) fn rav1d_open(s: &Rav1dSettings) -> Rav1dResult> { allocator: s.allocator.clone(), logger: s.logger.clone(), apply_grain: s.apply_grain, - operating_point: s.operating_point, + operating_point: s.operating_point.get(), // TODO propagate `InRange` all_layers: s.all_layers, frame_size_limit, strict_std_compliance: s.strict_std_compliance,