1use std::cmp;
11
12use crate::api::color::ChromaSampling;
13use crate::api::ContextInner;
14use crate::encoder::TEMPORAL_DELIMITER;
15use crate::quantize::{ac_q, dc_q, select_ac_qi, select_dc_qi};
16use crate::util::{
17 bexp64, bexp_q24, blog64, clamp, q24_to_q57, q57, q57_to_q24, Pixel,
18};
19
20pub const FRAME_NSUBTYPES: usize = 4;
24
25pub const FRAME_SUBTYPE_I: usize = 0;
26pub const FRAME_SUBTYPE_P: usize = 1;
27#[allow(unused)]
28pub const FRAME_SUBTYPE_B0: usize = 2;
29#[allow(unused)]
30pub const FRAME_SUBTYPE_B1: usize = 3;
31pub const FRAME_SUBTYPE_SEF: usize = 4;
32
33const PASS_SINGLE: i32 = 0;
34const PASS_1: i32 = 1;
35const PASS_2: i32 = 2;
36const PASS_2_PLUS_1: i32 = 3;
37
38const TWOPASS_MAGIC: i32 = 0x50324156;
40const TWOPASS_VERSION: i32 = 1;
42pub(crate) const TWOPASS_HEADER_SZ: usize = 16 + FRAME_NSUBTYPES * (4 + 1 + 8);
45const TWOPASS_PACKET_SZ: usize = 8;
47
48const SEF_BITS: i64 = 24;
49
50pub(crate) const QSCALE: i32 = 3;
52
53const INTER_DELAY_TARGET_MIN: i32 = 10;
58
59const MQP_Q12: &[i32; FRAME_NSUBTYPES] = &[
67 (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 (1.0 * (1 << 12) as f64) as i32,
73];
74
75const DQP_Q57: &[i64; FRAME_NSUBTYPES] = &[
78 (-(33_810_170.0 / 86_043_287.0) * (1i64 << 57) as f64) as i64,
79 (0.0 * (1i64 << 57) as f64) as i64,
80 ((33_810_170.0 / 86_043_287.0) * (1i64 << 57) as f64) as i64,
81 (2.0 * (33_810_170.0 / 86_043_287.0) * (1i64 << 57) as f64) as i64,
82];
83
84#[rustfmt::skip]
90const Q_MODEL_ADD: [i64; 4] = [
91 -0x24_4FE7_ECB3_DD90,
93 -0x37_41DA_38AD_0924,
95 -0x70_83BD_A626_311C,
97 0,
99];
100#[rustfmt::skip]
101const Q_MODEL_MUL: [i64; 4] = [
102 0x8A0_50DD,
104 0x887_7666,
106 0x8D4_A712,
108 0,
110];
111
112#[rustfmt::skip]
113const ROUGH_TAN_LOOKUP: &[u16; 18] = &[
114 0, 358, 722, 1098, 1491, 1910,
115 2365, 2868, 3437, 4096, 4881, 5850,
116 7094, 8784, 11254, 15286, 23230, 46817
117];
118
119pub struct IIRBessel2 {
123 c: [i32; 2],
124 g: i32,
125 x: [i32; 2],
126 y: [i32; 2],
127}
128
129fn warp_alpha(alpha: i32) -> i32 {
132 let i = ((alpha * 36) >> 24).min(16);
133 let t0 = ROUGH_TAN_LOOKUP[i as usize];
134 let t1 = ROUGH_TAN_LOOKUP[i as usize + 1];
135 let d = alpha * 36 - (i << 24);
136 ((((t0 as i64) << 32) + (((t1 - t0) << 8) as i64) * (d as i64)) >> 32) as i32
137}
138
139fn iir_bessel2_get_parameters(delay: i32) -> (i32, i32, i32) {
142 let alpha = (1 << 24) / delay;
147 let warp = warp_alpha(alpha).max(1) as i64;
149 let k1 = 3 * warp;
151 let k2 = k1 * warp;
153 let d = ((((1 << 12) + k1) << 12) + k2 + 256) >> 9;
155 let a = (k2 << 23) / d;
157 let ik2 = (1i64 << 48) / k2;
159 let b1 = 2 * a * (ik2 - (1i64 << 24));
161 let b2 = (1i64 << 56) - ((4 * a) << 24) - b1;
163 (
165 ((b1 + (1i64 << 31)) >> 32) as i32,
166 ((b2 + (1i64 << 31)) >> 32) as i32,
167 ((a + 128) >> 8) as i32,
168 )
169}
170
171impl IIRBessel2 {
172 pub fn new(delay: i32, value: i32) -> IIRBessel2 {
173 let (c0, c1, g) = iir_bessel2_get_parameters(delay);
174 IIRBessel2 { c: [c0, c1], g, x: [value, value], y: [value, value] }
175 }
176
177 pub fn reinit(&mut self, delay: i32) {
185 let (c0, c1, g) = iir_bessel2_get_parameters(delay);
186 self.c[0] = c0;
187 self.c[1] = c1;
188 self.g = g;
189 }
190
191 pub fn update(&mut self, x: i32) -> i32 {
192 let c0 = self.c[0] as i64;
193 let c1 = self.c[1] as i64;
194 let g = self.g as i64;
195 let x0 = self.x[0] as i64;
196 let x1 = self.x[1] as i64;
197 let y0 = self.y[0] as i64;
198 let y1 = self.y[1] as i64;
199 let ya =
200 ((((x as i64) + x0 * 2 + x1) * g + y0 * c0 + y1 * c1 + (1i64 << 23))
201 >> 24) as i32;
202 self.x[1] = self.x[0];
203 self.x[0] = x;
204 self.y[1] = self.y[0];
205 self.y[0] = ya;
206 ya
207 }
208}
209
210#[derive(Copy, Clone)]
211struct RCFrameMetrics {
212 log_scale_q24: i32,
214 fti: usize,
216 show_frame: bool,
218 }
222
223impl RCFrameMetrics {
224 const fn new() -> RCFrameMetrics {
225 RCFrameMetrics { log_scale_q24: 0, fti: 0, show_frame: false }
226 }
227}
228
229#[derive(Debug, Default, Clone)]
234pub struct RCSummary {
235 pub(crate) ntus: i32,
236 nframes: [i32; FRAME_NSUBTYPES + 1],
237 exp: [u8; FRAME_NSUBTYPES],
238 scale_sum: [i64; FRAME_NSUBTYPES],
239 pub(crate) total: i32,
240}
241
242pub(crate) struct RCDeserialize {
247 pass2_buffer_pos: usize,
249 pass2_buffer_fill: usize,
252 pass2_buffer: [u8; TWOPASS_HEADER_SZ],
254}
255
256impl Default for RCDeserialize {
257 fn default() -> Self {
258 RCDeserialize {
259 pass2_buffer: [0; TWOPASS_HEADER_SZ],
260 pass2_buffer_pos: 0,
261 pass2_buffer_fill: 0,
262 }
263 }
264}
265
266impl RCDeserialize {
267 pub(crate) fn buffer_fill(
272 &mut self, buf: &[u8], consumed: usize, goal: usize,
273 ) -> usize {
274 let mut consumed = consumed;
275 while self.pass2_buffer_fill < goal && consumed < buf.len() {
276 self.pass2_buffer[self.pass2_buffer_fill] = buf[consumed];
277 self.pass2_buffer_fill += 1;
278 consumed += 1;
279 }
280 consumed
281 }
282
283 fn unbuffer_val(&mut self, n: usize) -> i64 {
286 let mut bytes = n;
287 let mut ret = 0;
288 let mut shift = 0;
289 while bytes > 0 {
290 bytes -= 1;
291 ret |= (self.pass2_buffer[self.pass2_buffer_pos] as i64) << shift;
292 self.pass2_buffer_pos += 1;
293 shift += 8;
294 }
295 ret
296 }
297
298 fn parse_metrics(&mut self) -> Result<RCFrameMetrics, String> {
300 debug_assert!(self.pass2_buffer_fill >= TWOPASS_PACKET_SZ);
301 let ft_val = self.unbuffer_val(4);
302 let show_frame = (ft_val >> 31) != 0;
303 let fti = (ft_val & 0x7FFFFFFF) as usize;
304 if fti > FRAME_NSUBTYPES {
306 return Err("Invalid frame type".to_string());
307 }
308 let log_scale_q24 = self.unbuffer_val(4) as i32;
309 Ok(RCFrameMetrics { log_scale_q24, fti, show_frame })
310 }
311
312 pub(crate) fn parse_summary(&mut self) -> Result<RCSummary, String> {
314 if self.unbuffer_val(4) != TWOPASS_MAGIC as i64 {
316 return Err("Magic value mismatch".to_string());
317 }
318 if self.unbuffer_val(4) != TWOPASS_VERSION as i64 {
319 return Err("Version number mismatch".to_string());
320 }
321 let mut s =
322 RCSummary { ntus: self.unbuffer_val(4) as i32, ..Default::default() };
323
324 if s.ntus < 1 {
328 return Err("No TUs found in first pass summary".to_string());
329 }
330 let mut total: i32 = 0;
331 for nframes in s.nframes.iter_mut() {
332 let n = self.unbuffer_val(4) as i32;
333 if n < 0 {
334 return Err("Got negative frame count".to_string());
335 }
336 total = total
337 .checked_add(n)
338 .ok_or_else(|| "Frame count too large".to_string())?;
339
340 *nframes = n;
341 }
342
343 if s.ntus > total {
345 return Err("More TUs than frames".to_string());
346 }
347
348 s.total = total;
349
350 for exp in s.exp.iter_mut() {
351 *exp = self.unbuffer_val(1) as u8;
352 }
353
354 for scale_sum in s.scale_sum.iter_mut() {
355 *scale_sum = self.unbuffer_val(8);
356 if *scale_sum < 0 {
357 return Err("Got negative scale sum".to_string());
358 }
359 }
360 Ok(s)
361 }
362}
363
364pub struct RCState {
365 target_bitrate: i32,
367 reservoir_frame_delay: i32,
371 reservoir_frame_delay_is_set: bool,
374 maybe_ac_qi_max: Option<u8>,
377 ac_qi_min: u8,
379 drop_frames: bool,
381 cap_overflow: bool,
383 cap_underflow: bool,
385 pass1_log_base_q: i64,
387 twopass_state: i32,
394 log_npixels: i64,
396 bits_per_tu: i64,
398 reservoir_fullness: i64,
400 reservoir_target: i64,
404 reservoir_max: i64,
406 log_scale: [i64; FRAME_NSUBTYPES],
411 exp: [u8; FRAME_NSUBTYPES],
413 scalefilter: [IIRBessel2; FRAME_NSUBTYPES],
418 nframes: [i32; FRAME_NSUBTYPES + 1],
425 inter_delay: [i32; FRAME_NSUBTYPES - 1],
426 inter_delay_target: i32,
427 rate_bias: i64,
429 nencoded_frames: i64,
431 nsef_frames: i64,
433 pass1_buffer: [u8; TWOPASS_HEADER_SZ],
435 pub pass1_data_retrieved: bool,
440 pass1_summary_retrieved: bool,
443 pass2_data_ready: bool,
449 prev_metrics: RCFrameMetrics,
454 cur_metrics: RCFrameMetrics,
456 frame_metrics: Vec<RCFrameMetrics>,
458 nframe_metrics: usize,
460 frame_metrics_head: usize,
462 des: RCDeserialize,
464 ntus: i32,
466 ntus_total: i32,
468 ntus_left: i32,
470 nframes_total: [i32; FRAME_NSUBTYPES + 1],
472 nframes_total_total: i32,
474 nframes_left: [i32; FRAME_NSUBTYPES + 1],
476 scale_sum: [i64; FRAME_NSUBTYPES],
478 scale_window_ntus: i32,
480 scale_window_nframes: [i32; FRAME_NSUBTYPES + 1],
482 scale_window_sum: [i64; FRAME_NSUBTYPES],
484}
485
486pub struct QuantizerParameters {
488 pub log_base_q: i64,
493 pub log_target_q: i64,
499 pub dc_qi: [u8; 3],
500 pub ac_qi: [u8; 3],
501 pub lambda: f64,
502 pub dist_scale: [f64; 3],
503}
504
505const Q57_SQUARE_EXP_SCALE: f64 =
506 (2.0 * ::std::f64::consts::LN_2) / ((1i64 << 57) as f64);
507
508fn chroma_offset(
511 log_target_q: i64, chroma_sampling: ChromaSampling,
512) -> (i64, i64) {
513 let x = log_target_q.max(0);
514 let y = match chroma_sampling {
516 ChromaSampling::Cs400 => 0,
517 ChromaSampling::Cs420 => (x >> 2) + (x >> 6), ChromaSampling::Cs422 => (x >> 3) + (x >> 4) - (x >> 7), ChromaSampling::Cs444 => (x >> 4) + (x >> 5) + (x >> 8), };
521 (0x19D_5D9F_D501_0B37 - y, 0xA4_D3C2_5E68_DC58 - y)
523}
524
525impl QuantizerParameters {
526 fn new_from_log_q(
527 log_base_q: i64, log_target_q: i64, bit_depth: usize,
528 chroma_sampling: ChromaSampling, is_intra: bool,
529 log_isqrt_mean_scale: i64,
530 ) -> QuantizerParameters {
531 let scale = log_isqrt_mean_scale + q57(QSCALE + bit_depth as i32 - 8);
532
533 let mut log_q_y = log_target_q;
534 if !is_intra && bit_depth == 8 {
535 log_q_y = log_target_q
536 + (log_target_q >> 32) * Q_MODEL_MUL[chroma_sampling as usize]
537 + Q_MODEL_ADD[chroma_sampling as usize];
538 }
539
540 let quantizer = bexp64(log_q_y + scale);
541 let (offset_u, offset_v) =
542 chroma_offset(log_q_y + log_isqrt_mean_scale, chroma_sampling);
543 let mono = chroma_sampling == ChromaSampling::Cs400;
544 let log_q_u = log_q_y + offset_u;
545 let log_q_v = log_q_y + offset_v;
546 let quantizer_u = bexp64(log_q_u + scale);
547 let quantizer_v = bexp64(log_q_v + scale);
548 let lambda = (::std::f64::consts::LN_2 / 6.0)
549 * (((log_target_q + log_isqrt_mean_scale) as f64)
550 * Q57_SQUARE_EXP_SCALE)
551 .exp();
552
553 let scale = |q| bexp64((log_target_q - q) * 2 + q57(16)) as f64 / 65536.;
554 let dist_scale = [scale(log_q_y), scale(log_q_u), scale(log_q_v)];
555
556 let base_q_idx = select_ac_qi(quantizer, bit_depth).max(1);
557
558 let min_qi = base_q_idx.saturating_sub(63).max(1);
560 let max_qi = base_q_idx.saturating_add(63);
561 let clamp_qi = |qi: u8| qi.clamp(min_qi, max_qi);
562
563 QuantizerParameters {
564 log_base_q,
565 log_target_q,
566 dc_qi: [
568 clamp_qi(select_dc_qi(quantizer, bit_depth)),
569 if mono { 0 } else { clamp_qi(select_dc_qi(quantizer_u, bit_depth)) },
570 if mono { 0 } else { clamp_qi(select_dc_qi(quantizer_v, bit_depth)) },
571 ],
572 ac_qi: [
573 base_q_idx,
574 if mono { 0 } else { clamp_qi(select_ac_qi(quantizer_u, bit_depth)) },
575 if mono { 0 } else { clamp_qi(select_ac_qi(quantizer_v, bit_depth)) },
576 ],
577 lambda,
578 dist_scale,
579 }
580 }
581}
582
583impl RCState {
584 pub fn new(
585 frame_width: i32, frame_height: i32, framerate_num: i64,
586 framerate_den: i64, target_bitrate: i32, maybe_ac_qi_max: Option<u8>,
587 ac_qi_min: u8, max_key_frame_interval: i32,
588 maybe_reservoir_frame_delay: Option<i32>,
589 ) -> RCState {
590 let reservoir_frame_delay = maybe_reservoir_frame_delay
599 .unwrap_or_else(|| ((max_key_frame_interval * 3) >> 1).min(240))
600 .max(12);
601 let npixels = (frame_width as i64) * (frame_height as i64);
603 let bits_per_tu = clamp(
610 (target_bitrate as i64) * framerate_den / framerate_num,
611 40,
612 0x4000_0000_0000,
613 ) - (TEMPORAL_DELIMITER.len() * 8) as i64;
614 let reservoir_max = bits_per_tu * (reservoir_frame_delay as i64);
615 let reservoir_target = (reservoir_max + 1) >> 1;
617 let ibpp = npixels / bits_per_tu;
619 let (i_exp, i_log_scale) = if ibpp < 1 {
622 (48u8, blog64(36) - q57(QSCALE))
623 } else if ibpp < 4 {
624 (61u8, blog64(55) - q57(QSCALE))
625 } else {
626 (77u8, blog64(129) - q57(QSCALE))
627 };
628 let (p_exp, p_log_scale) = if ibpp < 2 {
629 (69u8, blog64(32) - q57(QSCALE))
630 } else if ibpp < 139 {
631 (104u8, blog64(84) - q57(QSCALE))
632 } else {
633 (83u8, blog64(19) - q57(QSCALE))
634 };
635 let (b0_exp, b0_log_scale) = if ibpp < 2 {
636 (84u8, blog64(30) - q57(QSCALE))
637 } else if ibpp < 92 {
638 (120u8, blog64(68) - q57(QSCALE))
639 } else {
640 (68u8, blog64(4) - q57(QSCALE))
641 };
642 let (b1_exp, b1_log_scale) = if ibpp < 2 {
643 (87u8, blog64(27) - q57(QSCALE))
644 } else if ibpp < 126 {
645 (139u8, blog64(84) - q57(QSCALE))
646 } else {
647 (61u8, blog64(1) - q57(QSCALE))
648 };
649
650 RCState {
652 target_bitrate,
653 reservoir_frame_delay,
654 reservoir_frame_delay_is_set: maybe_reservoir_frame_delay.is_some(),
655 maybe_ac_qi_max,
656 ac_qi_min,
657 drop_frames: false,
658 cap_overflow: true,
659 cap_underflow: false,
660 pass1_log_base_q: 0,
661 twopass_state: PASS_SINGLE,
662 log_npixels: blog64(npixels),
663 bits_per_tu,
664 reservoir_fullness: reservoir_target,
665 reservoir_target,
666 reservoir_max,
667 log_scale: [i_log_scale, p_log_scale, b0_log_scale, b1_log_scale],
668 exp: [i_exp, p_exp, b0_exp, b1_exp],
669 scalefilter: [
670 IIRBessel2::new(4, q57_to_q24(i_log_scale)),
671 IIRBessel2::new(INTER_DELAY_TARGET_MIN, q57_to_q24(p_log_scale)),
672 IIRBessel2::new(INTER_DELAY_TARGET_MIN, q57_to_q24(b0_log_scale)),
673 IIRBessel2::new(INTER_DELAY_TARGET_MIN, q57_to_q24(b1_log_scale)),
674 ],
675 nframes: [0; FRAME_NSUBTYPES + 1],
677 inter_delay: [INTER_DELAY_TARGET_MIN; FRAME_NSUBTYPES - 1],
678 inter_delay_target: reservoir_frame_delay >> 1,
679 rate_bias: 0,
680 nencoded_frames: 0,
681 nsef_frames: 0,
682 pass1_buffer: [0; TWOPASS_HEADER_SZ],
683 pass1_data_retrieved: true,
684 pass1_summary_retrieved: false,
685 pass2_data_ready: false,
686 prev_metrics: RCFrameMetrics::new(),
687 cur_metrics: RCFrameMetrics::new(),
688 frame_metrics: Vec::new(),
689 nframe_metrics: 0,
690 frame_metrics_head: 0,
691 ntus: 0,
692 ntus_total: 0,
693 ntus_left: 0,
694 nframes_total: [0; FRAME_NSUBTYPES + 1],
695 nframes_total_total: 0,
696 nframes_left: [0; FRAME_NSUBTYPES + 1],
697 scale_sum: [0; FRAME_NSUBTYPES],
698 scale_window_ntus: 0,
699 scale_window_nframes: [0; FRAME_NSUBTYPES + 1],
700 scale_window_sum: [0; FRAME_NSUBTYPES],
701 des: RCDeserialize::default(),
702 }
703 }
704
705 pub(crate) fn select_first_pass_qi(
706 &self, bit_depth: usize, fti: usize, chroma_sampling: ChromaSampling,
707 ) -> QuantizerParameters {
708 let log_q = ((self.pass1_log_base_q + (1i64 << 11)) >> 12)
710 * (MQP_Q12[fti] as i64)
711 + DQP_Q57[fti];
712 QuantizerParameters::new_from_log_q(
713 self.pass1_log_base_q,
714 log_q,
715 bit_depth,
716 chroma_sampling,
717 fti == 0,
718 0,
719 )
720 }
721
722 #[profiling::function]
724 pub(crate) fn select_qi<T: Pixel>(
725 &self, ctx: &ContextInner<T>, output_frameno: u64, fti: usize,
726 maybe_prev_log_base_q: Option<i64>, log_isqrt_mean_scale: i64,
727 ) -> QuantizerParameters {
728 if self.target_bitrate <= 0 {
730 let bit_depth = ctx.config.bit_depth;
733 let chroma_sampling = ctx.config.chroma_sampling;
734 let (log_base_q, log_q) =
735 Self::calc_flat_quantizer(ctx.config.quantizer as u8, bit_depth, fti);
736 QuantizerParameters::new_from_log_q(
737 log_base_q,
738 log_q,
739 bit_depth,
740 chroma_sampling,
741 fti == 0,
742 log_isqrt_mean_scale,
743 )
744 } else {
745 let mut nframes: [i32; FRAME_NSUBTYPES + 1] = [0; FRAME_NSUBTYPES + 1];
746 let mut log_scale: [i64; FRAME_NSUBTYPES] = self.log_scale;
747 let mut reservoir_tus = self.reservoir_frame_delay.min(self.ntus_left);
748 let mut reservoir_frames = 0;
749 let mut log_cur_scale = (self.scalefilter[fti].y[0] as i64) << 33;
750 match self.twopass_state {
751 PASS_1 => {
753 return self.select_first_pass_qi(
754 ctx.config.bit_depth,
755 fti,
756 ctx.config.chroma_sampling,
757 );
758 }
759 PASS_2 | PASS_2_PLUS_1 => {
763 let mut scale_window_sum: [i64; FRAME_NSUBTYPES] =
764 self.scale_window_sum;
765 let mut scale_window_nframes: [i32; FRAME_NSUBTYPES + 1] =
766 self.scale_window_nframes;
767 for ftj in 0..FRAME_NSUBTYPES {
769 reservoir_frames += scale_window_nframes[ftj];
770 }
771 if !self.frame_metrics.is_empty() {
788 let mut fm_tail = self.frame_metrics_head + self.nframe_metrics;
789 if fm_tail >= self.frame_metrics.len() {
790 fm_tail -= self.frame_metrics.len();
791 }
792 let mut fmi = fm_tail;
793 loop {
794 if fmi == 0 {
795 fmi += self.frame_metrics.len();
796 }
797 fmi -= 1;
798 if fmi == self.frame_metrics_head {
800 break;
801 }
802 if self.frame_metrics[fmi].fti == FRAME_SUBTYPE_I {
804 while fmi != fm_tail {
805 let m = &self.frame_metrics[fmi];
806 let ftj = m.fti;
807 scale_window_nframes[ftj] -= 1;
808 if ftj < FRAME_NSUBTYPES {
809 scale_window_sum[ftj] -= bexp_q24(m.log_scale_q24);
810 reservoir_frames -= 1;
811 }
812 if m.show_frame {
813 reservoir_tus -= 1;
814 }
815 fmi += 1;
816 if fmi >= self.frame_metrics.len() {
817 fmi = 0;
818 }
819 }
820 break;
822 }
823 }
824 }
825 nframes = scale_window_nframes;
826 if self.cur_metrics.fti != fti {
831 scale_window_nframes[self.cur_metrics.fti] -= 1;
832 if self.cur_metrics.fti != FRAME_SUBTYPE_SEF {
833 scale_window_sum[self.cur_metrics.fti] -=
834 bexp_q24(self.cur_metrics.log_scale_q24);
835 }
836 } else {
837 log_cur_scale = (self.cur_metrics.log_scale_q24 as i64) << 33;
838 }
839 if reservoir_tus >= self.ntus_left
845 && self.ntus_total as u64
846 > ctx.gop_input_frameno_start[&output_frameno]
847 {
848 let nfinal_gop_tus = self.ntus_total
849 - (ctx.gop_input_frameno_start[&output_frameno] as i32);
850 if ctx.config.max_key_frame_interval as i32 > nfinal_gop_tus {
851 let reservoir_pad = (ctx.config.max_key_frame_interval as i32
852 - nfinal_gop_tus)
853 .min(self.reservoir_frame_delay - reservoir_tus);
854 let (guessed_reservoir_frames, guessed_reservoir_tus) = ctx
855 .guess_frame_subtypes(
856 &mut nframes,
857 reservoir_tus + reservoir_pad,
858 );
859 reservoir_frames = guessed_reservoir_frames;
860 reservoir_tus = guessed_reservoir_tus;
861 }
862 }
863 for ftj in 0..FRAME_NSUBTYPES {
867 let scale = scale_window_sum[ftj]
868 + bexp_q24(self.scalefilter[ftj].y[0])
869 * (nframes[ftj] - scale_window_nframes[ftj]) as i64;
870 log_scale[ftj] = if nframes[ftj] > 0 {
871 blog64(scale) - blog64(nframes[ftj] as i64) - q57(24)
872 } else {
873 -self.log_npixels
874 };
875 }
876 }
877 _ => {
879 let (guessed_reservoir_frames, guessed_reservoir_tus) =
885 ctx.guess_frame_subtypes(&mut nframes, self.reservoir_frame_delay);
886 reservoir_frames = guessed_reservoir_frames;
887 reservoir_tus = guessed_reservoir_tus;
888 }
890 }
891 let rate_bias = (self.rate_bias / (self.nencoded_frames + 100))
893 * (reservoir_frames as i64);
894 let rate_total = self.reservoir_fullness - self.reservoir_target
897 + rate_bias
898 + (reservoir_tus as i64) * self.bits_per_tu;
899 let bit_depth = ctx.config.bit_depth;
912 let chroma_sampling = ctx.config.chroma_sampling;
913 let mut log_qlo = blog64(ac_q(self.ac_qi_min, 0, bit_depth).get() as i64)
915 - q57(QSCALE + bit_depth as i32 - 8);
916 let mut log_qhi = blog64(
920 ac_q(self.maybe_ac_qi_max.unwrap_or(255), 0, bit_depth).get() as i64,
921 ) - q57(QSCALE + bit_depth as i32 - 8);
922 let mut log_base_q = (log_qlo + log_qhi) >> 1;
923 while log_qlo < log_qhi {
924 let mut bits = 0i64;
926 for ftj in 0..FRAME_NSUBTYPES {
927 let log_q = ((log_base_q + (1i64 << 11)) >> 12)
929 * (MQP_Q12[ftj] as i64)
930 + DQP_Q57[ftj];
931 bits += (nframes[ftj] as i64)
934 * bexp64(
935 log_scale[ftj] + self.log_npixels
936 - ((log_q + 32) >> 6) * (self.exp[ftj] as i64),
937 );
938 }
939 bits += (nframes[FRAME_SUBTYPE_SEF] as i64) * SEF_BITS;
941 let diff = bits - rate_total;
942 if diff > 0 {
943 log_qlo = log_base_q + 1;
944 } else if diff < 0 {
945 log_qhi = log_base_q - 1;
946 } else {
947 break;
948 }
949 log_base_q = (log_qlo + log_qhi) >> 1;
950 }
951 if let Some(prev_log_base_q) = maybe_prev_log_base_q {
955 log_base_q = clamp(
956 log_base_q,
957 prev_log_base_q - 0xA4_D3C2_5E68_DC58,
958 prev_log_base_q + 0xA4_D3C2_5E68_DC58,
959 );
960 }
961 let mut log_q = ((log_base_q + (1i64 << 11)) >> 12)
963 * (MQP_Q12[fti] as i64)
964 + DQP_Q57[fti];
965 if self.cap_overflow {
971 let margin = (self.reservoir_max + 31) >> 5;
975 let soft_limit = self.reservoir_fullness + self.bits_per_tu
977 - (self.reservoir_max - margin);
978 if soft_limit > 0 {
979 let log_soft_limit = blog64(soft_limit);
980 let log_scale_pixels = log_cur_scale + self.log_npixels;
986 let exp = self.exp[fti] as i64;
987 let mut log_q_exp = ((log_q + 32) >> 6) * exp;
988 if log_scale_pixels - log_q_exp < log_soft_limit {
989 log_q_exp += ((log_scale_pixels - log_soft_limit - log_q_exp)
991 >> 32)
992 * ((margin.min(soft_limit) << 32) / margin);
993 log_q = ((log_q_exp + (exp >> 1)) / exp) << 6;
994 }
995 }
996 }
997 if self.maybe_ac_qi_max.is_none() {
1001 let log_hard_limit =
1006 blog64(self.reservoir_fullness + (self.bits_per_tu >> 1));
1007 let log_scale_pixels = log_cur_scale + self.log_npixels;
1013 let exp = self.exp[fti] as i64;
1014 let mut log_q_exp = ((log_q + 32) >> 6) * exp;
1015 if log_scale_pixels - log_q_exp > log_hard_limit {
1016 log_q_exp = log_scale_pixels - log_hard_limit;
1018 log_q = ((log_q_exp + (exp >> 1)) / exp) << 6;
1019 }
1021 }
1022
1023 if let Some(qi_max) = self.maybe_ac_qi_max {
1024 let (max_log_base_q, max_log_q) =
1025 Self::calc_flat_quantizer(qi_max, ctx.config.bit_depth, fti);
1026 log_base_q = cmp::min(log_base_q, max_log_base_q);
1027 log_q = cmp::min(log_q, max_log_q);
1028 }
1029 if self.ac_qi_min > 0 {
1030 let (min_log_base_q, min_log_q) =
1031 Self::calc_flat_quantizer(self.ac_qi_min, ctx.config.bit_depth, fti);
1032 log_base_q = cmp::max(log_base_q, min_log_base_q);
1033 log_q = cmp::max(log_q, min_log_q);
1034 }
1035 QuantizerParameters::new_from_log_q(
1036 log_base_q,
1037 log_q,
1038 bit_depth,
1039 chroma_sampling,
1040 fti == 0,
1041 log_isqrt_mean_scale,
1042 )
1043 }
1044 }
1045
1046 fn calc_flat_quantizer(
1049 base_qi: u8, bit_depth: usize, fti: usize,
1050 ) -> (i64, i64) {
1051 let ac_quantizer = ac_q(base_qi, 0, bit_depth).get() as i64;
1058 let dc_qi = select_dc_qi(ac_quantizer, bit_depth);
1060 let dc_quantizer = dc_q(dc_qi, 0, bit_depth).get() as i64;
1061 let log_ac_q = blog64(ac_quantizer) - q57(QSCALE + bit_depth as i32 - 8);
1063 let log_dc_q = blog64(dc_quantizer) - q57(QSCALE + bit_depth as i32 - 8);
1064 let log_base_q = (log_ac_q + log_dc_q + 1) >> 1;
1066 let log_q = ((log_base_q + (1i64 << 11)) >> 12) * (MQP_Q12[fti] as i64)
1068 + DQP_Q57[fti];
1069 (log_base_q, log_q)
1070 }
1071
1072 #[profiling::function]
1073 pub fn update_state(
1074 &mut self, bits: i64, fti: usize, show_frame: bool, log_target_q: i64,
1075 trial: bool, droppable: bool,
1076 ) -> bool {
1077 if trial {
1078 assert!(self.needs_trial_encode(fti));
1079 assert!(bits > 0);
1080 }
1081 let mut dropped = false;
1082 if self.target_bitrate > 0 {
1084 let mut estimated_bits = 0;
1085 let mut bits = bits;
1086 let mut droppable = droppable;
1087 let mut log_scale = q57(-64);
1088 if !self.drop_frames
1091 || fti == FRAME_SUBTYPE_SEF
1092 || (self.twopass_state == PASS_2
1093 || self.twopass_state == PASS_2_PLUS_1)
1094 && !self.frame_metrics.is_empty()
1095 {
1096 droppable = false;
1097 }
1098 if fti == FRAME_SUBTYPE_SEF {
1099 debug_assert!(bits == SEF_BITS);
1100 debug_assert!(show_frame);
1101 debug_assert!(!trial);
1103 estimated_bits = SEF_BITS;
1104 self.nsef_frames += 1;
1105 } else {
1106 let log_q_exp = ((log_target_q + 32) >> 6) * (self.exp[fti] as i64);
1107 let prev_log_scale = self.log_scale[fti];
1108 if bits <= 0 {
1109 bits = 0;
1111 dropped = true;
1112 } else {
1114 let log_bits = blog64(bits);
1116 log_scale = (log_bits - self.log_npixels + log_q_exp).min(q57(16));
1117 estimated_bits =
1118 bexp64(prev_log_scale + self.log_npixels - log_q_exp);
1119 if !trial {
1120 self.nencoded_frames += 1;
1121 }
1122 }
1123 }
1124 let log_scale_q24 = q57_to_q24(log_scale);
1125 if self.twopass_state == PASS_2 || self.twopass_state == PASS_2_PLUS_1 {
1127 if !trial {
1129 self.prev_metrics = self.cur_metrics;
1131 let ftj = self.prev_metrics.fti;
1133 self.nframes_left[ftj] -= 1;
1134 self.scale_window_nframes[ftj] -= 1;
1135 if ftj < FRAME_NSUBTYPES {
1136 self.scale_window_sum[ftj] -=
1137 bexp_q24(self.prev_metrics.log_scale_q24);
1138 }
1139 if self.prev_metrics.show_frame {
1140 self.ntus_left -= 1;
1141 self.scale_window_ntus -= 1;
1142 }
1143 if !self.frame_metrics.is_empty() {
1145 self.nframe_metrics -= 1;
1146 self.frame_metrics_head += 1;
1147 if self.frame_metrics_head >= self.frame_metrics.len() {
1148 self.frame_metrics_head = 0;
1149 }
1150 }
1151 self.pass2_data_ready = false;
1153 self.twopass_in(None).unwrap_or(0);
1157 }
1158 }
1159 if self.twopass_state == PASS_1 || self.twopass_state == PASS_2_PLUS_1 {
1160 self.prev_metrics.log_scale_q24 = log_scale_q24;
1162 self.prev_metrics.fti = fti;
1163 self.prev_metrics.show_frame = show_frame;
1164 self.pass1_data_retrieved = false;
1165 }
1166 if fti != FRAME_SUBTYPE_SEF && bits > 0 {
1168 if trial || self.nframes[fti] <= 0 {
1172 let f = &mut self.scalefilter[fti];
1173 let x = log_scale_q24;
1174 f.x[0] = x;
1175 f.x[1] = x;
1176 f.y[0] = x;
1177 f.y[1] = x;
1178 self.log_scale[fti] = log_scale;
1179 } else {
1181 if fti > 0
1184 && self.inter_delay[fti - 1] < self.inter_delay_target
1185 && self.nframes[fti] >= self.inter_delay[fti - 1]
1186 {
1187 self.inter_delay[fti - 1] += 1;
1188 self.scalefilter[fti].reinit(self.inter_delay[fti - 1]);
1189 }
1190 self.log_scale[fti] =
1193 q24_to_q57(self.scalefilter[fti].update(log_scale_q24));
1194 }
1195 if droppable && self.reservoir_fullness + self.bits_per_tu < bits {
1197 bits = 0;
1199 dropped = true;
1200 } else {
1201 }
1206 }
1207 if !trial {
1208 if !trial && self.nframes[fti] < i32::MAX {
1210 self.nframes[fti] += 1;
1211 }
1212 self.reservoir_fullness -= bits;
1213 if show_frame {
1214 self.reservoir_fullness += self.bits_per_tu;
1215 }
1217 if self.cap_overflow {
1220 self.reservoir_fullness =
1221 self.reservoir_fullness.min(self.reservoir_max);
1222 }
1223 if self.cap_underflow {
1226 self.reservoir_fullness = self.reservoir_fullness.max(0);
1227 }
1228 self.rate_bias += estimated_bits - bits;
1230 }
1231 }
1232 dropped
1233 }
1234
1235 pub const fn needs_trial_encode(&self, fti: usize) -> bool {
1236 self.target_bitrate > 0 && self.nframes[fti] == 0
1237 }
1238
1239 pub(crate) const fn ready(&self) -> bool {
1240 match self.twopass_state {
1241 PASS_SINGLE => true,
1242 PASS_1 => self.pass1_data_retrieved,
1243 PASS_2 => self.pass2_data_ready,
1244 _ => self.pass1_data_retrieved && self.pass2_data_ready,
1245 }
1246 }
1247
1248 fn buffer_val(&mut self, val: i64, bytes: usize, cur_pos: usize) -> usize {
1249 let mut val = val;
1250 let mut bytes = bytes;
1251 let mut cur_pos = cur_pos;
1252 while bytes > 0 {
1253 bytes -= 1;
1254 self.pass1_buffer[cur_pos] = val as u8;
1255 cur_pos += 1;
1256 val >>= 8;
1257 }
1258 cur_pos
1259 }
1260
1261 pub(crate) fn select_pass1_log_base_q<T: Pixel>(
1262 &self, ctx: &ContextInner<T>, output_frameno: u64,
1263 ) -> i64 {
1264 assert_eq!(self.twopass_state, PASS_SINGLE);
1265 self.select_qi(ctx, output_frameno, FRAME_SUBTYPE_I, None, 0).log_base_q
1266 }
1267
1268 pub(crate) fn init_first_pass(
1270 &mut self, maybe_pass1_log_base_q: Option<i64>,
1271 ) {
1272 if let Some(pass1_log_base_q) = maybe_pass1_log_base_q {
1273 assert_eq!(self.twopass_state, PASS_SINGLE);
1274 self.pass1_log_base_q = pass1_log_base_q;
1276 } else {
1277 debug_assert!(self.twopass_state == PASS_2);
1278 }
1279 self.twopass_state += PASS_1;
1280 }
1281
1282 fn emit_placeholder_summary(&mut self) -> &[u8] {
1284 let mut cur_pos = 0;
1286 cur_pos = self.buffer_val(TWOPASS_MAGIC as i64, 4, cur_pos);
1287 cur_pos = self.buffer_val(TWOPASS_VERSION as i64, 4, cur_pos);
1288 cur_pos = self.buffer_val(0, TWOPASS_HEADER_SZ - 8, cur_pos);
1289 debug_assert!(cur_pos == TWOPASS_HEADER_SZ);
1290 self.pass1_data_retrieved = true;
1291 &self.pass1_buffer[..cur_pos]
1292 }
1293
1294 pub(crate) fn emit_frame_data(&mut self) -> Option<&[u8]> {
1296 let mut cur_pos = 0;
1297 let fti = self.prev_metrics.fti;
1298 if fti < FRAME_NSUBTYPES {
1299 self.scale_sum[fti] += bexp_q24(self.prev_metrics.log_scale_q24);
1300 }
1301 if self.prev_metrics.show_frame {
1302 self.ntus += 1;
1303 }
1304 if self.nencoded_frames + self.nsef_frames >= i32::MAX as i64 {
1307 None?
1308 }
1309 cur_pos = self.buffer_val(
1310 ((self.prev_metrics.show_frame as i64) << 31)
1311 | self.prev_metrics.fti as i64,
1312 4,
1313 cur_pos,
1314 );
1315 cur_pos =
1316 self.buffer_val(self.prev_metrics.log_scale_q24 as i64, 4, cur_pos);
1317 debug_assert!(cur_pos == TWOPASS_PACKET_SZ);
1318 self.pass1_data_retrieved = true;
1319 Some(&self.pass1_buffer[..cur_pos])
1320 }
1321
1322 pub(crate) fn emit_summary(&mut self) -> &[u8] {
1324 let mut cur_pos = 0;
1325 cur_pos = self.buffer_val(TWOPASS_MAGIC as i64, 4, cur_pos);
1326 cur_pos = self.buffer_val(TWOPASS_VERSION as i64, 4, cur_pos);
1327 cur_pos = self.buffer_val(self.ntus as i64, 4, cur_pos);
1328 for fti in 0..=FRAME_NSUBTYPES {
1329 cur_pos = self.buffer_val(self.nframes[fti] as i64, 4, cur_pos);
1330 }
1331 for fti in 0..FRAME_NSUBTYPES {
1332 cur_pos = self.buffer_val(self.exp[fti] as i64, 1, cur_pos);
1333 }
1334 for fti in 0..FRAME_NSUBTYPES {
1335 cur_pos = self.buffer_val(self.scale_sum[fti], 8, cur_pos);
1336 }
1337 debug_assert!(cur_pos == TWOPASS_HEADER_SZ);
1338 self.pass1_summary_retrieved = true;
1339 &self.pass1_buffer[..cur_pos]
1340 }
1341
1342 pub(crate) fn twopass_out(
1344 &mut self, done_processing: bool,
1345 ) -> Option<&[u8]> {
1346 if !self.pass1_data_retrieved {
1347 if self.twopass_state != PASS_1 && self.twopass_state != PASS_2_PLUS_1 {
1348 Some(self.emit_placeholder_summary())
1349 } else {
1350 self.emit_frame_data()
1351 }
1352 } else if done_processing && !self.pass1_summary_retrieved {
1353 Some(self.emit_summary())
1354 } else {
1355 None
1357 }
1358 }
1359
1360 pub(crate) fn init_second_pass(&mut self) {
1362 if self.twopass_state == PASS_SINGLE || self.twopass_state == PASS_1 {
1363 self.twopass_state += PASS_2;
1365 if self.reservoir_frame_delay_is_set {
1368 debug_assert!(self.reservoir_frame_delay > 0);
1369 let nmetrics = (self.reservoir_frame_delay as usize) * 2 + 8;
1380 self.frame_metrics.reserve_exact(nmetrics);
1381 self.frame_metrics.resize(nmetrics, RCFrameMetrics::new());
1382 }
1383 }
1384 }
1385
1386 pub(crate) fn setup_second_pass(&mut self, s: &RCSummary) {
1387 self.ntus_total = s.ntus;
1388 self.ntus_left = s.ntus;
1389 self.nframes_total = s.nframes;
1390 self.nframes_left = s.nframes;
1391 self.nframes_total_total = s.nframes.iter().sum();
1392 if self.frame_metrics.is_empty() {
1393 self.reservoir_frame_delay = s.ntus;
1394 self.scale_window_nframes = self.nframes_total;
1395 self.scale_window_sum = s.scale_sum;
1396 self.reservoir_max =
1397 self.bits_per_tu * (self.reservoir_frame_delay as i64);
1398 self.reservoir_target = (self.reservoir_max + 1) >> 1;
1399 self.reservoir_fullness = self.reservoir_target;
1400 } else {
1401 self.reservoir_frame_delay = self.reservoir_frame_delay.min(s.ntus);
1402 }
1403 self.exp = s.exp;
1404 }
1405
1406 fn twopass_parse_summary(&mut self, buf: &[u8]) -> Result<usize, String> {
1411 let consumed = self.des.buffer_fill(buf, 0, TWOPASS_HEADER_SZ);
1412 if self.des.pass2_buffer_fill >= TWOPASS_HEADER_SZ {
1413 self.des.pass2_buffer_pos = 0;
1414
1415 let s = self.des.parse_summary()?;
1416
1417 self.setup_second_pass(&s);
1418
1419 self.des.pass2_buffer_fill = 0;
1424 }
1425
1426 Ok(consumed)
1427 }
1428
1429 pub(crate) fn twopass_first_packet_size(&self) -> usize {
1434 let frames_needed = if !self.frame_metrics.is_empty() {
1435 self.reservoir_frame_delay as usize
1438 } else {
1439 1
1441 };
1442
1443 TWOPASS_HEADER_SZ + frames_needed * TWOPASS_PACKET_SZ
1444 }
1445
1446 pub(crate) fn twopass_in_frames_needed(&self) -> i32 {
1449 if self.target_bitrate <= 0 {
1450 return 0;
1451 }
1452 if self.frame_metrics.is_empty() {
1453 return i32::from(!self.pass2_data_ready);
1454 }
1455 let mut cur_scale_window_nframes = 0;
1456 let mut cur_nframes_left = 0;
1457 for fti in 0..=FRAME_NSUBTYPES {
1458 cur_scale_window_nframes += self.scale_window_nframes[fti];
1459 cur_nframes_left += self.nframes_left[fti];
1460 }
1461
1462 (self.reservoir_frame_delay - self.scale_window_ntus)
1463 .clamp(0, cur_nframes_left - cur_scale_window_nframes)
1464 }
1465
1466 pub(crate) fn parse_frame_data_packet(
1467 &mut self, buf: &[u8],
1468 ) -> Result<(), String> {
1469 if buf.len() != TWOPASS_PACKET_SZ {
1470 return Err("Incorrect buffer size".to_string());
1471 }
1472
1473 self.des.buffer_fill(buf, 0, TWOPASS_PACKET_SZ);
1474 self.des.pass2_buffer_pos = 0;
1475 let m = self.des.parse_metrics()?;
1476 self.des.pass2_buffer_fill = 0;
1477
1478 if self.frame_metrics.is_empty() {
1479 self.cur_metrics = m;
1481 self.pass2_data_ready = true;
1482 } else {
1483 let frames_needed = self.twopass_in_frames_needed();
1485
1486 if frames_needed > 0 {
1487 if self.nframe_metrics >= self.frame_metrics.len() {
1488 return Err(
1489 "Read too many frames without finding enough TUs".to_string(),
1490 );
1491 }
1492
1493 let mut fmi = self.frame_metrics_head + self.nframe_metrics;
1494 if fmi >= self.frame_metrics.len() {
1495 fmi -= self.frame_metrics.len();
1496 }
1497 self.nframe_metrics += 1;
1498 self.frame_metrics[fmi] = m;
1499 self.scale_window_nframes[m.fti] += 1;
1501 if m.fti < FRAME_NSUBTYPES {
1502 self.scale_window_sum[m.fti] += bexp_q24(m.log_scale_q24);
1503 }
1504 if m.show_frame {
1505 self.scale_window_ntus += 1;
1506 }
1507 if frames_needed == 1 {
1508 self.pass2_data_ready = true;
1509 self.cur_metrics = self.frame_metrics[self.frame_metrics_head];
1510 }
1511 } else {
1512 return Err("No frames needed".to_string());
1513 }
1514 }
1515
1516 Ok(())
1517 }
1518
1519 fn twopass_parse_frame_data(
1527 &mut self, maybe_buf: Option<&[u8]>, mut consumed: usize,
1528 ) -> Result<usize, String> {
1529 {
1530 if self.frame_metrics.is_empty() {
1531 if let Some(buf) = maybe_buf {
1533 consumed = self.des.buffer_fill(buf, consumed, TWOPASS_PACKET_SZ);
1534 if self.des.pass2_buffer_fill >= TWOPASS_PACKET_SZ {
1535 self.des.pass2_buffer_pos = 0;
1536 self.cur_metrics = self.des.parse_metrics()?;
1538 self.des.pass2_buffer_fill = 0;
1540 self.pass2_data_ready = true;
1541 }
1542 } else {
1543 return Ok(TWOPASS_PACKET_SZ - self.des.pass2_buffer_fill);
1544 }
1545 } else {
1546 let mut cur_scale_window_nframes = 0;
1548 let mut cur_nframes_left = 0;
1549
1550 for fti in 0..=FRAME_NSUBTYPES {
1551 cur_scale_window_nframes += self.scale_window_nframes[fti];
1552 cur_nframes_left += self.nframes_left[fti];
1553 }
1554
1555 let mut frames_needed = self.twopass_in_frames_needed();
1556 while frames_needed > 0 {
1557 if let Some(buf) = maybe_buf {
1558 consumed = self.des.buffer_fill(buf, consumed, TWOPASS_PACKET_SZ);
1559 if self.des.pass2_buffer_fill >= TWOPASS_PACKET_SZ {
1560 self.des.pass2_buffer_pos = 0;
1561 let m = self.des.parse_metrics()?;
1563 if self.nframe_metrics >= self.frame_metrics.len() {
1565 return Err(
1566 "Read too many frames without finding enough TUs"
1567 .to_string(),
1568 );
1569 }
1570 let mut fmi = self.frame_metrics_head + self.nframe_metrics;
1571 if fmi >= self.frame_metrics.len() {
1572 fmi -= self.frame_metrics.len();
1573 }
1574 self.nframe_metrics += 1;
1575 self.frame_metrics[fmi] = m;
1576 self.scale_window_nframes[m.fti] += 1;
1578 cur_scale_window_nframes += 1;
1579 if m.fti < FRAME_NSUBTYPES {
1580 self.scale_window_sum[m.fti] += bexp_q24(m.log_scale_q24);
1581 }
1582 if m.show_frame {
1583 self.scale_window_ntus += 1;
1584 }
1585 frames_needed = (self.reservoir_frame_delay
1586 - self.scale_window_ntus)
1587 .clamp(0, cur_nframes_left - cur_scale_window_nframes);
1588 self.des.pass2_buffer_fill = 0;
1590 } else {
1591 break;
1593 }
1594 } else {
1595 return Ok(
1596 TWOPASS_PACKET_SZ * (frames_needed as usize)
1597 - self.des.pass2_buffer_fill,
1598 );
1599 }
1600 }
1601 if frames_needed <= 0 {
1604 self.cur_metrics = self.frame_metrics[self.frame_metrics_head];
1605 self.pass2_data_ready = true;
1607 }
1608 }
1609 }
1610
1611 Ok(consumed)
1612 }
1613
1614 pub(crate) fn twopass_in(
1621 &mut self, maybe_buf: Option<&[u8]>,
1622 ) -> Result<usize, String> {
1623 let mut consumed = 0;
1624 self.init_second_pass();
1625 if self.nframes_total[FRAME_SUBTYPE_I] == 0 {
1627 self.pass2_data_ready = false;
1628 if let Some(buf) = maybe_buf {
1629 consumed = self.twopass_parse_summary(buf)?
1630 } else {
1631 return Ok(self.twopass_first_packet_size());
1632 }
1633 }
1634 if self.nframes_total[FRAME_SUBTYPE_I] > 0 {
1635 if self.nencoded_frames + self.nsef_frames
1636 >= self.nframes_total_total as i64
1637 {
1638 self.pass2_data_ready = false;
1641 } else if !self.pass2_data_ready {
1642 return self.twopass_parse_frame_data(maybe_buf, consumed);
1643 }
1644 }
1645 Ok(consumed)
1646 }
1647}