1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
use crate::PlaneSize;
/// Constant Rate Factor lookup table
#[rustfmt::skip]
pub static CRF: [[f32; 4]; 10] = [
// baseline C max C C increase velocity feature radius
// (+1 C every X*dt_ref time) (X * min resolution, in pixels)
/*0*/ [0.0, 0.0, 10.0, 1E-9],
/*1*/ [0.0, 1.0, 9.0, 1.0/12.0],
/*2*/ [1.0, 3.0, 8.0, 1.0/14.0],
/*3*/ [2.0, 7.0, 7.0, 1.0/15.0],
/*4*/ [5.0, 9.0, 6.0, 1.0/18.0],
/*5*/ [6.0, 10.0, 5.0, 1.0/20.0],
/*6*/ [7.0, 13.0, 4.0, 1.0/25.0],
/*7*/ [8.0, 16.0, 3.0, 1.0/30.0],
/*8*/ [10.0, 20.0, 2.0, 1.0/30.0],
/*9*/ [15.0, 25.0, 1.0, 1.0/30.0],
];
/// The default CRF quality level
pub const DEFAULT_CRF_QUALITY: u8 = 3;
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Crf {
/// Constant Rate Factor (CRF) quality setting for the encoder. 0 is lossless, 9 is worst quality.
/// Determines:
/// * The baseline (starting) c-threshold for all pixels
/// * The maximum c-threshold for all pixels
/// * The Dt_max multiplier
/// * The c-threshold increase velocity (how often to increase C if the intensity is stable)
/// * The radius for which to reset the c-threshold for neighboring pixels (if feature detection is enabled)
crf_quality: Option<u8>,
parameters: CrfParameters,
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct CrfParameters {
/// The baseline (starting) contrast threshold for all pixels
pub c_thresh_baseline: u8,
/// The maximum contrast threshold for all pixels
pub c_thresh_max: u8,
/// The velocity at which to increase the contrast threshold for all pixels (increment c by 1
/// for every X input intervals, if it's stable)
pub c_increase_velocity: u8,
/// The radius for which to reset the c-threshold for neighboring pixels (if feature detection is enabled)
pub feature_c_radius: u16,
}
impl Crf {
pub fn new(crf: Option<u8>, plane: PlaneSize) -> Self {
let default_crf = crf.unwrap_or(DEFAULT_CRF_QUALITY);
Crf {
crf_quality: crf,
parameters: CrfParameters {
c_thresh_baseline: CRF[default_crf as usize][0] as u8,
c_thresh_max: CRF[default_crf as usize][1] as u8,
c_increase_velocity: CRF[default_crf as usize][2] as u8,
feature_c_radius: (CRF[default_crf as usize][3] * plane.min_resolution() as f32)
as u16,
},
}
}
pub fn override_c_thresh_baseline(&mut self, baseline: u8) {
self.parameters.c_thresh_baseline = baseline;
self.crf_quality = None;
}
pub fn override_c_thresh_max(&mut self, max: u8) {
self.parameters.c_thresh_max = max;
self.crf_quality = None;
}
pub fn override_c_increase_velocity(&mut self, velocity: u8) {
self.parameters.c_increase_velocity = velocity;
self.crf_quality = None;
}
pub fn override_feature_c_radius(&mut self, radius: u16) {
self.parameters.feature_c_radius = radius;
self.crf_quality = None;
}
pub fn get_parameters(&self) -> &CrfParameters {
&self.parameters
}
pub fn get_parameters_mut(&mut self) -> &mut CrfParameters {
&mut self.parameters
}
pub fn get_quality(&self) -> Option<u8> {
self.crf_quality
}
}