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.
3.1 KiB
pesbuf: one accumulation buffer for parsers that assemble access units across PES packets
A buffering parser has to answer the same question for every unit it emits: which PES contributed this unit's FIRST byte? Its timestamp comes from that PES, and so does the source byte offset that identifies which clip of a multi-clip title the unit belongs to. The trailing PES packets that complete the unit carry their own, later, values which must not override it.
That question was answered three different ways. DTS kept a deque of
(offset, pts) markers and took the one covering offset 0 — correct. AC-3
kept a single carry-over timestamp. TrueHD kept its own. None of them
carried the source offset at all, so provenance existed only for video, and
a title whose clip marks could not be read from timestamps alone had nine
audio and subtitle tracks with nothing to place them by.
Three spellings of one rule is how they drifted, so this is the one place it lives. The buffer owns the bytes AND the marks, and returns a PES's facts together — a parser cannot take the timestamp from one PES and the source from another, because it does not assemble them itself.
PesFacts
Returned as a unit so a caller cannot mix fields from different packets.
The timestamps are carried RAW, as the packet had them. This type answers
which packet a unit's facts come from — the question that was being
answered three different ways. How a given codec derives a timestamp from
that packet stays the codec's business: DVD subtitles read pts only and
fall back to 0, most audio takes pts.or(dts). Deriving it here would have
changed those semantics silently while fixing provenance.
PesFacts::of
Every parser reads its frame's timestamp, source and discontinuity from
a PesFacts — never off a PesPacket field directly — so the three can
never be taken from different packets. Parsers that assemble units
across packets get theirs from PesBuf::front; this is the same value
for a parser whose unit begins in the packet it is handed.
PesFacts::presentation_ns
PTS and DTS are not two spellings of one value: PTS is when to display, DTS is when to decode, and for a stream that REORDERS (video carrying B-frames) they differ, so reading DTS as a presentation time would be wrong. Reordering is handled by the video path, which reconstructs display order rather than calling this.
For everything that reaches here — audio and subtitles — there is no
reordering, so DTS is the presentation time, and falling back to it is
reading the same value from whichever field the packet used. A fallback
for a missing field, not a second rule: dvdsub read pts alone and
returned 0 for a packet that carried only DTS.
PesBuf::drain
The mark covering the new front byte is RETAINED at offset 0 even though its packet started earlier: those bytes are still that packet's. Dropping it would attribute the remainder of a straddling unit to whichever packet happened to start next — precisely the misattribution this type exists to prevent, and it would land at a clip boundary, the one place it matters.