@@ -1362,6 +1362,7 @@ impl RCState {
1362
1362
Ok ( RCFrameMetrics { log_scale_q24, fti, show_frame } )
1363
1363
}
1364
1364
1365
+ // Initialize the rate control for second pass encoding
1365
1366
pub ( crate ) fn twopass_init ( & mut self ) {
1366
1367
if self . twopass_state == PASS_SINGLE || self . twopass_state == PASS_1 {
1367
1368
// Initialize the second pass.
@@ -1387,7 +1388,6 @@ impl RCState {
1387
1388
}
1388
1389
}
1389
1390
1390
-
1391
1391
// Parse the rate control summary
1392
1392
//
1393
1393
// It returns the amount of data consumed in the process or
@@ -1488,6 +1488,114 @@ impl RCState {
1488
1488
TWOPASS_HEADER_SZ + frames_needed * TWOPASS_PACKET_SZ
1489
1489
}
1490
1490
1491
+ // Return the number of frame data packets to be parsed before
1492
+ // the encoding process can continue.
1493
+ fn twopass_in_frames_needed ( & self ) -> i32 {
1494
+ let mut cur_scale_window_nframes = 0 ;
1495
+ let mut cur_nframes_left = 0 ;
1496
+ for fti in 0 ..=FRAME_NSUBTYPES {
1497
+ cur_scale_window_nframes += self . scale_window_nframes [ fti] ;
1498
+ cur_nframes_left += self . nframes_left [ fti] ;
1499
+ }
1500
+
1501
+ ( self . reservoir_frame_delay - self . scale_window_ntus )
1502
+ . max ( 0 )
1503
+ . min ( cur_nframes_left - cur_scale_window_nframes)
1504
+ }
1505
+ // Parse the rate control per-frame data
1506
+ //
1507
+ // If no buffer is passed return the amount of data it expects
1508
+ // to consume next.
1509
+ //
1510
+ // If a properly sized buffer is passed it returns the amount of data
1511
+ // consumed in the process or an empty error on parsing failure.
1512
+ fn twopass_parse_frame_data (
1513
+ & mut self , maybe_buf : Option < & [ u8 ] > , mut consumed : usize ,
1514
+ ) -> Result < usize , ( ) > {
1515
+ {
1516
+ if self . frame_metrics . is_empty ( ) {
1517
+ // We're using a whole-file buffer.
1518
+ if let Some ( buf) = maybe_buf {
1519
+ consumed = self . buffer_fill ( buf, consumed, TWOPASS_PACKET_SZ ) ;
1520
+ if self . pass2_buffer_fill >= TWOPASS_PACKET_SZ {
1521
+ self . pass2_buffer_pos = 0 ;
1522
+ // Read metrics for the next frame.
1523
+ self . cur_metrics = self . parse_metrics ( ) ?;
1524
+ // Clear the buffer for the next frame.
1525
+ self . pass2_buffer_fill = 0 ;
1526
+ self . pass2_data_ready = true ;
1527
+ }
1528
+ } else {
1529
+ return Ok ( TWOPASS_PACKET_SZ - self . pass2_buffer_fill ) ;
1530
+ }
1531
+ } else {
1532
+ // We're using a finite buffer.
1533
+ let mut cur_scale_window_nframes = 0 ;
1534
+ let mut cur_nframes_left = 0 ;
1535
+
1536
+ for fti in 0 ..=FRAME_NSUBTYPES {
1537
+ cur_scale_window_nframes += self . scale_window_nframes [ fti] ;
1538
+ cur_nframes_left += self . nframes_left [ fti] ;
1539
+ }
1540
+
1541
+ let mut frames_needed = self . twopass_in_frames_needed ( ) ;
1542
+ while frames_needed > 0 {
1543
+ if let Some ( buf) = maybe_buf {
1544
+ consumed = self . buffer_fill ( buf, consumed, TWOPASS_PACKET_SZ ) ;
1545
+ if self . pass2_buffer_fill >= TWOPASS_PACKET_SZ {
1546
+ self . pass2_buffer_pos = 0 ;
1547
+ // Read the metrics for the next frame.
1548
+ let m = self . parse_metrics ( ) ?;
1549
+ // Add them to the circular buffer.
1550
+ if self . nframe_metrics >= self . frame_metrics . len ( ) {
1551
+ // We read too many frames without finding enough TUs.
1552
+ return Err ( ( ) ) ;
1553
+ }
1554
+ let mut fmi = self . frame_metrics_head + self . nframe_metrics ;
1555
+ if fmi >= self . frame_metrics . len ( ) {
1556
+ fmi -= self . frame_metrics . len ( ) ;
1557
+ }
1558
+ self . nframe_metrics += 1 ;
1559
+ self . frame_metrics [ fmi] = m;
1560
+ // And accumulate the statistics over the window.
1561
+ self . scale_window_nframes [ m. fti ] += 1 ;
1562
+ cur_scale_window_nframes += 1 ;
1563
+ if m. fti < FRAME_NSUBTYPES {
1564
+ self . scale_window_sum [ m. fti ] += bexp_q24 ( m. log_scale_q24 ) ;
1565
+ }
1566
+ if m. show_frame {
1567
+ self . scale_window_ntus += 1 ;
1568
+ }
1569
+ frames_needed = ( self . reservoir_frame_delay
1570
+ - self . scale_window_ntus )
1571
+ . max ( 0 )
1572
+ . min ( cur_nframes_left - cur_scale_window_nframes) ;
1573
+ // Clear the buffer for the next frame.
1574
+ self . pass2_buffer_fill = 0 ;
1575
+ } else {
1576
+ // Go back for more data.
1577
+ break ;
1578
+ }
1579
+ } else {
1580
+ return Ok (
1581
+ TWOPASS_PACKET_SZ * ( frames_needed as usize )
1582
+ - self . pass2_buffer_fill ,
1583
+ ) ;
1584
+ }
1585
+ }
1586
+ // If we've got all the frames we need, fill in the current metrics.
1587
+ // We're ready to go.
1588
+ if frames_needed <= 0 {
1589
+ self . cur_metrics = self . frame_metrics [ self . frame_metrics_head ] ;
1590
+ // Mark us ready for the next frame.
1591
+ self . pass2_data_ready = true ;
1592
+ }
1593
+ }
1594
+ }
1595
+
1596
+ Ok ( consumed)
1597
+ }
1598
+
1491
1599
// If called without a buffer it will return the size of the next
1492
1600
// buffer it expects.
1493
1601
//
@@ -1516,85 +1624,7 @@ impl RCState {
1516
1624
// to allow any more frames to be encoded.
1517
1625
self . pass2_data_ready = false ;
1518
1626
} else if !self . pass2_data_ready {
1519
- if self . frame_metrics . is_empty ( ) {
1520
- // We're using a whole-file buffer.
1521
- if let Some ( buf) = maybe_buf {
1522
- consumed = self . buffer_fill ( buf, consumed, TWOPASS_PACKET_SZ ) ;
1523
- if self . pass2_buffer_fill >= TWOPASS_PACKET_SZ {
1524
- self . pass2_buffer_pos = 0 ;
1525
- // Read metrics for the next frame.
1526
- self . cur_metrics = self . parse_metrics ( ) ?;
1527
- // Clear the buffer for the next frame.
1528
- self . pass2_buffer_fill = 0 ;
1529
- self . pass2_data_ready = true ;
1530
- }
1531
- } else {
1532
- return Ok ( TWOPASS_PACKET_SZ - self . pass2_buffer_fill ) ;
1533
- }
1534
- } else {
1535
- // We're using a finite buffer.
1536
- let mut cur_scale_window_nframes = 0 ;
1537
- let mut cur_nframes_left = 0 ;
1538
- for fti in 0 ..=FRAME_NSUBTYPES {
1539
- cur_scale_window_nframes += self . scale_window_nframes [ fti] ;
1540
- cur_nframes_left += self . nframes_left [ fti] ;
1541
- }
1542
- let mut frames_needed = ( self . reservoir_frame_delay
1543
- - self . scale_window_ntus )
1544
- . max ( 0 )
1545
- . min ( cur_nframes_left - cur_scale_window_nframes) ;
1546
- while frames_needed > 0 {
1547
- if let Some ( buf) = maybe_buf {
1548
- consumed = self . buffer_fill ( buf, consumed, TWOPASS_PACKET_SZ ) ;
1549
- if self . pass2_buffer_fill >= TWOPASS_PACKET_SZ {
1550
- self . pass2_buffer_pos = 0 ;
1551
- // Read the metrics for the next frame.
1552
- let m = self . parse_metrics ( ) ?;
1553
- // Add them to the circular buffer.
1554
- if self . nframe_metrics >= self . frame_metrics . len ( ) {
1555
- // We read too many frames without finding enough TUs.
1556
- return Err ( ( ) ) ;
1557
- }
1558
- let mut fmi = self . frame_metrics_head + self . nframe_metrics ;
1559
- if fmi >= self . frame_metrics . len ( ) {
1560
- fmi -= self . frame_metrics . len ( ) ;
1561
- }
1562
- self . nframe_metrics += 1 ;
1563
- self . frame_metrics [ fmi] = m;
1564
- // And accumulate the statistics over the window.
1565
- self . scale_window_nframes [ m. fti ] += 1 ;
1566
- cur_scale_window_nframes += 1 ;
1567
- if m. fti < FRAME_NSUBTYPES {
1568
- self . scale_window_sum [ m. fti ] += bexp_q24 ( m. log_scale_q24 ) ;
1569
- }
1570
- if m. show_frame {
1571
- self . scale_window_ntus += 1 ;
1572
- }
1573
- frames_needed = ( self . reservoir_frame_delay
1574
- - self . scale_window_ntus )
1575
- . max ( 0 )
1576
- . min ( cur_nframes_left - cur_scale_window_nframes) ;
1577
- // Clear the buffer for the next frame.
1578
- self . pass2_buffer_fill = 0 ;
1579
- } else {
1580
- // Go back for more data.
1581
- break ;
1582
- }
1583
- } else {
1584
- return Ok (
1585
- TWOPASS_PACKET_SZ * ( frames_needed as usize )
1586
- - self . pass2_buffer_fill ,
1587
- ) ;
1588
- }
1589
- }
1590
- // If we've got all the frames we need, fill in the current metrics.
1591
- // We're ready to go.
1592
- if frames_needed <= 0 {
1593
- self . cur_metrics = self . frame_metrics [ self . frame_metrics_head ] ;
1594
- // Mark us ready for the next frame.
1595
- self . pass2_data_ready = true ;
1596
- }
1597
- }
1627
+ return self . twopass_parse_frame_data ( maybe_buf, consumed) ;
1598
1628
}
1599
1629
}
1600
1630
Ok ( consumed)
0 commit comments