tests: second video track does not drive timeline epochs in mkv and demux sinks

This commit is contained in:
Matthew Jackson
2026-09-29 20:38:09 -07:00
parent d1ba39c424
commit ebd23bce47
2 changed files with 68 additions and 0 deletions
+38
View File
@@ -1800,6 +1800,44 @@ mod tests {
let _ = std::fs::remove_dir_all(&dir);
}
// A second video track (Dolby Vision EL) rides the base layer's epoch: its
// old-clip straggler after a seam must not open a spurious epoch.
#[test]
fn second_video_track_does_not_drive_epochs() {
let dir = tempdir();
let title = title_with(
vec![video_stream(Codec::H264), video_stream(Codec::H264)],
vec![None, None],
);
let mut sink = DemuxSink::create(&dir, &title, &DemuxOptions::default()).unwrap();
let fr = |track: usize, pts: i64| PesFrame {
discard_padding_ns: 0,
coding: None,
source: None,
track,
pts,
keyframe: true,
data: vec![0x00, 0x00, 0x00, 0x01, 0xAA],
duration_ns: None,
};
let s = 1_000_000_000i64;
for f in [fr(0, 0), fr(1, 0), fr(0, 600 * s), fr(1, 600 * s), fr(0, 0)] {
sink.write(&f).unwrap();
}
let seam = sink.timeline.offset_ns;
assert!(seam >= 600 * s, "base layer reset opens the epoch");
// Clip 1's EL tail, EL at the new clip's start, then BL continues.
for f in [fr(1, 599 * s + s / 2), fr(1, 0), fr(0, 5 * s)] {
sink.write(&f).unwrap();
}
assert_eq!(
sink.timeline.offset_ns, seam,
"the EL straggler must not open another epoch"
);
sink.finish().unwrap();
let _ = std::fs::remove_dir_all(&dir);
}
// ── End-to-end sink ──────────────────────────────────────────────────────
#[test]
+30
View File
@@ -3209,6 +3209,36 @@ mod tests {
);
}
// A Dolby Vision EL (second video track) must not drive epochs: its old-clip
// straggler after a seam would advance the frontier and open a spurious epoch.
#[test]
fn dv_enhancement_layer_straggler_does_not_open_a_spurious_epoch() {
let tracks = [make_video_track(), make_video_track()];
let ms = |m: i64| m * 1_000_000;
let frames: Vec<(usize, i64, bool, Vec<u8>)> = vec![
(0, ms(0), true, vec![0x01; 16]),
(1, ms(0), true, vec![0xB0; 8]),
(0, ms(600_000), true, vec![0x02; 16]),
(1, ms(600_000), true, vec![0xB1; 8]),
// Clip 2: BL resets to 0, then clip 1's EL tail straggles in.
(0, ms(0), true, vec![0x03; 16]),
(1, ms(599_500), true, vec![0xB2; 8]),
(1, ms(0), true, vec![0xB3; 8]),
(0, ms(5_000), true, vec![0x04; 16]),
];
let (data, frame_count) = mux_to_bytes(&tracks, &[], &frames);
assert_eq!(frame_count, 8, "all frames written (none dropped)");
let tick = |ms: i64| ms * 1_000_000 / TIMESTAMP_SCALE_NS;
let ts: Vec<u64> = find_clusters(&data).iter().map(|&(_, _, t)| t).collect();
assert!(ts.windows(2).all(|w| w[1] >= w[0]), "monotonic, got {ts:?}");
let max = *ts.iter().max().unwrap() as i64;
assert!(max >= tick(600_000), "timeline spans the seam, got {max}");
assert!(
max < tick(1_000_000),
"EL straggler must not ratchet the timeline, got {max} ticks"
);
}
#[test]
fn mkv_multiple_tracks() {
let buf = Cursor::new(Vec::new());