1use crate::api::color::ChromaSampling;
11use crate::api::ContextInner;
12use crate::encoder::TEMPORAL_DELIMITER;
13use crate::quantize::{ac_q, dc_q, select_ac_qi, select_dc_qi};
14use crate::util::{
15  bexp64, bexp_q24, blog64, clamp, q24_to_q57, q57, q57_to_q24, Pixel,
16};
17use std::cmp;
18
19pub const FRAME_NSUBTYPES: usize = 4;
23
24pub const FRAME_SUBTYPE_I: usize = 0;
25pub const FRAME_SUBTYPE_P: usize = 1;
26#[allow(unused)]
27pub const FRAME_SUBTYPE_B0: usize = 2;
28#[allow(unused)]
29pub const FRAME_SUBTYPE_B1: usize = 3;
30pub const FRAME_SUBTYPE_SEF: usize = 4;
31
32const PASS_SINGLE: i32 = 0;
33const PASS_1: i32 = 1;
34const PASS_2: i32 = 2;
35const PASS_2_PLUS_1: i32 = 3;
36
37const TWOPASS_MAGIC: i32 = 0x50324156;
39const TWOPASS_VERSION: i32 = 1;
41pub(crate) const TWOPASS_HEADER_SZ: usize = 16 + FRAME_NSUBTYPES * (4 + 1 + 8);
44const TWOPASS_PACKET_SZ: usize = 8;
46
47const SEF_BITS: i64 = 24;
48
49pub(crate) const QSCALE: i32 = 3;
51
52const INTER_DELAY_TARGET_MIN: i32 = 10;
57
58const MQP_Q12: &[i32; FRAME_NSUBTYPES] = &[
66  (1.0 * (1 << 12) as f64) as i32,
69  (1.0 * (1 << 12) as f64) as i32,
70  (1.0 * (1 << 12) as f64) as i32,
71  (1.0 * (1 << 12) as f64) as i32,
72];
73
74const DQP_Q57: &[i64; FRAME_NSUBTYPES] = &[
77  (-(33_810_170.0 / 86_043_287.0) * (1i64 << 57) as f64) as i64,
78  (0.0 * (1i64 << 57) as f64) as i64,
79  ((33_810_170.0 / 86_043_287.0) * (1i64 << 57) as f64) as i64,
80  (2.0 * (33_810_170.0 / 86_043_287.0) * (1i64 << 57) as f64) as i64,
81];
82
83#[rustfmt::skip]
89const Q_MODEL_ADD: [i64; 4] = [
90  -0x24_4FE7_ECB3_DD90,
92  -0x37_41DA_38AD_0924,
94  -0x70_83BD_A626_311C,
96  0,
98];
99#[rustfmt::skip]
100const Q_MODEL_MUL: [i64; 4] = [
101  0x8A0_50DD,
103  0x887_7666,
105  0x8D4_A712,
107  0,
109];
110
111#[rustfmt::skip]
112const ROUGH_TAN_LOOKUP: &[u16; 18] = &[
113     0,   358,   722,  1098,  1491,  1910,
114  2365,  2868,  3437,  4096,  4881,  5850,
115  7094,  8784, 11254, 15286, 23230, 46817
116];
117
118pub struct IIRBessel2 {
122  c: [i32; 2],
123  g: i32,
124  x: [i32; 2],
125  y: [i32; 2],
126}
127
128fn warp_alpha(alpha: i32) -> i32 {
131  let i = ((alpha * 36) >> 24).min(16);
132  let t0 = ROUGH_TAN_LOOKUP[i as usize];
133  let t1 = ROUGH_TAN_LOOKUP[i as usize + 1];
134  let d = alpha * 36 - (i << 24);
135  ((((t0 as i64) << 32) + (((t1 - t0) << 8) as i64) * (d as i64)) >> 32) as i32
136}
137
138fn iir_bessel2_get_parameters(delay: i32) -> (i32, i32, i32) {
141  let alpha = (1 << 24) / delay;
146  let warp = warp_alpha(alpha).max(1) as i64;
148  let k1 = 3 * warp;
150  let k2 = k1 * warp;
152  let d = ((((1 << 12) + k1) << 12) + k2 + 256) >> 9;
154  let a = (k2 << 23) / d;
156  let ik2 = (1i64 << 48) / k2;
158  let b1 = 2 * a * (ik2 - (1i64 << 24));
160  let b2 = (1i64 << 56) - ((4 * a) << 24) - b1;
162  (
164    ((b1 + (1i64 << 31)) >> 32) as i32,
165    ((b2 + (1i64 << 31)) >> 32) as i32,
166    ((a + 128) >> 8) as i32,
167  )
168}
169
170impl IIRBessel2 {
171  pub fn new(delay: i32, value: i32) -> IIRBessel2 {
172    let (c0, c1, g) = iir_bessel2_get_parameters(delay);
173    IIRBessel2 { c: [c0, c1], g, x: [value, value], y: [value, value] }
174  }
175
176  pub fn reinit(&mut self, delay: i32) {
184    let (c0, c1, g) = iir_bessel2_get_parameters(delay);
185    self.c[0] = c0;
186    self.c[1] = c1;
187    self.g = g;
188  }
189
190  pub fn update(&mut self, x: i32) -> i32 {
191    let c0 = self.c[0] as i64;
192    let c1 = self.c[1] as i64;
193    let g = self.g as i64;
194    let x0 = self.x[0] as i64;
195    let x1 = self.x[1] as i64;
196    let y0 = self.y[0] as i64;
197    let y1 = self.y[1] as i64;
198    let ya =
199      ((((x as i64) + x0 * 2 + x1) * g + y0 * c0 + y1 * c1 + (1i64 << 23))
200        >> 24) as i32;
201    self.x[1] = self.x[0];
202    self.x[0] = x;
203    self.y[1] = self.y[0];
204    self.y[0] = ya;
205    ya
206  }
207}
208
209#[derive(Copy, Clone)]
210struct RCFrameMetrics {
211  log_scale_q24: i32,
213  fti: usize,
215  show_frame: bool,
217  }
221
222impl RCFrameMetrics {
223  const fn new() -> RCFrameMetrics {
224    RCFrameMetrics { log_scale_q24: 0, fti: 0, show_frame: false }
225  }
226}
227
228#[derive(Debug, Default, Clone)]
233pub struct RCSummary {
234  pub(crate) ntus: i32,
235  nframes: [i32; FRAME_NSUBTYPES + 1],
236  exp: [u8; FRAME_NSUBTYPES],
237  scale_sum: [i64; FRAME_NSUBTYPES],
238  pub(crate) total: i32,
239}
240
241pub(crate) struct RCDeserialize {
246  pass2_buffer_pos: usize,
248  pass2_buffer_fill: usize,
251  pass2_buffer: [u8; TWOPASS_HEADER_SZ],
253}
254
255impl Default for RCDeserialize {
256  fn default() -> Self {
257    RCDeserialize {
258      pass2_buffer: [0; TWOPASS_HEADER_SZ],
259      pass2_buffer_pos: 0,
260      pass2_buffer_fill: 0,
261    }
262  }
263}
264
265impl RCDeserialize {
266  pub(crate) fn buffer_fill(
271    &mut self, buf: &[u8], consumed: usize, goal: usize,
272  ) -> usize {
273    let mut consumed = consumed;
274    while self.pass2_buffer_fill < goal && consumed < buf.len() {
275      self.pass2_buffer[self.pass2_buffer_fill] = buf[consumed];
276      self.pass2_buffer_fill += 1;
277      consumed += 1;
278    }
279    consumed
280  }
281
282  fn unbuffer_val(&mut self, n: usize) -> i64 {
285    let mut bytes = n;
286    let mut ret = 0;
287    let mut shift = 0;
288    while bytes > 0 {
289      bytes -= 1;
290      ret |= (self.pass2_buffer[self.pass2_buffer_pos] as i64) << shift;
291      self.pass2_buffer_pos += 1;
292      shift += 8;
293    }
294    ret
295  }
296
297  fn parse_metrics(&mut self) -> Result<RCFrameMetrics, String> {
299    debug_assert!(self.pass2_buffer_fill >= TWOPASS_PACKET_SZ);
300    let ft_val = self.unbuffer_val(4);
301    let show_frame = (ft_val >> 31) != 0;
302    let fti = (ft_val & 0x7FFFFFFF) as usize;
303    if fti > FRAME_NSUBTYPES {
305      return Err("Invalid frame type".to_string());
306    }
307    let log_scale_q24 = self.unbuffer_val(4) as i32;
308    Ok(RCFrameMetrics { log_scale_q24, fti, show_frame })
309  }
310
311  pub(crate) fn parse_summary(&mut self) -> Result<RCSummary, String> {
313    if self.unbuffer_val(4) != TWOPASS_MAGIC as i64 {
315      return Err("Magic value mismatch".to_string());
316    }
317    if self.unbuffer_val(4) != TWOPASS_VERSION as i64 {
318      return Err("Version number mismatch".to_string());
319    }
320    let mut s =
321      RCSummary { ntus: self.unbuffer_val(4) as i32, ..Default::default() };
322
323    if s.ntus < 1 {
327      return Err("No TUs found in first pass summary".to_string());
328    }
329    let mut total: i32 = 0;
330    for nframes in s.nframes.iter_mut() {
331      let n = self.unbuffer_val(4) as i32;
332      if n < 0 {
333        return Err("Got negative frame count".to_string());
334      }
335      total = total
336        .checked_add(n)
337        .ok_or_else(|| "Frame count too large".to_string())?;
338
339      *nframes = n;
340    }
341
342    if s.ntus > total {
344      return Err("More TUs than frames".to_string());
345    }
346
347    s.total = total;
348
349    for exp in s.exp.iter_mut() {
350      *exp = self.unbuffer_val(1) as u8;
351    }
352
353    for scale_sum in s.scale_sum.iter_mut() {
354      *scale_sum = self.unbuffer_val(8);
355      if *scale_sum < 0 {
356        return Err("Got negative scale sum".to_string());
357      }
358    }
359    Ok(s)
360  }
361}
362
363pub struct RCState {
364  target_bitrate: i32,
366  reservoir_frame_delay: i32,
370  reservoir_frame_delay_is_set: bool,
373  maybe_ac_qi_max: Option<u8>,
376  ac_qi_min: u8,
378  drop_frames: bool,
380  cap_overflow: bool,
382  cap_underflow: bool,
384  pass1_log_base_q: i64,
386  twopass_state: i32,
393  log_npixels: i64,
395  bits_per_tu: i64,
397  reservoir_fullness: i64,
399  reservoir_target: i64,
403  reservoir_max: i64,
405  log_scale: [i64; FRAME_NSUBTYPES],
410  exp: [u8; FRAME_NSUBTYPES],
412  scalefilter: [IIRBessel2; FRAME_NSUBTYPES],
417  nframes: [i32; FRAME_NSUBTYPES + 1],
424  inter_delay: [i32; FRAME_NSUBTYPES - 1],
425  inter_delay_target: i32,
426  rate_bias: i64,
428  nencoded_frames: i64,
430  nsef_frames: i64,
432  pass1_buffer: [u8; TWOPASS_HEADER_SZ],
434  pub pass1_data_retrieved: bool,
439  pass1_summary_retrieved: bool,
442  pass2_data_ready: bool,
448  prev_metrics: RCFrameMetrics,
453  cur_metrics: RCFrameMetrics,
455  frame_metrics: Vec<RCFrameMetrics>,
457  nframe_metrics: usize,
459  frame_metrics_head: usize,
461  des: RCDeserialize,
463  ntus: i32,
465  ntus_total: i32,
467  ntus_left: i32,
469  nframes_total: [i32; FRAME_NSUBTYPES + 1],
471  nframes_total_total: i32,
473  nframes_left: [i32; FRAME_NSUBTYPES + 1],
475  scale_sum: [i64; FRAME_NSUBTYPES],
477  scale_window_ntus: i32,
479  scale_window_nframes: [i32; FRAME_NSUBTYPES + 1],
481  scale_window_sum: [i64; FRAME_NSUBTYPES],
483}
484
485pub struct QuantizerParameters {
487  pub log_base_q: i64,
492  pub log_target_q: i64,
498  pub dc_qi: [u8; 3],
499  pub ac_qi: [u8; 3],
500  pub lambda: f64,
501  pub dist_scale: [f64; 3],
502}
503
504const Q57_SQUARE_EXP_SCALE: f64 =
505  (2.0 * ::std::f64::consts::LN_2) / ((1i64 << 57) as f64);
506
507fn chroma_offset(
510  log_target_q: i64, chroma_sampling: ChromaSampling,
511) -> (i64, i64) {
512  let x = log_target_q.max(0);
513  let y = match chroma_sampling {
515    ChromaSampling::Cs400 => 0,
516    ChromaSampling::Cs420 => (x >> 2) + (x >> 6), ChromaSampling::Cs422 => (x >> 3) + (x >> 4) - (x >> 7), ChromaSampling::Cs444 => (x >> 4) + (x >> 5) + (x >> 8), };
520  (0x19D_5D9F_D501_0B37 - y, 0xA4_D3C2_5E68_DC58 - y)
522}
523
524impl QuantizerParameters {
525  fn new_from_log_q(
526    log_base_q: i64, log_target_q: i64, bit_depth: usize,
527    chroma_sampling: ChromaSampling, is_intra: bool,
528    log_isqrt_mean_scale: i64,
529  ) -> QuantizerParameters {
530    let scale = log_isqrt_mean_scale + q57(QSCALE + bit_depth as i32 - 8);
531
532    let mut log_q_y = log_target_q;
533    if !is_intra && bit_depth == 8 {
534      log_q_y = log_target_q
535        + (log_target_q >> 32) * Q_MODEL_MUL[chroma_sampling as usize]
536        + Q_MODEL_ADD[chroma_sampling as usize];
537    }
538
539    let quantizer = bexp64(log_q_y + scale);
540    let (offset_u, offset_v) =
541      chroma_offset(log_q_y + log_isqrt_mean_scale, chroma_sampling);
542    let mono = chroma_sampling == ChromaSampling::Cs400;
543    let log_q_u = log_q_y + offset_u;
544    let log_q_v = log_q_y + offset_v;
545    let quantizer_u = bexp64(log_q_u + scale);
546    let quantizer_v = bexp64(log_q_v + scale);
547    let lambda = (::std::f64::consts::LN_2 / 6.0)
548      * (((log_target_q + log_isqrt_mean_scale) as f64)
549        * Q57_SQUARE_EXP_SCALE)
550        .exp();
551
552    let scale = |q| bexp64((log_target_q - q) * 2 + q57(16)) as f64 / 65536.;
553    let dist_scale = [scale(log_q_y), scale(log_q_u), scale(log_q_v)];
554
555    let base_q_idx = select_ac_qi(quantizer, bit_depth).max(1);
556
557    let min_qi = base_q_idx.saturating_sub(63).max(1);
559    let max_qi = base_q_idx.saturating_add(63).min(255);
560    let clamp_qi = |qi: u8| qi.clamp(min_qi, max_qi);
561
562    QuantizerParameters {
563      log_base_q,
564      log_target_q,
565      dc_qi: [
567        clamp_qi(select_dc_qi(quantizer, bit_depth)),
568        if mono { 0 } else { clamp_qi(select_dc_qi(quantizer_u, bit_depth)) },
569        if mono { 0 } else { clamp_qi(select_dc_qi(quantizer_v, bit_depth)) },
570      ],
571      ac_qi: [
572        base_q_idx,
573        if mono { 0 } else { clamp_qi(select_ac_qi(quantizer_u, bit_depth)) },
574        if mono { 0 } else { clamp_qi(select_ac_qi(quantizer_v, bit_depth)) },
575      ],
576      lambda,
577      dist_scale,
578    }
579  }
580}
581
582impl RCState {
583  pub fn new(
584    frame_width: i32, frame_height: i32, framerate_num: i64,
585    framerate_den: i64, target_bitrate: i32, maybe_ac_qi_max: Option<u8>,
586    ac_qi_min: u8, max_key_frame_interval: i32,
587    maybe_reservoir_frame_delay: Option<i32>,
588  ) -> RCState {
589    let reservoir_frame_delay = maybe_reservoir_frame_delay
598      .unwrap_or_else(|| ((max_key_frame_interval * 3) >> 1).min(240))
599      .max(12);
600    let npixels = (frame_width as i64) * (frame_height as i64);
602    let bits_per_tu = clamp(
609      (target_bitrate as i64) * framerate_den / framerate_num,
610      40,
611      0x4000_0000_0000,
612    ) - (TEMPORAL_DELIMITER.len() * 8) as i64;
613    let reservoir_max = bits_per_tu * (reservoir_frame_delay as i64);
614    let reservoir_target = (reservoir_max + 1) >> 1;
616    let ibpp = npixels / bits_per_tu;
618    let (i_exp, i_log_scale) = if ibpp < 1 {
621      (48u8, blog64(36) - q57(QSCALE))
622    } else if ibpp < 4 {
623      (61u8, blog64(55) - q57(QSCALE))
624    } else {
625      (77u8, blog64(129) - q57(QSCALE))
626    };
627    let (p_exp, p_log_scale) = if ibpp < 2 {
628      (69u8, blog64(32) - q57(QSCALE))
629    } else if ibpp < 139 {
630      (104u8, blog64(84) - q57(QSCALE))
631    } else {
632      (83u8, blog64(19) - q57(QSCALE))
633    };
634    let (b0_exp, b0_log_scale) = if ibpp < 2 {
635      (84u8, blog64(30) - q57(QSCALE))
636    } else if ibpp < 92 {
637      (120u8, blog64(68) - q57(QSCALE))
638    } else {
639      (68u8, blog64(4) - q57(QSCALE))
640    };
641    let (b1_exp, b1_log_scale) = if ibpp < 2 {
642      (87u8, blog64(27) - q57(QSCALE))
643    } else if ibpp < 126 {
644      (139u8, blog64(84) - q57(QSCALE))
645    } else {
646      (61u8, blog64(1) - q57(QSCALE))
647    };
648
649    RCState {
651      target_bitrate,
652      reservoir_frame_delay,
653      reservoir_frame_delay_is_set: maybe_reservoir_frame_delay.is_some(),
654      maybe_ac_qi_max,
655      ac_qi_min,
656      drop_frames: false,
657      cap_overflow: true,
658      cap_underflow: false,
659      pass1_log_base_q: 0,
660      twopass_state: PASS_SINGLE,
661      log_npixels: blog64(npixels),
662      bits_per_tu,
663      reservoir_fullness: reservoir_target,
664      reservoir_target,
665      reservoir_max,
666      log_scale: [i_log_scale, p_log_scale, b0_log_scale, b1_log_scale],
667      exp: [i_exp, p_exp, b0_exp, b1_exp],
668      scalefilter: [
669        IIRBessel2::new(4, q57_to_q24(i_log_scale)),
670        IIRBessel2::new(INTER_DELAY_TARGET_MIN, q57_to_q24(p_log_scale)),
671        IIRBessel2::new(INTER_DELAY_TARGET_MIN, q57_to_q24(b0_log_scale)),
672        IIRBessel2::new(INTER_DELAY_TARGET_MIN, q57_to_q24(b1_log_scale)),
673      ],
674      nframes: [0; FRAME_NSUBTYPES + 1],
676      inter_delay: [INTER_DELAY_TARGET_MIN; FRAME_NSUBTYPES - 1],
677      inter_delay_target: reservoir_frame_delay >> 1,
678      rate_bias: 0,
679      nencoded_frames: 0,
680      nsef_frames: 0,
681      pass1_buffer: [0; TWOPASS_HEADER_SZ],
682      pass1_data_retrieved: true,
683      pass1_summary_retrieved: false,
684      pass2_data_ready: false,
685      prev_metrics: RCFrameMetrics::new(),
686      cur_metrics: RCFrameMetrics::new(),
687      frame_metrics: Vec::new(),
688      nframe_metrics: 0,
689      frame_metrics_head: 0,
690      ntus: 0,
691      ntus_total: 0,
692      ntus_left: 0,
693      nframes_total: [0; FRAME_NSUBTYPES + 1],
694      nframes_total_total: 0,
695      nframes_left: [0; FRAME_NSUBTYPES + 1],
696      scale_sum: [0; FRAME_NSUBTYPES],
697      scale_window_ntus: 0,
698      scale_window_nframes: [0; FRAME_NSUBTYPES + 1],
699      scale_window_sum: [0; FRAME_NSUBTYPES],
700      des: RCDeserialize::default(),
701    }
702  }
703
704  pub(crate) fn select_first_pass_qi(
705    &self, bit_depth: usize, fti: usize, chroma_sampling: ChromaSampling,
706  ) -> QuantizerParameters {
707    let log_q = ((self.pass1_log_base_q + (1i64 << 11)) >> 12)
709      * (MQP_Q12[fti] as i64)
710      + DQP_Q57[fti];
711    QuantizerParameters::new_from_log_q(
712      self.pass1_log_base_q,
713      log_q,
714      bit_depth,
715      chroma_sampling,
716      fti == 0,
717      0,
718    )
719  }
720
721  #[profiling::function]
723  pub(crate) fn select_qi<T: Pixel>(
724    &self, ctx: &ContextInner<T>, output_frameno: u64, fti: usize,
725    maybe_prev_log_base_q: Option<i64>, log_isqrt_mean_scale: i64,
726  ) -> QuantizerParameters {
727    if self.target_bitrate <= 0 {
729      let bit_depth = ctx.config.bit_depth;
732      let chroma_sampling = ctx.config.chroma_sampling;
733      let (log_base_q, log_q) =
734        Self::calc_flat_quantizer(ctx.config.quantizer as u8, bit_depth, fti);
735      QuantizerParameters::new_from_log_q(
736        log_base_q,
737        log_q,
738        bit_depth,
739        chroma_sampling,
740        fti == 0,
741        log_isqrt_mean_scale,
742      )
743    } else {
744      let mut nframes: [i32; FRAME_NSUBTYPES + 1] = [0; FRAME_NSUBTYPES + 1];
745      let mut log_scale: [i64; FRAME_NSUBTYPES] = self.log_scale;
746      let mut reservoir_tus = self.reservoir_frame_delay.min(self.ntus_left);
747      let mut reservoir_frames = 0;
748      let mut log_cur_scale = (self.scalefilter[fti].y[0] as i64) << 33;
749      match self.twopass_state {
750        PASS_1 => {
752          return self.select_first_pass_qi(
753            ctx.config.bit_depth,
754            fti,
755            ctx.config.chroma_sampling,
756          );
757        }
758        PASS_2 | PASS_2_PLUS_1 => {
762          let mut scale_window_sum: [i64; FRAME_NSUBTYPES] =
763            self.scale_window_sum;
764          let mut scale_window_nframes: [i32; FRAME_NSUBTYPES + 1] =
765            self.scale_window_nframes;
766          for ftj in 0..FRAME_NSUBTYPES {
768            reservoir_frames += scale_window_nframes[ftj];
769          }
770          if !self.frame_metrics.is_empty() {
787            let mut fm_tail = self.frame_metrics_head + self.nframe_metrics;
788            if fm_tail >= self.frame_metrics.len() {
789              fm_tail -= self.frame_metrics.len();
790            }
791            let mut fmi = fm_tail;
792            loop {
793              if fmi == 0 {
794                fmi += self.frame_metrics.len();
795              }
796              fmi -= 1;
797              if fmi == self.frame_metrics_head {
799                break;
800              }
801              if self.frame_metrics[fmi].fti == FRAME_SUBTYPE_I {
803                while fmi != fm_tail {
804                  let m = &self.frame_metrics[fmi];
805                  let ftj = m.fti;
806                  scale_window_nframes[ftj] -= 1;
807                  if ftj < FRAME_NSUBTYPES {
808                    scale_window_sum[ftj] -= bexp_q24(m.log_scale_q24);
809                    reservoir_frames -= 1;
810                  }
811                  if m.show_frame {
812                    reservoir_tus -= 1;
813                  }
814                  fmi += 1;
815                  if fmi >= self.frame_metrics.len() {
816                    fmi = 0;
817                  }
818                }
819                break;
821              }
822            }
823          }
824          nframes = scale_window_nframes;
825          if self.cur_metrics.fti != fti {
830            scale_window_nframes[self.cur_metrics.fti] -= 1;
831            if self.cur_metrics.fti != FRAME_SUBTYPE_SEF {
832              scale_window_sum[self.cur_metrics.fti] -=
833                bexp_q24(self.cur_metrics.log_scale_q24);
834            }
835          } else {
836            log_cur_scale = (self.cur_metrics.log_scale_q24 as i64) << 33;
837          }
838          if reservoir_tus >= self.ntus_left
844            && self.ntus_total as u64
845              > ctx.gop_input_frameno_start[&output_frameno]
846          {
847            let nfinal_gop_tus = self.ntus_total
848              - (ctx.gop_input_frameno_start[&output_frameno] as i32);
849            if ctx.config.max_key_frame_interval as i32 > nfinal_gop_tus {
850              let reservoir_pad = (ctx.config.max_key_frame_interval as i32
851                - nfinal_gop_tus)
852                .min(self.reservoir_frame_delay - reservoir_tus);
853              let (guessed_reservoir_frames, guessed_reservoir_tus) = ctx
854                .guess_frame_subtypes(
855                  &mut nframes,
856                  reservoir_tus + reservoir_pad,
857                );
858              reservoir_frames = guessed_reservoir_frames;
859              reservoir_tus = guessed_reservoir_tus;
860            }
861          }
862          for ftj in 0..FRAME_NSUBTYPES {
866            let scale = scale_window_sum[ftj]
867              + bexp_q24(self.scalefilter[ftj].y[0])
868                * (nframes[ftj] - scale_window_nframes[ftj]) as i64;
869            log_scale[ftj] = if nframes[ftj] > 0 {
870              blog64(scale) - blog64(nframes[ftj] as i64) - q57(24)
871            } else {
872              -self.log_npixels
873            };
874          }
875        }
876        _ => {
878          let (guessed_reservoir_frames, guessed_reservoir_tus) =
884            ctx.guess_frame_subtypes(&mut nframes, self.reservoir_frame_delay);
885          reservoir_frames = guessed_reservoir_frames;
886          reservoir_tus = guessed_reservoir_tus;
887          }
889      }
890      let rate_bias = (self.rate_bias / (self.nencoded_frames + 100))
892        * (reservoir_frames as i64);
893      let rate_total = self.reservoir_fullness - self.reservoir_target
896        + rate_bias
897        + (reservoir_tus as i64) * self.bits_per_tu;
898      let bit_depth = ctx.config.bit_depth;
911      let chroma_sampling = ctx.config.chroma_sampling;
912      let mut log_qlo = blog64(ac_q(self.ac_qi_min, 0, bit_depth).get() as i64)
914        - q57(QSCALE + bit_depth as i32 - 8);
915      let mut log_qhi = blog64(
919        ac_q(self.maybe_ac_qi_max.unwrap_or(255), 0, bit_depth).get() as i64,
920      ) - q57(QSCALE + bit_depth as i32 - 8);
921      let mut log_base_q = (log_qlo + log_qhi) >> 1;
922      while log_qlo < log_qhi {
923        let mut bits = 0i64;
925        for ftj in 0..FRAME_NSUBTYPES {
926          let log_q = ((log_base_q + (1i64 << 11)) >> 12)
928            * (MQP_Q12[ftj] as i64)
929            + DQP_Q57[ftj];
930          bits += (nframes[ftj] as i64)
933            * bexp64(
934              log_scale[ftj] + self.log_npixels
935                - ((log_q + 32) >> 6) * (self.exp[ftj] as i64),
936            );
937        }
938        bits += (nframes[FRAME_SUBTYPE_SEF] as i64) * SEF_BITS;
940        let diff = bits - rate_total;
941        if diff > 0 {
942          log_qlo = log_base_q + 1;
943        } else if diff < 0 {
944          log_qhi = log_base_q - 1;
945        } else {
946          break;
947        }
948        log_base_q = (log_qlo + log_qhi) >> 1;
949      }
950      if let Some(prev_log_base_q) = maybe_prev_log_base_q {
954        log_base_q = clamp(
955          log_base_q,
956          prev_log_base_q - 0xA4_D3C2_5E68_DC58,
957          prev_log_base_q + 0xA4_D3C2_5E68_DC58,
958        );
959      }
960      let mut log_q = ((log_base_q + (1i64 << 11)) >> 12)
962        * (MQP_Q12[fti] as i64)
963        + DQP_Q57[fti];
964      if self.cap_overflow {
970        let margin = (self.reservoir_max + 31) >> 5;
974        let soft_limit = self.reservoir_fullness + self.bits_per_tu
976          - (self.reservoir_max - margin);
977        if soft_limit > 0 {
978          let log_soft_limit = blog64(soft_limit);
979          let log_scale_pixels = log_cur_scale + self.log_npixels;
985          let exp = self.exp[fti] as i64;
986          let mut log_q_exp = ((log_q + 32) >> 6) * exp;
987          if log_scale_pixels - log_q_exp < log_soft_limit {
988            log_q_exp += ((log_scale_pixels - log_soft_limit - log_q_exp)
990              >> 32)
991              * ((margin.min(soft_limit) << 32) / margin);
992            log_q = ((log_q_exp + (exp >> 1)) / exp) << 6;
993          }
994        }
995      }
996      if self.maybe_ac_qi_max.is_none() {
1000        let log_hard_limit =
1005          blog64(self.reservoir_fullness + (self.bits_per_tu >> 1));
1006        let log_scale_pixels = log_cur_scale + self.log_npixels;
1012        let exp = self.exp[fti] as i64;
1013        let mut log_q_exp = ((log_q + 32) >> 6) * exp;
1014        if log_scale_pixels - log_q_exp > log_hard_limit {
1015          log_q_exp = log_scale_pixels - log_hard_limit;
1017          log_q = ((log_q_exp + (exp >> 1)) / exp) << 6;
1018          }
1020      }
1021
1022      if let Some(qi_max) = self.maybe_ac_qi_max {
1023        let (max_log_base_q, max_log_q) =
1024          Self::calc_flat_quantizer(qi_max, ctx.config.bit_depth, fti);
1025        log_base_q = cmp::min(log_base_q, max_log_base_q);
1026        log_q = cmp::min(log_q, max_log_q);
1027      }
1028      if self.ac_qi_min > 0 {
1029        let (min_log_base_q, min_log_q) =
1030          Self::calc_flat_quantizer(self.ac_qi_min, ctx.config.bit_depth, fti);
1031        log_base_q = cmp::max(log_base_q, min_log_base_q);
1032        log_q = cmp::max(log_q, min_log_q);
1033      }
1034      QuantizerParameters::new_from_log_q(
1035        log_base_q,
1036        log_q,
1037        bit_depth,
1038        chroma_sampling,
1039        fti == 0,
1040        log_isqrt_mean_scale,
1041      )
1042    }
1043  }
1044
1045  fn calc_flat_quantizer(
1048    base_qi: u8, bit_depth: usize, fti: usize,
1049  ) -> (i64, i64) {
1050    let ac_quantizer = ac_q(base_qi, 0, bit_depth).get() as i64;
1057    let dc_qi = select_dc_qi(ac_quantizer, bit_depth);
1059    let dc_quantizer = dc_q(dc_qi, 0, bit_depth).get() as i64;
1060    let log_ac_q = blog64(ac_quantizer) - q57(QSCALE + bit_depth as i32 - 8);
1062    let log_dc_q = blog64(dc_quantizer) - q57(QSCALE + bit_depth as i32 - 8);
1063    let log_base_q = (log_ac_q + log_dc_q + 1) >> 1;
1065    let log_q = ((log_base_q + (1i64 << 11)) >> 12) * (MQP_Q12[fti] as i64)
1067      + DQP_Q57[fti];
1068    (log_base_q, log_q)
1069  }
1070
1071  #[profiling::function]
1072  pub fn update_state(
1073    &mut self, bits: i64, fti: usize, show_frame: bool, log_target_q: i64,
1074    trial: bool, droppable: bool,
1075  ) -> bool {
1076    if trial {
1077      assert!(self.needs_trial_encode(fti));
1078      assert!(bits > 0);
1079    }
1080    let mut dropped = false;
1081    if self.target_bitrate > 0 {
1083      let mut estimated_bits = 0;
1084      let mut bits = bits;
1085      let mut droppable = droppable;
1086      let mut log_scale = q57(-64);
1087      if !self.drop_frames
1090        || fti == FRAME_SUBTYPE_SEF
1091        || (self.twopass_state == PASS_2
1092          || self.twopass_state == PASS_2_PLUS_1)
1093          && !self.frame_metrics.is_empty()
1094      {
1095        droppable = false;
1096      }
1097      if fti == FRAME_SUBTYPE_SEF {
1098        debug_assert!(bits == SEF_BITS);
1099        debug_assert!(show_frame);
1100        debug_assert!(!trial);
1102        estimated_bits = SEF_BITS;
1103        self.nsef_frames += 1;
1104      } else {
1105        let log_q_exp = ((log_target_q + 32) >> 6) * (self.exp[fti] as i64);
1106        let prev_log_scale = self.log_scale[fti];
1107        if bits <= 0 {
1108          bits = 0;
1110          dropped = true;
1111        } else {
1113          let log_bits = blog64(bits);
1115          log_scale = (log_bits - self.log_npixels + log_q_exp).min(q57(16));
1116          estimated_bits =
1117            bexp64(prev_log_scale + self.log_npixels - log_q_exp);
1118          if !trial {
1119            self.nencoded_frames += 1;
1120          }
1121        }
1122      }
1123      let log_scale_q24 = q57_to_q24(log_scale);
1124      if self.twopass_state == PASS_2 || self.twopass_state == PASS_2_PLUS_1 {
1126        if !trial {
1128          self.prev_metrics = self.cur_metrics;
1130          let ftj = self.prev_metrics.fti;
1132          self.nframes_left[ftj] -= 1;
1133          self.scale_window_nframes[ftj] -= 1;
1134          if ftj < FRAME_NSUBTYPES {
1135            self.scale_window_sum[ftj] -=
1136              bexp_q24(self.prev_metrics.log_scale_q24);
1137          }
1138          if self.prev_metrics.show_frame {
1139            self.ntus_left -= 1;
1140            self.scale_window_ntus -= 1;
1141          }
1142          if !self.frame_metrics.is_empty() {
1144            self.nframe_metrics -= 1;
1145            self.frame_metrics_head += 1;
1146            if self.frame_metrics_head >= self.frame_metrics.len() {
1147              self.frame_metrics_head = 0;
1148            }
1149          }
1150          self.pass2_data_ready = false;
1152          self.twopass_in(None).unwrap_or(0);
1156        }
1157      }
1158      if self.twopass_state == PASS_1 || self.twopass_state == PASS_2_PLUS_1 {
1159        self.prev_metrics.log_scale_q24 = log_scale_q24;
1161        self.prev_metrics.fti = fti;
1162        self.prev_metrics.show_frame = show_frame;
1163        self.pass1_data_retrieved = false;
1164      }
1165      if fti != FRAME_SUBTYPE_SEF && bits > 0 {
1167        if trial || self.nframes[fti] <= 0 {
1171          let f = &mut self.scalefilter[fti];
1172          let x = log_scale_q24;
1173          f.x[0] = x;
1174          f.x[1] = x;
1175          f.y[0] = x;
1176          f.y[1] = x;
1177          self.log_scale[fti] = log_scale;
1178        } else {
1180          if fti > 0
1183            && self.inter_delay[fti - 1] < self.inter_delay_target
1184            && self.nframes[fti] >= self.inter_delay[fti - 1]
1185          {
1186            self.inter_delay[fti - 1] += 1;
1187            self.scalefilter[fti].reinit(self.inter_delay[fti - 1]);
1188          }
1189          self.log_scale[fti] =
1192            q24_to_q57(self.scalefilter[fti].update(log_scale_q24));
1193        }
1194        if droppable && self.reservoir_fullness + self.bits_per_tu < bits {
1196          bits = 0;
1198          dropped = true;
1199        } else {
1200          }
1205      }
1206      if !trial {
1207        if !trial && self.nframes[fti] < ::std::i32::MAX {
1209          self.nframes[fti] += 1;
1210        }
1211        self.reservoir_fullness -= bits;
1212        if show_frame {
1213          self.reservoir_fullness += self.bits_per_tu;
1214          }
1216        if self.cap_overflow {
1219          self.reservoir_fullness =
1220            self.reservoir_fullness.min(self.reservoir_max);
1221        }
1222        if self.cap_underflow {
1225          self.reservoir_fullness = self.reservoir_fullness.max(0);
1226        }
1227        self.rate_bias += estimated_bits - bits;
1229      }
1230    }
1231    dropped
1232  }
1233
1234  pub const fn needs_trial_encode(&self, fti: usize) -> bool {
1235    self.target_bitrate > 0 && self.nframes[fti] == 0
1236  }
1237
1238  pub(crate) const fn ready(&self) -> bool {
1239    match self.twopass_state {
1240      PASS_SINGLE => true,
1241      PASS_1 => self.pass1_data_retrieved,
1242      PASS_2 => self.pass2_data_ready,
1243      _ => self.pass1_data_retrieved && self.pass2_data_ready,
1244    }
1245  }
1246
1247  fn buffer_val(&mut self, val: i64, bytes: usize, cur_pos: usize) -> usize {
1248    let mut val = val;
1249    let mut bytes = bytes;
1250    let mut cur_pos = cur_pos;
1251    while bytes > 0 {
1252      bytes -= 1;
1253      self.pass1_buffer[cur_pos] = val as u8;
1254      cur_pos += 1;
1255      val >>= 8;
1256    }
1257    cur_pos
1258  }
1259
1260  pub(crate) fn select_pass1_log_base_q<T: Pixel>(
1261    &self, ctx: &ContextInner<T>, output_frameno: u64,
1262  ) -> i64 {
1263    assert_eq!(self.twopass_state, PASS_SINGLE);
1264    self.select_qi(ctx, output_frameno, FRAME_SUBTYPE_I, None, 0).log_base_q
1265  }
1266
1267  pub(crate) fn init_first_pass(
1269    &mut self, maybe_pass1_log_base_q: Option<i64>,
1270  ) {
1271    if let Some(pass1_log_base_q) = maybe_pass1_log_base_q {
1272      assert_eq!(self.twopass_state, PASS_SINGLE);
1273      self.pass1_log_base_q = pass1_log_base_q;
1275    } else {
1276      debug_assert!(self.twopass_state == PASS_2);
1277    }
1278    self.twopass_state += PASS_1;
1279  }
1280
1281  fn emit_placeholder_summary(&mut self) -> &[u8] {
1283    let mut cur_pos = 0;
1285    cur_pos = self.buffer_val(TWOPASS_MAGIC as i64, 4, cur_pos);
1286    cur_pos = self.buffer_val(TWOPASS_VERSION as i64, 4, cur_pos);
1287    cur_pos = self.buffer_val(0, TWOPASS_HEADER_SZ - 8, cur_pos);
1288    debug_assert!(cur_pos == TWOPASS_HEADER_SZ);
1289    self.pass1_data_retrieved = true;
1290    &self.pass1_buffer[..cur_pos]
1291  }
1292
1293  pub(crate) fn emit_frame_data(&mut self) -> Option<&[u8]> {
1295    let mut cur_pos = 0;
1296    let fti = self.prev_metrics.fti;
1297    if fti < FRAME_NSUBTYPES {
1298      self.scale_sum[fti] += bexp_q24(self.prev_metrics.log_scale_q24);
1299    }
1300    if self.prev_metrics.show_frame {
1301      self.ntus += 1;
1302    }
1303    if self.nencoded_frames + self.nsef_frames >= std::i32::MAX as i64 {
1306      None?
1307    }
1308    cur_pos = self.buffer_val(
1309      (self.prev_metrics.show_frame as i64) << 31
1310        | self.prev_metrics.fti as i64,
1311      4,
1312      cur_pos,
1313    );
1314    cur_pos =
1315      self.buffer_val(self.prev_metrics.log_scale_q24 as i64, 4, cur_pos);
1316    debug_assert!(cur_pos == TWOPASS_PACKET_SZ);
1317    self.pass1_data_retrieved = true;
1318    Some(&self.pass1_buffer[..cur_pos])
1319  }
1320
1321  pub(crate) fn emit_summary(&mut self) -> &[u8] {
1323    let mut cur_pos = 0;
1324    cur_pos = self.buffer_val(TWOPASS_MAGIC as i64, 4, cur_pos);
1325    cur_pos = self.buffer_val(TWOPASS_VERSION as i64, 4, cur_pos);
1326    cur_pos = self.buffer_val(self.ntus as i64, 4, cur_pos);
1327    for fti in 0..=FRAME_NSUBTYPES {
1328      cur_pos = self.buffer_val(self.nframes[fti] as i64, 4, cur_pos);
1329    }
1330    for fti in 0..FRAME_NSUBTYPES {
1331      cur_pos = self.buffer_val(self.exp[fti] as i64, 1, cur_pos);
1332    }
1333    for fti in 0..FRAME_NSUBTYPES {
1334      cur_pos = self.buffer_val(self.scale_sum[fti], 8, cur_pos);
1335    }
1336    debug_assert!(cur_pos == TWOPASS_HEADER_SZ);
1337    self.pass1_summary_retrieved = true;
1338    &self.pass1_buffer[..cur_pos]
1339  }
1340
1341  pub(crate) fn twopass_out(
1343    &mut self, done_processing: bool,
1344  ) -> Option<&[u8]> {
1345    if !self.pass1_data_retrieved {
1346      if self.twopass_state != PASS_1 && self.twopass_state != PASS_2_PLUS_1 {
1347        Some(self.emit_placeholder_summary())
1348      } else {
1349        self.emit_frame_data()
1350      }
1351    } else if done_processing && !self.pass1_summary_retrieved {
1352      Some(self.emit_summary())
1353    } else {
1354      None
1356    }
1357  }
1358
1359  pub(crate) fn init_second_pass(&mut self) {
1361    if self.twopass_state == PASS_SINGLE || self.twopass_state == PASS_1 {
1362      self.twopass_state += PASS_2;
1364      if self.reservoir_frame_delay_is_set {
1367        debug_assert!(self.reservoir_frame_delay > 0);
1368        let nmetrics = (self.reservoir_frame_delay as usize) * 2 + 8;
1379        self.frame_metrics.reserve_exact(nmetrics);
1380        self.frame_metrics.resize(nmetrics, RCFrameMetrics::new());
1381      }
1382    }
1383  }
1384
1385  pub(crate) fn setup_second_pass(&mut self, s: &RCSummary) {
1386    self.ntus_total = s.ntus;
1387    self.ntus_left = s.ntus;
1388    self.nframes_total = s.nframes;
1389    self.nframes_left = s.nframes;
1390    self.nframes_total_total = s.nframes.iter().sum();
1391    if self.frame_metrics.is_empty() {
1392      self.reservoir_frame_delay = s.ntus;
1393      self.scale_window_nframes = self.nframes_total;
1394      self.scale_window_sum = s.scale_sum;
1395      self.reservoir_max =
1396        self.bits_per_tu * (self.reservoir_frame_delay as i64);
1397      self.reservoir_target = (self.reservoir_max + 1) >> 1;
1398      self.reservoir_fullness = self.reservoir_target;
1399    } else {
1400      self.reservoir_frame_delay = self.reservoir_frame_delay.min(s.ntus);
1401    }
1402    self.exp = s.exp;
1403  }
1404
1405  fn twopass_parse_summary(&mut self, buf: &[u8]) -> Result<usize, String> {
1410    let consumed = self.des.buffer_fill(buf, 0, TWOPASS_HEADER_SZ);
1411    if self.des.pass2_buffer_fill >= TWOPASS_HEADER_SZ {
1412      self.des.pass2_buffer_pos = 0;
1413
1414      let s = self.des.parse_summary()?;
1415
1416      self.setup_second_pass(&s);
1417
1418      self.des.pass2_buffer_fill = 0;
1423    }
1424
1425    Ok(consumed)
1426  }
1427
1428  pub(crate) fn twopass_first_packet_size(&self) -> usize {
1433    let frames_needed = if !self.frame_metrics.is_empty() {
1434      self.reservoir_frame_delay as usize
1437    } else {
1438      1
1440    };
1441
1442    TWOPASS_HEADER_SZ + frames_needed * TWOPASS_PACKET_SZ
1443  }
1444
1445  pub(crate) fn twopass_in_frames_needed(&self) -> i32 {
1448    if self.target_bitrate <= 0 {
1449      return 0;
1450    }
1451    if self.frame_metrics.is_empty() {
1452      return i32::from(!self.pass2_data_ready);
1453    }
1454    let mut cur_scale_window_nframes = 0;
1455    let mut cur_nframes_left = 0;
1456    for fti in 0..=FRAME_NSUBTYPES {
1457      cur_scale_window_nframes += self.scale_window_nframes[fti];
1458      cur_nframes_left += self.nframes_left[fti];
1459    }
1460
1461    (self.reservoir_frame_delay - self.scale_window_ntus)
1462      .clamp(0, cur_nframes_left - cur_scale_window_nframes)
1463  }
1464
1465  pub(crate) fn parse_frame_data_packet(
1466    &mut self, buf: &[u8],
1467  ) -> Result<(), String> {
1468    if buf.len() != TWOPASS_PACKET_SZ {
1469      return Err("Incorrect buffer size".to_string());
1470    }
1471
1472    self.des.buffer_fill(buf, 0, TWOPASS_PACKET_SZ);
1473    self.des.pass2_buffer_pos = 0;
1474    let m = self.des.parse_metrics()?;
1475    self.des.pass2_buffer_fill = 0;
1476
1477    if self.frame_metrics.is_empty() {
1478      self.cur_metrics = m;
1480      self.pass2_data_ready = true;
1481    } else {
1482      let frames_needed = self.twopass_in_frames_needed();
1484
1485      if frames_needed > 0 {
1486        if self.nframe_metrics >= self.frame_metrics.len() {
1487          return Err(
1488            "Read too many frames without finding enough TUs".to_string(),
1489          );
1490        }
1491
1492        let mut fmi = self.frame_metrics_head + self.nframe_metrics;
1493        if fmi >= self.frame_metrics.len() {
1494          fmi -= self.frame_metrics.len();
1495        }
1496        self.nframe_metrics += 1;
1497        self.frame_metrics[fmi] = m;
1498        self.scale_window_nframes[m.fti] += 1;
1500        if m.fti < FRAME_NSUBTYPES {
1501          self.scale_window_sum[m.fti] += bexp_q24(m.log_scale_q24);
1502        }
1503        if m.show_frame {
1504          self.scale_window_ntus += 1;
1505        }
1506        if frames_needed == 1 {
1507          self.pass2_data_ready = true;
1508          self.cur_metrics = self.frame_metrics[self.frame_metrics_head];
1509        }
1510      } else {
1511        return Err("No frames needed".to_string());
1512      }
1513    }
1514
1515    Ok(())
1516  }
1517
1518  fn twopass_parse_frame_data(
1526    &mut self, maybe_buf: Option<&[u8]>, mut consumed: usize,
1527  ) -> Result<usize, String> {
1528    {
1529      if self.frame_metrics.is_empty() {
1530        if let Some(buf) = maybe_buf {
1532          consumed = self.des.buffer_fill(buf, consumed, TWOPASS_PACKET_SZ);
1533          if self.des.pass2_buffer_fill >= TWOPASS_PACKET_SZ {
1534            self.des.pass2_buffer_pos = 0;
1535            self.cur_metrics = self.des.parse_metrics()?;
1537            self.des.pass2_buffer_fill = 0;
1539            self.pass2_data_ready = true;
1540          }
1541        } else {
1542          return Ok(TWOPASS_PACKET_SZ - self.des.pass2_buffer_fill);
1543        }
1544      } else {
1545        let mut cur_scale_window_nframes = 0;
1547        let mut cur_nframes_left = 0;
1548
1549        for fti in 0..=FRAME_NSUBTYPES {
1550          cur_scale_window_nframes += self.scale_window_nframes[fti];
1551          cur_nframes_left += self.nframes_left[fti];
1552        }
1553
1554        let mut frames_needed = self.twopass_in_frames_needed();
1555        while frames_needed > 0 {
1556          if let Some(buf) = maybe_buf {
1557            consumed = self.des.buffer_fill(buf, consumed, TWOPASS_PACKET_SZ);
1558            if self.des.pass2_buffer_fill >= TWOPASS_PACKET_SZ {
1559              self.des.pass2_buffer_pos = 0;
1560              let m = self.des.parse_metrics()?;
1562              if self.nframe_metrics >= self.frame_metrics.len() {
1564                return Err(
1565                  "Read too many frames without finding enough TUs"
1566                    .to_string(),
1567                );
1568              }
1569              let mut fmi = self.frame_metrics_head + self.nframe_metrics;
1570              if fmi >= self.frame_metrics.len() {
1571                fmi -= self.frame_metrics.len();
1572              }
1573              self.nframe_metrics += 1;
1574              self.frame_metrics[fmi] = m;
1575              self.scale_window_nframes[m.fti] += 1;
1577              cur_scale_window_nframes += 1;
1578              if m.fti < FRAME_NSUBTYPES {
1579                self.scale_window_sum[m.fti] += bexp_q24(m.log_scale_q24);
1580              }
1581              if m.show_frame {
1582                self.scale_window_ntus += 1;
1583              }
1584              frames_needed = (self.reservoir_frame_delay
1585                - self.scale_window_ntus)
1586                .clamp(0, cur_nframes_left - cur_scale_window_nframes);
1587              self.des.pass2_buffer_fill = 0;
1589            } else {
1590              break;
1592            }
1593          } else {
1594            return Ok(
1595              TWOPASS_PACKET_SZ * (frames_needed as usize)
1596                - self.des.pass2_buffer_fill,
1597            );
1598          }
1599        }
1600        if frames_needed <= 0 {
1603          self.cur_metrics = self.frame_metrics[self.frame_metrics_head];
1604          self.pass2_data_ready = true;
1606        }
1607      }
1608    }
1609
1610    Ok(consumed)
1611  }
1612
1613  pub(crate) fn twopass_in(
1620    &mut self, maybe_buf: Option<&[u8]>,
1621  ) -> Result<usize, String> {
1622    let mut consumed = 0;
1623    self.init_second_pass();
1624    if self.nframes_total[FRAME_SUBTYPE_I] == 0 {
1626      self.pass2_data_ready = false;
1627      if let Some(buf) = maybe_buf {
1628        consumed = self.twopass_parse_summary(buf)?
1629      } else {
1630        return Ok(self.twopass_first_packet_size());
1631      }
1632    }
1633    if self.nframes_total[FRAME_SUBTYPE_I] > 0 {
1634      if self.nencoded_frames + self.nsef_frames
1635        >= self.nframes_total_total as i64
1636      {
1637        self.pass2_data_ready = false;
1640      } else if !self.pass2_data_ready {
1641        return self.twopass_parse_frame_data(maybe_buf, consumed);
1642      }
1643    }
1644    Ok(consumed)
1645  }
1646}