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.
5.0 KiB
TrueHD codec parser — extended notes
is_truehd_major_sync — why 0xBA must be exact
The 32-bit word that FOLLOWS the sync is laid out per stream type: TrueHD's
format_info carries [31..28] audio_sampling_frequency, the 5-bit 6-channel
and 13-bit 8-channel presentation channel-assignment masks; MLP's (0xBB) same
word carries quantization word lengths and the MLP group sample-rate fields
instead. So every site that decodes format_info with the TrueHD layout must
require 0xBA exactly — masking the low sync bit there read a quantization code
as the rate nibble and pulled channel masks out of unrelated bits, giving the
track header a wrong SamplingFrequency and truehd_au_duration_ns a wrong
per-AU increment (audio drifting against video for the whole track).
None from these helpers is the safe outcome: the caller falls back to its
container-derived rate/channel count.
truehd_sample_rate_hz — rate formula and rationale
The MLP rate formula is (ratebits & 8 ? 44100 : 48000) << (ratebits & 7);
rather than evaluate it blindly, truehd_sample_rate_hz is a strict
whitelist of the only six rates that occur on real BD/UHD TrueHD. Every
other code — the invalid 0xF, the formula-only 0x3/0xB, and all
reserved values — returns None.
au_check — corruption decision
Decide whether an access unit is corrupt, updating num_substreams from a
valid major sync. Per the MLP/TrueHD access-unit decode rules: a major sync
with a bad header CRC, or any AU whose header parity fails, is undecodable.
Returns false (not corrupt) when the AU is too short to judge or no
major sync has established num_substreams yet — we never drop what we
cannot verify. Verified against real TrueHD streams (3600/3600 AUs).
ac3_frame_at_head — AC-3 size lookup
Size (bytes) of the AC-3 frame at the buffer head. Distinguishes three cases the caller must treat differently:
Unmappable: the header's fscod/frmsizecod don't map to a real frame size (reserved fscod==3, or frmsizecod >= 38). The caller must drain and resync, NOT wait for more data — waiting would stall forever.NeedMore: a valid size, but the frame isn't fully buffered yet.Frame(n): a completen-byte AC-3 frame is buffered.
Frame sizing reuses ac3::ac3_frame_size so the AC-3 size table has a
single source of truth shared with the AC-3 parser; a returned 0 there
(reserved fscod or out-of-range frmsizecod) is the unmappable case.
ac3_boundary_corroborated
Secondary validation for an AC-3 frame of frame_bytes at the buffer head:
is its computed end a plausible boundary? Accept when the frame fills the
rest of the buffer, or the bytes that follow start another AC-3 sync
(0x0B77) or a plausible TrueHD access unit (non-zero 12-bit length within
the 32 KiB cap). If none holds, the leading 0x0B77 is more likely a TrueHD
AU header that happens to look like AC-3, so the AC-3 reading is rejected.
mlp_major_sync_header_size
Major-sync header size in bytes: base 28, plus 2 + extensions*2 when the
extension flag (major-sync byte 25, bit 0) is set (extensions = byte 26
high nibble). ms is the major-sync header, i.e. AU bytes [4..]. None
when the AU is too short to contain the full header.
mlp_major_sync_crc_ok
Validate the MLP/TrueHD major-sync header checksum (a CRC-16 with polynomial 0x002D). The stored trailer is the last 2 header bytes; because MLP's checksum is byte-reversed relative to a standard CRC, a standard CRC of the header body XOR the little-endian word before the trailer must equal the trailer read LITTLE-endian. (Comparing it big-endian was the bug this function was fixed for; the body and the inline note are authoritative.)
mlp_substr_header_size — test rationale
The substream count and the substream-directory size are the two numbers
that position mlp_parity_ok's check window over the AU header. Every
other fixture in this module uses the degenerate shape — one substream,
no extraword — so neither function's real behaviour was ever exercised:
a constant answer agreed with all of them, and would then mis-window the
parity check on the multi-substream AUs that carry 7.1 and Atmos, judging
clean audio corrupt (or corrupt audio clean).
ref_crc16_2d test oracle
Independent bitwise CRC-16 (poly 0x002D, init 0, MSB-first) — a separate
oracle from crc16_mlp, so a fixture built with it is not tautological
with the validator under test. Anchored to the catalogue check value
(0x4FF7 for "123456789") so the oracle itself is proven correct without
reference to the code under test.
finalize_major_sync test helper
Turn a synthetic major-sync AU (sync bytes already set at offset 4, any
format_info set) into one that passes the decodability gate: 1 substream,
a clean substream directory, a valid major-sync CRC-16, and a valid header
parity nibble. Mirrors what a real encoder writes (verified against real
TrueHD streams). The AU must be ≥ 36 bytes (4 AU header + 28 major-sync
header + 2 directory + slack), which every make_truehd_unit(≥200) is.