Files
libfreemkv/docs/pesbuf.md
T
Matthew Jackson 6e14fc0c0c libfreemkv: 1.7.0 groundwork — sector-recycle soundness + CI hardening
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.
2026-09-02 12:40:55 -07:00

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.