3 pub struct RateControl {
15 // todo intra/inter decision, better allocation for intra frames
17 pub fn new() -> Self {
30 pub fn init(&mut self, mb_w: usize, mb_h: usize, bitrate: u32, ts_num: u32, ts_den: u32) {
35 if bitrate == 0 || ts_num == 0 || ts_den == 0 {
39 self.tgt_br = bitrate;
40 self.budget = bitrate as isize;
45 pub fn guess_quant(&mut self, intra: bool, huffman: bool) -> usize {
46 let fsize = self.get_target_frame_size(intra);
47 self.projected = fsize;
50 let est_fsize = estimate_frame_size(intra, huffman, q, self.mb_w, self.mb_h);
51 if fsize < est_fsize - est_fsize / 10 {
52 return q.saturating_sub(1);
54 if fsize < est_fsize + est_fsize / 10 {
63 pub fn update(&mut self, dsize: usize) {
64 const LAMBDA_STEP: f32 = 1.0 / 32.0;
69 if (self.projected > dsize + dsize / 10) && self.lambda > LAMBDA_STEP {
70 self.lambda -= LAMBDA_STEP;
71 } else if self.projected < dsize - dsize / 10 {
72 self.lambda += LAMBDA_STEP;
74 self.budget -= dsize as isize;
75 self.cur_time += self.ts_num;
76 while self.cur_time >= self.ts_den {
77 self.cur_time -= self.ts_den;
78 self.budget += self.tgt_br as isize;
81 fn get_target_frame_size(&self, intra: bool) -> usize {
85 let mut avg_fsize = self.budget / ((self.ts_den - self.cur_time) as isize);
87 // todo better intra/inter selection
93 (self.tgt_br as usize) * (self.ts_num as usize) / (self.ts_den as usize) / 2