From 3d7974dbce0c010f9951e0bebc45abeb9da2a334 Mon Sep 17 00:00:00 2001 From: EthanRosenthal Date: Sun, 4 Oct 2026 22:20:37 +0000 Subject: [PATCH] Encode the B-frame end_time test clip with explicit B-frames test_decode_end_time_with_b_frames relied on libx264's default GOP having B-frames. Add a b_frames option to TestVideoParameters (-bf N, plus b-adapt=0 for libx264 so the pattern is fixed rather than adaptive) and request 3 B-frames in that test, so it keeps exercising out-of-order packets if encoder defaults change. --- src/decoder/mod.rs | 11 +++++++---- src/util/test_utils.rs | 12 ++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 6bf5ad8..d1c4f4d 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -5262,9 +5262,9 @@ mod tests { Ok(()) } - /// libx264 emits B-frames, so packets past the end of the window precede - /// in-window frames in decode order. The window must hold exactly the - /// frames with start <= pts < end, contiguous. + /// With B-frames, packets past the end of the window precede in-window + /// frames in decode order. The window must hold exactly the frames with + /// start <= pts < end, contiguous. #[test_case(None, 1.7, 51 ; "end only")] #[test_case(Some(0.5), 1.7, 36 ; "start and end")] fn test_decode_end_time_with_b_frames( @@ -5273,7 +5273,10 @@ mod tests { expected_frames: usize, ) -> anyhow::Result<()> { init_logger(); - let params = TestVideoParameters::default(); + let params = TestVideoParameters { + b_frames: Some(3), + ..Default::default() + }; let file = generate_test_video_file(¶ms)?; let decoded = decode_media( MediaDecodeRequest { diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index 73627de..720b7c2 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -23,6 +23,9 @@ pub struct TestVideoParameters { pub color_trc: Option, /// FFmpeg color range tag (e.g. "tv", "pc"). pub color_range: Option, + /// Number of consecutive B-frames between reference frames. None keeps the + /// encoder default; set it when a test depends on B-frames being present. + pub b_frames: Option, } impl Default for TestVideoParameters { @@ -41,6 +44,7 @@ impl Default for TestVideoParameters { color_primaries: None, color_trc: None, color_range: None, + b_frames: None, } } } @@ -129,6 +133,9 @@ pub fn generate_test_video( if let Some(ref cr) = parameters.color_range { cmd.args(["-color_range", cr]); } + if let Some(b_frames) = parameters.b_frames { + cmd.args(["-bf", &b_frames.to_string()]); + } // libx264 does not propagate ffmpeg's -color_primaries/-color_trc flags // into the bitstream VUI (decoders would see them as "unknown"), so write @@ -144,6 +151,11 @@ pub fn generate_test_video( if let Some(ref ct) = parameters.color_trc { x264_params.push(format!("transfer={ct}")); } + // -bf only caps the B-frame run; with adaptive placement libx264 can + // still choose fewer (or none) per GOP. Pin the pattern. + if parameters.b_frames.is_some() { + x264_params.push("b-adapt=0".to_string()); + } if !x264_params.is_empty() { cmd.args(["-x264-params", &x264_params.join(":")]); }