test: salvage the orphaned labels/disc triage, and extract build_labels
Thirteen agents triaging src/labels and src/disc died on a saturated
machine, leaving 5,836 insertions across 28 files uncommitted in a
worktree. Recovered by 3-way apply onto twelve commits of drift; zero
conflicts. The diff was archived to freemkv-private first, because a
worktree is not a backup and this one had already nearly been lost.
One production change, and it is the right one: mpls_universal::parse
read every playlist off the disc AND converted the entries to labels in
a single function, so the conversion — stream-type mapping, dedup key,
the dense global counters — could only be reached through a synthetic
UDF image. Extracted to build_labels(&[Playlist]), which unit tests can
drive from already-parsed values. Behaviour-preserving: same iteration
order, same skip-on-error.
Two collisions resolved by hand:
A second mod pass_progress_tests, written independently against the
same survivors as the one committed in c610285. Kept mine — it covers
the distinct-counters case and the Progress blanket impl, which theirs
does not — but theirs had three clamp tests mine lacked: good_pct,
bad_pct and pending_pct also clamp an overshoot, and I had only tested
that for work_pct. Merged those in as one test and proved each of the
three clamps load-bearing by removing them individually.
An unused_parens warning in a new fixture.
Method note, recorded because it cost real time: git apply --3way
STAGES its result, so `git diff` reads empty and the tree looks
untouched. I nearly concluded the patch had silently failed. Worse, the
first attempt piped through `head -20`, so `echo exit=$?` reported
head's status rather than git's — the same mistake this audit has
already documented once. Check the real exit status, and check
--cached, not just the working tree.
This commit is contained in:
@@ -1320,4 +1320,51 @@ mod tests {
|
||||
// Chapter 0 stays at 0.0 (no shift).
|
||||
assert!((t.chapters[0].time_secs - 0.0).abs() < 0.01);
|
||||
}
|
||||
|
||||
/// Audio PID fallback (dvd.rs `Disc::scan_dvd_titles`): when an audio
|
||||
/// stream has no on-wire private_stream_1 sub-stream id — MP1/MP2 audio,
|
||||
/// per `ifo::assign_audio_sub_stream_ids` — the PID falls back to
|
||||
/// `0xBD00 + i` where `i` is the stream's positional index in the IFO
|
||||
/// audio-attribute table. Two MPEG-audio (coding_mode 2) streams must
|
||||
/// land on two DISTINCT, correctly-offset PIDs: 0xBD00 and 0xBD01. This
|
||||
/// pins the `+` (not `-`/`*`) so the second stream doesn't collide with,
|
||||
/// or wrap under, the first.
|
||||
#[test]
|
||||
fn scan_dvd_titles_mp2_audio_pid_fallback_is_additive() {
|
||||
let mut disc = MemDisc::new();
|
||||
let vmg = build_vmg(&[(1, 1, 1)]);
|
||||
// coding_mode bits are b0>>5 & 0x7; mode 2 = MPEG-1 Layer II (Mp2),
|
||||
// which `assign_audio_sub_stream_ids` leaves at `sub_stream_id: None`.
|
||||
// b0 = 0b010_00000 = 0x40. b1 = 0 (mono, sample rate 48k).
|
||||
let audio = [(0x40u8, 0x00u8, [0u8, 0u8]), (0x40u8, 0x00u8, [0u8, 0u8])];
|
||||
let vts = build_vts(1000, 0x00, &audio, &[], &[(10, 109)], false);
|
||||
let udf = build_video_ts_fs(
|
||||
&mut disc,
|
||||
&[
|
||||
FileSpec {
|
||||
name: "VIDEO_TS.IFO".into(),
|
||||
icb_lba: 60,
|
||||
data_lba: 5000,
|
||||
contents: vmg,
|
||||
},
|
||||
FileSpec {
|
||||
name: "VTS_01_0.IFO".into(),
|
||||
icb_lba: 62,
|
||||
data_lba: 6000,
|
||||
contents: vts,
|
||||
},
|
||||
],
|
||||
);
|
||||
let titles = Disc::scan_dvd_titles(&mut disc, &udf);
|
||||
let t = &titles[0];
|
||||
let audio_pids: Vec<u16> = t
|
||||
.streams
|
||||
.iter()
|
||||
.filter_map(|s| match s {
|
||||
Stream::Audio(a) => Some(a.pid),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
assert_eq!(audio_pids, vec![0xBD00u16, 0xBD01u16]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user