mirror of
https://github.com/freemkv/libfreemkv.git
synced 2026-10-07 18:13:10 +00:00
Security - Remove the unsafe Vec::set_len over recycled sector buffers — UB reachable from safe code (GHSA-j8ww-f5fg-9pmh, low). Uses Vec::resize; pooling unchanged. CI / tooling - clippy on stable with the MSRV single-sourced from Cargo.toml; cargo-deny dependency-audit gate with first-party git sources allowed (#15); audience-based comment-guard (#17). Docs - README (keydb ownership, BD-J parser count), drive-access transport/reset notes, mux timeline module-doc links.
96 lines
4.9 KiB
Markdown
96 lines
4.9 KiB
Markdown
# `src/labels/mpls_universal.rs`
|
|
|
|
Universal MPLS-based stream labels — the confidence-tier "floor" for the
|
|
`labels` registry.
|
|
|
|
## Why this module exists
|
|
|
|
Unlike the framework-specific parsers in `src/labels/` (dbp, pixelogic, ctrm,
|
|
criterion, ...), this module is the floor: every Blu-ray ships with MPLS
|
|
playlists under `/BDMV/PLAYLIST/`, and every MPLS file has an STN table with
|
|
per-stream ISO 639-2 language codes plus coding-type / channel-layout /
|
|
sample-rate bytes from the BD spec.
|
|
|
|
The framework parsers extract richer editorial labels ("English Dolby Atmos",
|
|
"Director's Commentary") when the disc was authored with a recognized tool.
|
|
When none of them match (e.g. a "no BD-J" disc, or an authoring framework we
|
|
haven't catalogued), MPLS still gives us language + codec on every stream —
|
|
enough to render something more useful than the bare PID.
|
|
|
|
Output confidence is Low: MPLS carries language + codec but never
|
|
purpose/qualifier info (no way to tell "Commentary" from "Normal" from the STN
|
|
table alone). Higher-confidence framework parsers, when present, always win on
|
|
the registry's max-by-confidence tiebreaker — MPLS is only chosen when nothing
|
|
else matched.
|
|
|
|
## `build_labels`
|
|
|
|
Converts every stream entry across `playlists` into one `StreamLabel` per
|
|
physical stream. Factored out of `parse` so unit tests can drive the actual
|
|
conversion logic (stream-type mapping, identity, slot numbering) directly from
|
|
already-parsed `crate::mpls::Playlist` values, without needing a synthetic
|
|
on-disc UDF image.
|
|
|
|
Identity is `(clip, PID)` — what the STN entry states — and it is both the
|
|
dedup key and the label's `StreamId`. A stream twenty playlists list is one
|
|
label; two clips that both open their first audio at 0x1100 are two. This
|
|
replaced a disc-global dense counter that numbered surviving entries 1, 2, 3,
|
|
… in playlist-directory order: that number was not an STN slot in anything,
|
|
but it was handed to a binder that reads `stream_number` as one.
|
|
|
|
## `label_type_for`
|
|
|
|
Which per-type numbering list an STN entry belongs to, or `None` when it is
|
|
not a labellable stream at all.
|
|
|
|
This MUST agree with the stream list `disc::bluray` builds from the same
|
|
entries, because that list is what `labels::apply_labels` counts against when
|
|
it binds `stream_number`. The two counters run over the same STN entries in
|
|
the same order, so any entry one side keeps and the other drops — or files
|
|
under a different type — shifts every later label of that type onto the wrong
|
|
stream. Three rules, all mirroring `disc::bluray`:
|
|
|
|
* `coding_type == 0` is the STN table's empty/padding slot. Not a stream on
|
|
either side.
|
|
* a PG coding_type in an audio STN slot is a subtitle, not audio.
|
|
`mpls::parse_stream_entry` has a dedicated arm for this layout, so it is an
|
|
authored shape rather than a corruption.
|
|
* video (1 / 6 / 7 = primary, secondary, Dolby Vision EL) and IG (4) have no
|
|
`StreamLabelType`; they are numbered in their own STN lists and never
|
|
interleave with the audio or PG lists.
|
|
|
|
## Test helpers and fixtures
|
|
|
|
`playlist_with`: a playlist over clip "00001". `Playlist::streams` is read out
|
|
of the first play item's STN table, so a playlist that has streams always has
|
|
a play item to have read them from — the fixture carries one so tests exercise
|
|
the shape production sees, and so each label gets the `(clip, PID)` identity
|
|
it is bound by.
|
|
|
|
`labels_from_playlists`: drives the actual production conversion logic
|
|
(`build_labels`, the function `parse()` calls) starting from already-parsed
|
|
Playlists, so tests don't have to synthesize valid on-disc MPLS/UDF bytes.
|
|
This calls the *real* code under test rather than a hand-written
|
|
re-implementation, so mutations inside `build_labels` (stream-type mapping,
|
|
dedup key, counters) are actually caught here.
|
|
|
|
`padding_stn_entry_does_not_consume_a_label_slot`: `stream_number` is bound by
|
|
`labels::apply_labels` against the title's own stream list, which
|
|
`disc::bluray` builds from these same STN entries. That builder DROPS an entry
|
|
whose `coding_type` is 0 — the STN table's empty/padding slot — so it must not
|
|
be counted here either. Counting it advances the audio counter past a stream
|
|
that never materializes, and every label behind it binds one stream late.
|
|
|
|
`pg_coding_type_in_an_audio_slot_counts_as_a_subtitle`: a PG coding_type
|
|
sitting in an audio STN slot is a real, documented shape —
|
|
`mpls::parse_stream_entry` has an explicit arm for it, and `disc::bluray`
|
|
builds it as a Subtitle stream, not an Audio one. This module must classify it
|
|
the same way, or the audio counter runs one ahead and the subtitle counter one
|
|
behind for every later stream.
|
|
|
|
`same_pid_in_two_clips_is_two_streams`: the same PID in two DIFFERENT clips is
|
|
two different streams — a PID is only unique within one clip. Deduping on the
|
|
PID alone (as the old key's `(type, language, codec_hint, pid)` did across
|
|
clips) collapses them into one label, and the second clip's stream is then
|
|
described by the first clip's.
|