Skip to content

Commit 5870b10

Browse files
lu-zerobarrbrain
authored andcommitted
Refactor twopass_out()
It is another function taking care of multiple concerns at the same time: - first pass initialization - emitting summary (dummy and final) - emitting per-frame pass data
1 parent c6a5abe commit 5870b10

File tree

1 file changed

+78
-52
lines changed

1 file changed

+78
-52
lines changed

src/rate.rs

Lines changed: 78 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,69 +1264,95 @@ impl RCState {
12641264
TwoPassOutParams { pass1_log_base_q, done_processing }
12651265
}
12661266

1267+
// Initialize the first pass and emit a placeholder summary
1268+
fn init_first_pass(&mut self, pass1_log_base_q: i64) {
1269+
if self.twopass_state == PASS_SINGLE {
1270+
// Pick first-pass qi for scale calculations.
1271+
self.pass1_log_base_q = pass1_log_base_q;
1272+
} else {
1273+
debug_assert!(self.twopass_state == PASS_2);
1274+
}
1275+
self.twopass_state += PASS_1;
1276+
}
1277+
1278+
// Prepare a placeholder summary
1279+
fn emit_placeholder_summary(&mut self) -> &[u8] {
1280+
// Fill in dummy summary values.
1281+
let mut cur_pos = 0;
1282+
cur_pos = self.buffer_val(TWOPASS_MAGIC as i64, 4, cur_pos);
1283+
cur_pos = self.buffer_val(TWOPASS_VERSION as i64, 4, cur_pos);
1284+
cur_pos = self.buffer_val(0, TWOPASS_HEADER_SZ - 8, cur_pos);
1285+
debug_assert!(cur_pos == TWOPASS_HEADER_SZ);
1286+
self.pass1_data_retrieved = true;
1287+
&self.pass1_buffer[..cur_pos]
1288+
}
1289+
1290+
// Frame-specific pass data
1291+
fn emit_frame_data(&mut self) -> Option<&[u8]> {
1292+
let mut cur_pos = 0;
1293+
let fti = self.prev_metrics.fti;
1294+
if fti < FRAME_NSUBTYPES {
1295+
self.scale_sum[fti] += bexp_q24(self.prev_metrics.log_scale_q24);
1296+
}
1297+
if self.prev_metrics.show_frame {
1298+
self.ntus += 1;
1299+
}
1300+
// If we have encoded too many frames, prevent us from reaching the
1301+
// ready state required to encode more.
1302+
if self.nencoded_frames + self.nsef_frames >= std::i32::MAX as i64 {
1303+
None?
1304+
}
1305+
cur_pos = self.buffer_val(
1306+
(self.prev_metrics.show_frame as i64) << 31
1307+
| self.prev_metrics.fti as i64,
1308+
4,
1309+
cur_pos,
1310+
);
1311+
cur_pos =
1312+
self.buffer_val(self.prev_metrics.log_scale_q24 as i64, 4, cur_pos);
1313+
debug_assert!(cur_pos == TWOPASS_PACKET_SZ);
1314+
self.pass1_data_retrieved = true;
1315+
Some(&self.pass1_buffer[..cur_pos])
1316+
}
1317+
1318+
// Summary of the whole encoding process.
1319+
fn emit_summary(&mut self) -> &[u8] {
1320+
let mut cur_pos = 0;
1321+
cur_pos = self.buffer_val(TWOPASS_MAGIC as i64, 4, cur_pos);
1322+
cur_pos = self.buffer_val(TWOPASS_VERSION as i64, 4, cur_pos);
1323+
cur_pos = self.buffer_val(self.ntus as i64, 4, cur_pos);
1324+
for fti in 0..=FRAME_NSUBTYPES {
1325+
cur_pos = self.buffer_val(self.nframes[fti] as i64, 4, cur_pos);
1326+
}
1327+
for fti in 0..FRAME_NSUBTYPES {
1328+
cur_pos = self.buffer_val(self.exp[fti] as i64, 1, cur_pos);
1329+
}
1330+
for fti in 0..FRAME_NSUBTYPES {
1331+
cur_pos = self.buffer_val(self.scale_sum[fti], 8, cur_pos);
1332+
}
1333+
debug_assert!(cur_pos == TWOPASS_HEADER_SZ);
1334+
self.pass1_summary_retrieved = true;
1335+
&self.pass1_buffer[..cur_pos]
1336+
}
1337+
1338+
// Initialize the first pass, emit either summary or frame-specific data
1339+
// depending on the previous call
12671340
pub(crate) fn twopass_out(
12681341
&mut self, params: TwoPassOutParams,
12691342
) -> Option<&[u8]> {
1270-
let mut cur_pos = 0;
12711343
if !self.pass1_data_retrieved {
12721344
if self.twopass_state != PASS_1 && self.twopass_state != PASS_2_PLUS_1 {
1273-
// Initialize the first pass.
1274-
if self.twopass_state == PASS_SINGLE {
1275-
// Pick first-pass qi for scale calculations.
1276-
self.pass1_log_base_q = params.pass1_log_base_q;
1277-
} else {
1278-
debug_assert!(self.twopass_state == PASS_2);
1279-
}
1280-
self.twopass_state += PASS_1;
1281-
// Fill in dummy summary values.
1282-
cur_pos = self.buffer_val(TWOPASS_MAGIC as i64, 4, cur_pos);
1283-
cur_pos = self.buffer_val(TWOPASS_VERSION as i64, 4, cur_pos);
1284-
cur_pos = self.buffer_val(0, TWOPASS_HEADER_SZ - 8, cur_pos);
1285-
debug_assert!(cur_pos == TWOPASS_HEADER_SZ);
1345+
self.init_first_pass(params.pass1_log_base_q);
1346+
Some(self.emit_placeholder_summary())
12861347
} else {
1287-
let fti = self.prev_metrics.fti;
1288-
if fti < FRAME_NSUBTYPES {
1289-
self.scale_sum[fti] += bexp_q24(self.prev_metrics.log_scale_q24);
1290-
}
1291-
if self.prev_metrics.show_frame {
1292-
self.ntus += 1;
1293-
}
1294-
// If we have encoded too many frames, prevent us from reaching the
1295-
// ready state required to encode more.
1296-
if self.nencoded_frames + self.nsef_frames >= std::i32::MAX as i64 {
1297-
None?
1298-
}
1299-
cur_pos = self.buffer_val(
1300-
(self.prev_metrics.show_frame as i64) << 31
1301-
| self.prev_metrics.fti as i64,
1302-
4,
1303-
cur_pos,
1304-
);
1305-
cur_pos =
1306-
self.buffer_val(self.prev_metrics.log_scale_q24 as i64, 4, cur_pos);
1307-
debug_assert!(cur_pos == TWOPASS_PACKET_SZ);
1348+
self.emit_frame_data()
13081349
}
1309-
self.pass1_data_retrieved = true;
13101350
} else if params.done_processing && !self.pass1_summary_retrieved {
1311-
cur_pos = self.buffer_val(TWOPASS_MAGIC as i64, 4, cur_pos);
1312-
cur_pos = self.buffer_val(TWOPASS_VERSION as i64, 4, cur_pos);
1313-
cur_pos = self.buffer_val(self.ntus as i64, 4, cur_pos);
1314-
for fti in 0..=FRAME_NSUBTYPES {
1315-
cur_pos = self.buffer_val(self.nframes[fti] as i64, 4, cur_pos);
1316-
}
1317-
for fti in 0..FRAME_NSUBTYPES {
1318-
cur_pos = self.buffer_val(self.exp[fti] as i64, 1, cur_pos);
1319-
}
1320-
for fti in 0..FRAME_NSUBTYPES {
1321-
cur_pos = self.buffer_val(self.scale_sum[fti], 8, cur_pos);
1322-
}
1323-
debug_assert!(cur_pos == TWOPASS_HEADER_SZ);
1324-
self.pass1_summary_retrieved = true;
1351+
Some(self.emit_summary())
13251352
} else {
13261353
// The data for this frame has already been retrieved.
1327-
return None;
1354+
None
13281355
}
1329-
Some(&self.pass1_buffer[..cur_pos])
13301356
}
13311357

13321358
fn buffer_fill(

0 commit comments

Comments
 (0)