adder_codec_core/codec/
rate_controller.rs

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