4 pub struct RateControl {
16 pub fn new() -> Self {
22 pub fn init(&mut self, tb_num: u32, tb_den: u32, bitrate: u32, quality: u8) {
25 self.bitrate = bitrate;
26 self.quality = quality;
28 self.bitpool = self.bitrate;
32 pub fn metric(&self, diff: u32, bits: usize) -> u32 {
33 diff.saturating_add((self.get_weight() * (bits as f32)) as u32)
35 fn get_weight(&self) -> f32 {
36 if (0..=100).contains(&self.quality) {
37 self.lambda * ((100 - self.quality) as f32)
42 pub fn expected_size(&self) -> u32 {
43 if self.bitrate != 0 {
45 let ticks = self.tb_den - self.fpos;
46 u64::from(self.bitpool) * u64::from(self.tb_num) / u64::from(ticks)
48 u64::from(self.bitrate) * 4 * u64::from(self.tb_num) / u64::from(self.tb_den)
54 pub fn update_size(&mut self, real_size: usize) {
55 if self.bitrate != 0 {
56 let bits = (real_size * 8) as u32;
57 let tgt_size = self.expected_size();
59 self.fpos += self.tb_num;
60 while self.fpos >= self.tb_den {
61 self.fpos -= self.tb_den;
62 self.bitpool += self.bitrate;
64 self.bitpool = self.bitpool.saturating_sub(bits);
66 if bits > tgt_size + tgt_size / 8 {
69 if bits < tgt_size - tgt_size / 8 {
71 if self.lambda < 0.0 {
78 pub fn pattern_run_threshold(&self) -> u8 {
87 pub fn get_quant_ranges(&self) -> [u8; 4] {
89 98..=100 => [ 0, 0, 0, 2 ],
90 92..=97 => [ 2, 16, 4, 16 ],
91 85..=91 => [ 5, 16, 7, 16 ],
92 75..=84 => [ 8, 16, 10, 16 ],
93 55..=74 => [ 11, 16, 12, 16 ],
94 1..=54 => [ 12, 16, 13, 16 ],
95 _ => [ 0, 16, 0, 16 ],
98 pub fn modify_forbidden_btypes(&self, forbidden: &mut [bool; 12]) {
99 if self.quality > 98 {
100 forbidden[usize::from(BlockMode::Intra)] = true;
102 if self.quality > 0 {
103 if self.quality < 80 {
104 forbidden[usize::from(BlockMode::Run)] = true;
105 forbidden[usize::from(BlockMode::Residue)] = true;
107 if self.quality < 90 {
108 forbidden[usize::from(BlockMode::Raw)] = true;