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.
60 lines
3.1 KiB
Markdown
60 lines
3.1 KiB
Markdown
# 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.
|