libfreemkv: rc.5.2 DVD test coverage — depth-aware mux, colour codes, CSS scan
Implements the rc.5.2 quick-units list from the DVD coverage audit and corrects the "passes-but-encodes-the-bug" tests that could not distinguish correct from wrong behaviour. New tests (each with the bug it guards): mux/mkv.rs - field_duration_is_direct_trackentry_child_not_in_video: depth-aware check that DefaultDecodedFieldDuration (and DefaultDuration) are direct TrackEntry children, NOT nested in the Video master. Replaces the flat find_id byte-scan that passed either way. Adds master_children / first_track_entry depth-walking helpers. - pal_576i_emits_bt470bg_colour_codes / ntsc_480i_emits_smpte170m_colour_codes: assert the actual CICP tuples written into the MKV Colour master — PAL (5,5,5,1) vs NTSC (6,6,6,1) — not just stream-layer ColorSpace. - ntsc_480i_field_order_is_tff_and_encoded: pins NTSC 480i hardcoded TFF and its ~33.37ms/16.68ms frame/field durations, asserting the encoded FlagInterlaced/FieldOrder bytes (480i was never exercised before). ifo.rs - video_attr_absolute_bytes_pin_real_layout: drives parse_video_attr with HARDCODED real DVD-Video bytes (PAL/NTSC x 4:3/16:9, plus mpeg_version in bits 7-6) instead of v_atr_byte, so a co-edit of the shift constants can't re-seed the PAL-as-NTSC bug. Anchors that permitted_df bits (1-0) are not read as the TV system. disc/dvd.rs - scan_dvd_titles_lpcm_routes_to_a0_pid_range: LPCM (coding 4) → sub-id 0xA0 → PID 0xBDA0, disjoint from the AC-3 0xBD8x space, channels kept. - scan_dvd_titles_multiple_vobsub_tracks_distinct_pids: three VobSub tracks → distinct 0x20+ordinal PIDs, per-language, shared palette. css/mod.rs - crack_outcome_reaches_cracked_with_span: drives the full crack scan to CrackOutcome::Cracked via a Stevenson-crackable synthetic sector and asserts crack_span recording (the Cracked branch was never exercised). - recrack_succeeds_on_other_vts_extents: per-VTS re-crack SUCCESS path. - all_locked_synthetic_iso_yields_css_key_missing_signal: all-locked multi-extent ISO → ScrambledUncracked, the signal the scan converts to css_error = Some(CssKeyMissing). Corrected fixtures (passes-but-encodes-the-bug): - scan_dvd_titles_mixed_audio_codecs_distinct_pids: real channel nibbles (AC-3 5.1 = 6ch, DTS 2.0 = 2ch) replacing the 1ch placeholders; asserts channel counts and exact canonical PIDs (0xBD80 / 0xBD88). - ebml.rs FieldOrder comment: drop the stale "PAL DVD (576i) is bottom-field-first" line that contradicted the TFF-for-all code.
This commit is contained in:
+48
@@ -1056,6 +1056,54 @@ mod tests {
|
||||
assert_eq!(attr.resolution, Resolution::R576i);
|
||||
}
|
||||
|
||||
/// ABSOLUTE-BYTE pin (audit §3 #2): the existing video-attr tests build the
|
||||
/// byte via `v_atr_byte(...)`, which uses the SAME shift constants the parser
|
||||
/// reads with — a co-edit of constant + helper would silently re-introduce
|
||||
/// the PAL-as-NTSC bug and every test would still pass. This test feeds
|
||||
/// `parse_video_attr` HARDCODED bytes captured from real DVD-Video layouts
|
||||
/// (DVD spec / libdvdread `video_attr_t`: mpeg_version[7-6] video_format[5-4]
|
||||
/// display_aspect[3-2] permitted_df[1-0]) — no `v_atr_byte`. If the parser's
|
||||
/// bit positions drift, these fail.
|
||||
#[test]
|
||||
fn video_attr_absolute_bytes_pin_real_layout() {
|
||||
// (byte @0x200, expected standard, expected aspect, expected resolution).
|
||||
// PAL 16:9 anamorphic = mpeg(00) format(01=PAL) aspect(11=16:9) df(00)
|
||||
// = 0b0001_1100 = 0x1C (e.g. a PAL 16:9 R2 feature disc).
|
||||
// PAL 4:3 = 0b0001_0000 = 0x10.
|
||||
// NTSC 16:9 = 0b0000_1100 = 0x0C.
|
||||
// NTSC 4:3 = 0b0000_0000 = 0x00.
|
||||
// A real disc also sets mpeg_version=01 (MPEG-2) in bits 7-6, which the
|
||||
// parser must IGNORE; OR it in (|0x40) to prove it doesn't leak into the
|
||||
// video_format read.
|
||||
let cases: &[(u8, TvSystem, DvdAspect, Resolution)] = &[
|
||||
(0x1C, TvSystem::Pal, DvdAspect::R16x9, Resolution::R576i),
|
||||
(0x10, TvSystem::Pal, DvdAspect::R4x3, Resolution::R576i),
|
||||
(0x0C, TvSystem::Ntsc, DvdAspect::R16x9, Resolution::R480i),
|
||||
(0x00, TvSystem::Ntsc, DvdAspect::R4x3, Resolution::R480i),
|
||||
// mpeg_version=2 (MPEG-2) in bits 7-6 must not perturb the read.
|
||||
(0x5C, TvSystem::Pal, DvdAspect::R16x9, Resolution::R576i),
|
||||
];
|
||||
for &(b0, std, aspect, res) in cases {
|
||||
let mut data = vec![0u8; 0x204];
|
||||
data[0x200] = b0;
|
||||
let attr = parse_video_attr(&data).unwrap();
|
||||
assert_eq!(attr.standard, std, "byte {b0:#04x} → standard");
|
||||
assert_eq!(attr.aspect, aspect, "byte {b0:#04x} → aspect");
|
||||
assert_eq!(attr.resolution, res, "byte {b0:#04x} → resolution");
|
||||
}
|
||||
// Anti-bug anchor: the original bug read the TV system from bits 1-0
|
||||
// (permitted_df). A PAL byte whose low 2 bits are 0 (0x1C) must NOT be
|
||||
// misread as NTSC — and a byte with low bits set but format=NTSC
|
||||
// (0x03 = NTSC, df=11) must stay NTSC, proving the low bits are ignored.
|
||||
let mut df = vec![0u8; 0x204];
|
||||
df[0x200] = 0x03; // format=NTSC(00), df=11
|
||||
assert_eq!(
|
||||
parse_video_attr(&df).unwrap().standard,
|
||||
TvSystem::Ntsc,
|
||||
"permitted_df bits (1-0) must NOT be read as the TV system"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn audio_attr_parsing() {
|
||||
let mut data = vec![0u8; 16];
|
||||
|
||||
Reference in New Issue
Block a user