Remove reference-decoder citations from a public MIT-licensed repo

This crate is MIT licensed. Comments citing another decoder's internal symbols
and reproducing its tables verbatim create licence risk that no engineering
benefit justifies, so every such citation is replaced with the primary source:
ETSI TS 102 114 §5.3.1.

Eleven sites across src/mux/codec/dts.rs and src/mux/mp4/audio.rs. The technical
substance is unchanged in every case — the deficit-sample-count semantics, the
reserved-field skips, the invalid LFF value, and the 16 legal AMODE codes are all
spec facts and are now attributed as such. Four CHANGELOG entries that named a
validator are reworded; the "no a reference decoder" dependency claim stays, since stating
what this project does NOT depend on carries no risk.

I initially argued this was a false positive on the grounds that the project's
hygiene rules name internal infrastructure and reverse-engineering material, not
open-source citations, and that a channel-count table from a standard is fact
rather than expression. That reasoning missed the point: the exposure is MIT
distributing text derived from GPL/LGPL sources, and that is the maintainer's
risk to weigh, not mine. Reversed in full.
This commit is contained in:
Matthew Jackson
2026-07-29 19:09:10 -07:00
parent 22a3e3fd01
commit 50f37462db
3 changed files with 15 additions and 15 deletions
+4 -4
View File
@@ -524,7 +524,7 @@
Program Stream packs several DTS core frames into one PES packet; the parser Program Stream packs several DTS core frames into one PES packet; the parser
stamped every access unit with that single PES timestamp and no per-frame stamped every access unit with that single PES timestamp and no per-frame
duration, so consecutive frames collided on one PTS and a strict decode/remux duration, so consecutive frames collided on one PTS and a strict decode/remux
(ffmpeg) rejected the track — `non monotonically increasing dts to muxer`. a standard validator rejected the track — `non monotonically increasing dts to muxer`.
The DTS parser now derives each core frame's duration from its header The DTS parser now derives each core frame's duration from its header
(`(NBLKS+1)*32` samples ÷ the `SFREQ` sample rate) and re-bases to each PES's (`(NBLKS+1)*32` samples ÷ the `SFREQ` sample rate) and re-bases to each PES's
own container timestamp, advancing by a frame duration only *within* a single own container timestamp, advancing by a frame duration only *within* a single
@@ -611,7 +611,7 @@ consumers are the in-tree toolchain crates.
frame. The undecryptable aligned unit is concealed as NULL transport-stream frame. The undecryptable aligned unit is concealed as NULL transport-stream
packets (PID 0x1FFF, invisible to every real stream), and the codec layer packets (PID 0x1FFF, invisible to every real stream), and the codec layer
**drops forward to the next keyframe** so no frame with a dangling reference **drops forward to the next keyframe** so no frame with a dangling reference
reaches the muxer. An ffmpeg deep scan of the result is clean — no missing reaches the muxer. A deep validator scan of the result is clean — no missing
references, no partial frames. The loss is tallied and logged, never silently references, no partial frames. The loss is tallied and logged, never silently
dropped, and the mux always completes. Audio and subtitle tracks have no dropped, and the mux always completes. Audio and subtitle tracks have no
cross-frame references, so only the directly-affected frames are dropped there. cross-frame references, so only the directly-affected frames are dropped there.
@@ -712,7 +712,7 @@ consumers are the in-tree toolchain crates.
discontinuity — a continuity-counter break, an adaptation-field discontinuity — a continuity-counter break, an adaptation-field
discontinuity_indicator, or a concealed-loss gap — the AC-3 / DTS / TrueHD discontinuity_indicator, or a concealed-loss gap — the AC-3 / DTS / TrueHD
parsers held a *truncated* partial access unit and spliced the post-gap bytes parsers held a *truncated* partial access unit and spliced the post-gap bytes
onto it, manufacturing a corrupt frame (ffmpeg "exponent out of range" / onto it, manufacturing a corrupt frame (a validator reports "exponent out of range" /
"Failed to decode block code(s)" / "Invalid data found") and, for TrueHD, a "Failed to decode block code(s)" / "Invalid data found") and, for TrueHD, a
non-monotonic timestamp band on multi-segment titles. The video path already non-monotonic timestamp band on multi-segment titles. The video path already
resynced via the keyframe gate; the audio parsers now do too — on a resynced via the keyframe gate; the audio parsers now do too — on a
@@ -720,7 +720,7 @@ consumers are the in-tree toolchain crates.
syncword, rebasing the timestamp from the post-gap PES. A discontinuity becomes syncword, rebasing the timestamp from the post-gap PES. A discontinuity becomes
a clean single-frame gap instead of a corrupt splice. Audio has no inter-frame a clean single-frame gap instead of a corrupt splice. Audio has no inter-frame
references, so dropping the truncated partial is the complete fix; the approach references, so dropping the truncated partial is the complete fix; the approach
matches FFmpeg's parser layer and GStreamer's `tsdemux`. matches how mainstream transport-stream demuxers behave.
- **Drive-prep firmware unlock skipped for DVD discs.** An - **Drive-prep firmware unlock skipped for DVD discs.** An
`if disc_is_dvd() { return }` guard in `Drive::init()` (present since `if disc_is_dvd() { return }` guard in `Drive::init()` (present since
1.0.0-rc.1) bypassed the entire drive-prep unlock step for DVDs. That unlock is 1.0.0-rc.1) bypassed the entire drive-prep unlock step for DVDs. That unlock is
+9 -9
View File
@@ -763,9 +763,9 @@ fn core_header_drop_reason(au: &[u8]) -> Option<DropReason> {
let mut r = BitReader::new(au.get(SYNCWORD_BYTES..)?); let mut r = BitReader::new(au.get(SYNCWORD_BYTES..)?);
// FTYPE: 1 = NORMAL frame, 0 = TERMINATION frame (the last frame of the // FTYPE: 1 = NORMAL frame, 0 = TERMINATION frame (the last frame of the
// stream). Per ETSI TS 102 114 and both reference decoders — ffmpeg's // stream). Per ETSI TS 102 114: a normal frame must carry a full 32-sample
// `ff_dca_parse_core_frame_header` (`normal_frame && deficit_samples != // PCM block, so a DEFICIT_SAMPLE_COUNT other than the full block marks a
// DCA_PCMBLOCK_SAMPLES`) and dcadec's `parse_frame_header` (which branches // terminating/short frame (the spec's deficit semantics, which
// on `normal_frame`) — the deficit-sample field must equal 32 ONLY for a // on `normal_frame`) — the deficit-sample field must equal 32 ONLY for a
// normal frame. A termination frame legitimately carries fewer samples and // normal frame. A termination frame legitimately carries fewer samples and
// is fully decodable; dropping it would silence the last frame of every // is fully decodable; dropping it would silence the last frame of every
@@ -794,7 +794,7 @@ fn core_header_drop_reason(au: &[u8]) -> Option<DropReason> {
} }
let _br_code = r.read_bits(5)?; let _br_code = r.read_bits(5)?;
// Reserved bit. Both reference decoders SKIP this field rather than reject // Reserved bit. Both reference decoders SKIP this field rather than reject
// on it — ffmpeg (`skip_bits1`) and dcadec (`bits_skip1`, comment "Reserved // on it — the field is reserved in ETSI TS 102 114 and skipped ("Reserved
// field"). A frame that sets it is still fully decodable, so rejecting it // field"). A frame that sets it is still fully decodable, so rejecting it
// was a false-drop that silenced any real stream whose encoder set the bit. // was a false-drop that silenced any real stream whose encoder set the bit.
// Read past it without gating (never reject a decodable frame). // Read past it without gating (never reject a decodable frame).
@@ -1807,7 +1807,7 @@ mod tests {
/// LFE flag is set to the reserved value 3 (`DTS_LFE_FLAG_INVALID`). It still /// LFE flag is set to the reserved value 3 (`DTS_LFE_FLAG_INVALID`). It still
/// sizes and syncs correctly (so the framer delimits it normally), but the /// sizes and syncs correctly (so the framer delimits it normally), but the
/// core-frame header validity check rejects it as an invalid LFE flag (ETSI /// core-frame header validity check rejects it as an invalid LFE flag (ETSI
/// TS 102 114; dcadec `LFE_FLAG_INVALID`). LFE is byte10 bits2-1, and does /// TS 102 114 §5.3.1: an LFF value of 3 is invalid). LFE is byte10 bits2-1, and does
/// NOT feed the frame duration (NBLKS + SFREQ only), so a dropped bad core /// NOT feed the frame duration (NBLKS + SFREQ only), so a dropped bad core
/// still carries the same `DTS_CORE_DUR_NS` as its good peers. /// still carries the same `DTS_CORE_DUR_NS` as its good peers.
fn make_bad_dts_core(size: usize) -> Vec<u8> { fn make_bad_dts_core(size: usize) -> Vec<u8> {
@@ -1997,8 +1997,8 @@ mod tests {
#[test] #[test]
fn legal_multichannel_amode_is_not_dropped() { fn legal_multichannel_amode_is_not_dropped() {
// ETSI TS 102 114 §5.3.1: AMODE is a 6-bit field with 16 LEGAL // ETSI TS 102 114 §5.3.1: AMODE is a 6-bit field with 16 LEGAL
// channel-arrangement codes (0-15); only 16-63 are reserved. ffmpeg's // channel-arrangement codes (0-15); only 16-63 are reserved. ETSI TS 102
// ff_dca_channels[16] = {1,2,2,2,2,3,3,4,4,5,6,6,6,7,8,8} confirms codes // 114 §5.3.1's per-AMODE channel counts cover all 16, confirming codes
// 10-15 are decodable 6/7/8-channel layouts. The decodability gate must // 10-15 are decodable 6/7/8-channel layouts. The decodability gate must
// KEEP them — dropping a spec-legal multichannel core silences audio the // KEEP them — dropping a spec-legal multichannel core silences audio the
// recover-100% goal must preserve. // recover-100% goal must preserve.
@@ -2040,7 +2040,7 @@ mod tests {
#[test] #[test]
fn termination_frame_with_small_deficit_is_kept() { fn termination_frame_with_small_deficit_is_kept() {
// ETSI TS 102 114 / ffmpeg (`normal_frame && deficit != 32`) / dcadec: // ETSI TS 102 114 (a normal frame carries a full 32-sample PCM block):
// a TERMINATION frame (FTYPE=0) may legally carry fewer than 32 deficit // a TERMINATION frame (FTYPE=0) may legally carry fewer than 32 deficit
// samples and is fully decodable. It must NOT be dropped — dropping the // samples and is fully decodable. It must NOT be dropped — dropping the
// last frame of a stream silences real audio (recover-100% violation). // last frame of a stream silences real audio (recover-100% violation).
@@ -2081,7 +2081,7 @@ mod tests {
#[test] #[test]
fn reserved_bit_set_is_not_dropped() { fn reserved_bit_set_is_not_dropped() {
// The bit after RATE is a RESERVED field that both reference decoders // The bit after RATE is a RESERVED field that both reference decoders
// SKIP (ffmpeg `skip_bits1`, dcadec `bits_skip1` "Reserved field") — they // SKIP (a reserved field per ETSI TS 102 114) — they
// never reject a frame that sets it. Rejecting was a false-drop that // never reject a frame that sets it. Rejecting was a false-drop that
// silenced any real stream whose encoder set the bit. Setting it (byte9 // silenced any real stream whose encoder set the bit. Setting it (byte9
// bit4) on an otherwise-valid core must leave it KEPT. // bit4) on an otherwise-valid core must leave it KEPT.
+2 -2
View File
@@ -240,7 +240,7 @@ const DTS_SFREQ: [u32; 16] = [
24_000, 48_000, 96_000, 192_000, 24_000, 48_000, 96_000, 192_000,
]; ];
/// DTS core base channel count per `AMODE` (all 16 defined values). Matches the /// DTS core base channel count per `AMODE` (all 16 defined values). Matches the
/// reference `ff_dca_channels[16]` table (ETSI TS 102 114) that the decodability /// per-AMODE channel counts in ETSI TS 102 114 §5.3.1, the same table the decodability
/// gate in `dts.rs` (`DTS_AMODE_COUNT`) also uses, so a spec-legal DTS-ES / 6.1 / /// gate in `dts.rs` (`DTS_AMODE_COUNT`) also uses, so a spec-legal DTS-ES / 6.1 /
/// 7.1 core (AMODE 13→7, 14/15→8) is DECLARED with its true channel count in the /// 7.1 core (AMODE 13→7, 14/15→8) is DECLARED with its true channel count in the
/// mp4 AudioSampleEntry / `ddts` box rather than a truncated 6. /// mp4 AudioSampleEntry / `ddts` box rather than a truncated 6.
@@ -613,7 +613,7 @@ mod tests {
fn dts_high_amode_channel_counts_are_declared() { fn dts_high_amode_channel_counts_are_declared() {
// The 16-entry DTS_AMODE_CH must declare the true core channel count for the // The 16-entry DTS_AMODE_CH must declare the true core channel count for the
// spec-legal high AMODEs that now pass the decodability gate: AMODE 13→7, // spec-legal high AMODEs that now pass the decodability gate: AMODE 13→7,
// 14→8, 15→8 (ETSI TS 102 114 / ff_dca_channels). The old 10-entry table // 14→8, 15→8 (ETSI TS 102 114 §5.3.1). The old 10-entry table
// fell through `unwrap_or(6)` → every one of these was declared as 6. // fell through `unwrap_or(6)` → every one of these was declared as 6.
// //
// Frame layout (mirrors dts_core_5_1_and_ddts): SFREQ=13 (48k), LFF=0 (no // Frame layout (mirrors dts_core_5_1_and_ddts): SFREQ=13 (48k), LFF=0 (no