labels/mpls_universal: dense stream numbering across playlists
Per-playlist stream_number counters were resetting between MPLS files, so a disc with 2 MPLS files each listing the same 8 audio streams produced labels with stream_number 1..8 then 1..8 again (dedup kept whichever PID was different, leaving the numbering visibly broken — multiple "audio1: eng" rows). Move the counters outside the per-file loop and increment only when an entry survives dedup. Surviving entries now get dense 1..N numbering across the whole disc per stream_type. Verified on corpus disc-02 (HDMV-only): was `audio1, audio1, audio1` for the 3 distinct audio codecs (TrueHD/AC-3/DTS-HD MA), now `audio1, audio2, audio3`. Same fix applies to disc-01 (12 audio streams across multiple MPLS) and disc-09 (14 audio streams).
This commit is contained in:
@@ -68,6 +68,15 @@ pub fn parse(reader: &mut dyn SectorReader, udf: &UdfFs) -> Option<ParseResult>
|
||||
// to share a PID across playlists with different metadata.
|
||||
let mut seen: Vec<(u8, String, String, u16)> = Vec::new();
|
||||
|
||||
// Global 1-based counters keyed by StreamLabelType. Incremented
|
||||
// only when an entry survives dedup, so stream_numbers are dense
|
||||
// (1, 2, 3, ...) per type across the whole disc — not reset per
|
||||
// playlist. A disc with 2 MPLS files that each list the same
|
||||
// 8 audio streams ends up with audio_1..audio_8, not audio_1..
|
||||
// audio_16 or audio_1..audio_8 with audio_1 duplicated.
|
||||
let mut audio_idx: u16 = 0;
|
||||
let mut sub_idx: u16 = 0;
|
||||
|
||||
for name in &mpls_names {
|
||||
let path = format!("/BDMV/PLAYLIST/{}", name);
|
||||
let Ok(data) = udf.read_file(reader, &path) else {
|
||||
@@ -77,13 +86,6 @@ pub fn parse(reader: &mut dyn SectorReader, udf: &UdfFs) -> Option<ParseResult>
|
||||
continue;
|
||||
};
|
||||
|
||||
// Per-MPLS-file 1-based counters keyed by StreamLabelType.
|
||||
// The dedup pass below removes duplicates across files; the
|
||||
// numbering of the *surviving* entries comes from whichever
|
||||
// playlist contributed each PID first.
|
||||
let mut audio_idx: u16 = 0;
|
||||
let mut sub_idx: u16 = 0;
|
||||
|
||||
for entry in &playlist.streams {
|
||||
let label_type = match entry.stream_type {
|
||||
2 | 5 => StreamLabelType::Audio, // primary + secondary audio
|
||||
@@ -95,17 +97,6 @@ pub fn parse(reader: &mut dyn SectorReader, udf: &UdfFs) -> Option<ParseResult>
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
let stream_number = match label_type {
|
||||
StreamLabelType::Audio => {
|
||||
audio_idx += 1;
|
||||
audio_idx
|
||||
}
|
||||
StreamLabelType::Subtitle => {
|
||||
sub_idx += 1;
|
||||
sub_idx
|
||||
}
|
||||
};
|
||||
|
||||
let language = normalize_language(&entry.language);
|
||||
let name = language_display_name(&language);
|
||||
let codec_hint = build_codec_hint(label_type, entry);
|
||||
@@ -117,6 +108,17 @@ pub fn parse(reader: &mut dyn SectorReader, udf: &UdfFs) -> Option<ParseResult>
|
||||
}
|
||||
seen.push(key);
|
||||
|
||||
let stream_number = match label_type {
|
||||
StreamLabelType::Audio => {
|
||||
audio_idx += 1;
|
||||
audio_idx
|
||||
}
|
||||
StreamLabelType::Subtitle => {
|
||||
sub_idx += 1;
|
||||
sub_idx
|
||||
}
|
||||
};
|
||||
|
||||
labels.push(StreamLabel {
|
||||
stream_number,
|
||||
stream_type: label_type,
|
||||
|
||||
Reference in New Issue
Block a user