oxideav-dvd
Read-only DVD-Video disc reader — ISO 9660 + UDF 1.02 mount +
VIDEO_TS/ directory walk + IFO body parser (VMGI / VTSI / PGC /
TT_SRPT / VTS_PTT_SRPT / VTS_C_ADT) + VOB demuxer (MPEG-PS pack
- nav-pack + DVD substream router) + optional VOB → Matroska
mux with
ChapterTimeStart/ChapterTimeEndcarried over from the PGC playback-time fields. Clean-room per ECMA-267 / ECMA-268 + OSTA UDF 1.02 + the ECMA-167 UDF base standard + RFC 9559 §5.1.7 + mpucoder + stnsoft community RE references.
Scope
Phases 1, 2, and 3a (this release) handle the physical + filesystem + disc-identification + IFO structural + VOB demux layers — enough to point a player at a DVD-Video disc image or block device, enumerate the title-set files, pull the title / chapter / program-chain / cell layout out of every IFO, demux each cell's VOBUs into raw MPEG-2 video + AC-3 / DTS / LPCM audio
- subpicture elementary streams keyed by track ID, and answer
time-based seek queries through the per-PGC
VTS_TMAPTItime map + the title-setVTS_VOBU_ADMAPabsolute-sector list. The Phase 3a nav-pack decoder also surfaces the typed DSI sub-sections (DSI_GIgeneral info;SML_PBIseamless-playback interleaved-unit flags + jump pointers + per-stream audio-gap table;SML_AGLI9-cell seamless-angle table;VOBU_SRI19-forward + 19-backward seek pointers + bracket pointers;SYNCIper-audio + per-subpicture sync pointers) that chapter-accurate seek and A/V sync need, plus the PCI highlight information (HLI_GI timing + the three SL_COLI selection/action colour-contrast schemes + the per-button BTN_IT table — geometry, D-pad adjacency and the raw action command) that a menu renderer needs to draw and route button input, plus the PCI NSML_AGLI non-seamless angle jump table (9nsml_agl_cN_dstacells, each carrying a direction bit + signed sector offset, with the0x0000_0000absent and0x7FFF_FFFFno-more-video sentinels) that a player re-seeks against on a non-seamless angle switch. A newnavmodule (Phase 3c precursor) decodes each 8-byteNavCommandword into a typedNavInstructiontree — NOP / Goto / Break / SetTmpPML, the fullLink*family (with the 13-entry link-subset table),Exit/JumpTT/JumpVTS_TT/JumpVTS_PTT, the four-wayJumpSS/CallSStarget selector, theSetSystemfamily (SetSTN/SetNVTMR/SetGPRMMDwith counter-mode bit /SetAMXMD/SetHL_BTNN), the plainSetarithmetic family (12 SET sub-ops × GPRM-or-SPRM source), and classifier sub-ops for the compound Type 4..6 CMP/SET/LNK encodings. The Phase 3cvmmodule wraps the decoder with a register file (16 GPRMs + 24 SPRMs with spec-defined defaults + per-GPRM counter-mode bits), an RSM call/return stack, intra-list PC handling (Goto/Break/ runaway-loop bound), and aVm::step(NavInstruction) -> VmActioninterpreter that surfacesLink/JumpTitle/JumpVtsTitle/JumpVtsPtt/JumpSs/CallSs/Resume/SetNavTimer/Exitactions to the playback engine. No CSS yet — Phase 3c via the externaloxideav-csscrate.
| Layer | Status |
|---|---|
| ISO 9660 PVD + path-table + directory walk | landed |
| UDF 1.02 mount (PVD / PD / LVD / FSD / FE / FID) | landed |
| VIDEO_TS file enumeration (VIDEO_TS.IFO / .VOB / .BUP + VTS_xx) | landed |
dvd:// source driver (registry feature) |
landed |
| VMGI / VTSI MAT parse (header + sector pointers) | landed |
| VTSI_MAT / VMGI_MAT stream-attribute extension (video / audio × 8 / subpicture × 32 / karaoke MC extension) | landed |
| VMG_VTS_ATRT (per-VTS attribute copies — entry header + VTS_CAT + raw attribute blob) | landed |
| VMG_PTL_MAIT (country-keyed parental management — 8 levels × (Nts + 1) 16-bit allow-masks per country) | landed |
| VMGM_PGCI_UT / VTSM_PGCI_UT (menu PGCI Unit Table — outer ISO 639 language-unit search-pointer list + inner per-LU PGC search-pointer list + PGC bodies + menu-existence flag decoder) | landed |
FP_PGC (First-Play PGC — disc-insertion startup routing via DvdDisc::parse_fp_pgc; byte-addressed per VMGI_MAT 0x0084, body parsed by Pgc::parse) |
landed |
| TT_SRPT (title list) + VTS_PTT_SRPT (chapter list) | landed |
| VTS_PGCI + PGC (program chains + cells + colour-LUT + command table) | landed |
| VTS_C_ADT (cell-to-VOB-sector lookup) | landed |
VMGM_C_ADT / VTSM_C_ADT + VMGM_VOBU_ADMAP / VTSM_VOBU_ADMAP (menu cell-address tables + menu VOBU sector maps via DvdDisc::parse_vmgm_c_adt / parse_vtsm_c_adt / parse_vmgm_vobu_admap / parse_vtsm_vobu_admap) |
landed |
| VTS_VOBU_ADMAP (per-VOBU sector list + partition lookup) | landed |
| VTS_TMAPTI (per-PGC time map + seconds → VOBU sector seek) | landed |
| VOB demux (MPEG-PS pack + nav-pack + PES) | landed (Phase 3a) |
| DVD substream routing (AC-3 / DTS / LPCM / subpicture) | landed (Phase 3a) |
| LPCM 7-byte audio-pack header decode (quantisation / sample rate / channels / dynamic range) | landed (Phase 3a) |
AC-3 sync-frame header decode (syncinfo() fscod / frmsizecod + bsi() bsid / bsmod / acmod / mix-level conditionals / lfeon → sample rate + frame size + nominal bitrate + channel layout) |
landed (Phase 3a) |
User Operation flag decoder (TT_SRPT / PGC / PCI-VOBU three-level OR-merged UopMask) |
landed (Phase 3c support) |
| VOBU_SRI search-table decode | landed (Phase 3a) |
| NAV-pack PCI highlight (HLI_GI + SL_COLI + BTN_IT buttons) | landed (Phase 3a) |
NAV-pack PCI NSML_AGLI (non-seamless angle jump table — 9 nsml_agl_cN_dsta cells with direction bit + absent / no-more-video sentinels + 1-based angle() accessor) |
landed (Phase 3a) |
PCI_GI hli_ss → typed HighlightStatus enum (None / AllNew / UsePrevious / UsePreviousExceptCommands) + geometry-inheritance + own-commands classifiers |
landed (Phase 3a) |
HLI_GI btn_md → typed ButtonMode view (btngr_ns group count + three 3-bit btngrN_ty codes) |
landed (Phase 3a) |
NAV-pack DSI typed sub-sections (DSI_GI + SML_PBI + SML_AGLI + VOBU_SRI + SYNCI; DSI_GI c_eltm → typed PgcTime + ns) |
landed (Phase 3a) |
| MKV mux + chapter encoding wiring | landed (Phase 3b, mkv-output feature) |
VM instruction decode (typed NavInstruction disassembler — non-executing) |
landed (Phase 3c precursor) |
PgcCommandTable typed-instruction iterators (pre_instructions / post_instructions / cell_instructions + 1-based cell_instruction(index)) |
landed (Phase 3c bridge) |
| Sub-Picture Unit (SPU) decode (SPUH + SP_DCSQT command stream + PXDtf/PXDbf 2-bit RLE) | landed |
| SPU → RGBA compositor (palette + contrast resolve + BT.601 YCbCr→RGB + field interleave) | landed |
| VM execution (interpreter over SPRMs/GPRMs + RSM stack + PC) | landed (Phase 3c — Type 0..6, including compound SET+CMP+LINK) |
| Typed SPRM accessors — language slots + sentinel-typed integer slots (SPRM 0 / 1 / 3 / 12 / 13 / 16 / 17 / 18 / 19) | landed |
| CSS authentication + descrambling | Phase 3c (external oxideav-css crate) |
Quick start
use DvdDisc;
// Open a DVD-Video ISO or block device.
let disc = open.unwrap;
println!;
println!;
for f in &disc.video_ts_files
Standalone build
oxideav-core is gated behind the default-on registry feature.
Drop the framework dependency entirely with:
= { = "0.0", = false }
The DvdDisc, iso9660::*, and udf::* parser surface stays
available; only the dvd:// source-registry plumbing disappears.
DVD → MKV (Phase 3b)
Enable the mkv-output feature to convert a DVD title to a
Matroska file:
= { = "0.0", = ["mkv-output"] }
convert_dvd_to_mkv.unwrap;
The muxer preserves each PES packet's 90 kHz PTS, sizes the MKV
Tracks element to the streams the title actually carries
(video + AC-3 / DTS / LPCM / subpicture), and emits one MKV
ChapterAtom per DvdChapter with ChapterTimeStart /
ChapterTimeEnd computed from the PGC playback-time BCD field
(30 fps for NTSC, 25 fps for PAL — per mpucoder-pgc.html).
The feature is default-off so the parse-only surface above
keeps compiling against any oxideav-mkv patch release on
crates.io. Toggle it on once you've got oxideav-mkv >= 0.0.8
(the release that landed MkvMuxer::add_chapter).
Decoding a Sub-Picture Unit
The spu module turns the raw bytes of a DVD subtitle / menu
overlay into a typed control sequence plus run-length-decoded
pixel data, without rendering. The PGC palette + final
framebuffer step stays with the caller:
use ;
// `spu_bytes` is the concatenation of every subpicture PES packet
// payload for one subpicture stream over one display interval.
let spu_bytes: & = &;
let unit = parse.unwrap;
for dcsq in &unit.control_sequences
// Materialise the top field's 2-bit palette indices given the
// known display width / line count.
if let =
The decoder handles the four PXD run-length forms (n n c c /
0 0 n n n n c c / 0 0 0 0 n n n n n n c c /
0 0 0 0 0 0 n n n n n n n n c c), the 16-bit-form "count=0 =
until end of line" terminator, and the per-row byte alignment
required by mpucoder-spu.html §PXDtf.
To go all the way to a finished overlay, pass the parsed unit and
the PGC's 16-entry palette to SubPictureUnit::composite:
use SubPictureUnit;
use PaletteEntry;
let spu_bytes: & = &;
let palette: = ;
let unit = parse.unwrap;
if let Some = unit.composite.unwrap
composite resolves the four 2-bit pixel codes through the unit's
own SET_COLOR (→ 0..=15 palette index) and SET_CONTR
(→ 0..=15 alpha), converts the palette's BT.601 studio-swing
YCbCr to RGB (ycbcr_to_rgb, luma scale Y = 16 0 % … Y = 235
100 % per stnsoft-color_pick.html), and interleaves the
top-field (lines 1, 3, 5, …) and bottom-field pixel data into one
row-major SpuBitmap. Positioning/scaling the overlay onto the
video frame stays with the player.
Decoding an LPCM audio-pack header
The lpcm module pulls the 7-byte audio-pack header off the start
of a private_stream_1 LPCM PES payload (substream 0xA0..=0xA7)
and surfaces the sample format the raw PCM bytes were encoded in:
use ;
// `lpcm_payload` starts at the substream-ID byte (`0xA0..=0xA7`) —
// the same shape `VobStreams::lpcm` would carry if the demuxer
// preserved the substream selector ahead of the body.
let lpcm_payload: & = &;
let = peel_lpcm_payload.unwrap;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert!;
// `samples` is the big-endian PCM tail, ready for sample unpacking.
let _ = samples;
LpcmHeader::bitrate_kbps() returns the channels × sample_rate × bits_per_sample / 1000 rate; is_within_dvd_video_limit() checks
the result against the 6144 kbps DVD-Video ceiling per
stnsoft-LimPcmAud.html (the red-highlighted combinations like
96 kHz × 24-bit × 8-channel return false). linear_gain() /
gain_db() evaluate the two parameterisations of the X/Y
dynamic-range coefficient on mpucoder-lpcm.html
(2^(4 - (X + Y/30)) and 24.082 - 6.0206 X - 0.2007 Y); applying
the gain to the decoded samples stays with the audio decoder.
Decoding an AC-3 sync-frame header
The ac3 module pulls the AC-3 (Dolby Digital) syncinfo() +
bsi() header fields off the start of an AC-3 elementary stream —
the raw bytes the demuxer routes to VobStreams::ac3 from
private_stream_1 substream 0x80..=0x87. It surfaces the format
a player needs to size buffers and label the track without pulling
in a full AC-3 audio decoder:
use ;
// `frame` starts at the AC-3 sync word (0x0B77).
let frame: & = &;
let h = parse.unwrap;
assert_eq!;
println!;
// 3/2 + LFE → 5.1
if h.audio_coding_mode == ThreeTwo && h.lfe_on
// Seek to the next frame boundary.
let next = h.frame_size_bytes.unwrap;
println!;
frame_size_words() / frame_size_bytes() read the 38-entry
frmsizecod table (with separate 32 / 44.1 / 48 kHz word-count
columns) selected by the decoded fscod; reserved fscod /
frmsizecod codes are preserved and return None. The decode
covers the deterministically-positioned bsi() prefix
(bsid / bsmod / acmod + the cmixlev / surmixlev /
dsurmod conditionals + lfeon); the variable-length bsi() tail
and the audio blocks stay with a downstream decoder, per
stnsoft-ac3hdr.html.
Querying User Operation prohibitions
The uops module surfaces the 25-entry user-operation table per
mpucoder-uops.html plus the spec's three-level OR-merge rule.
Three on-disc fields carry a UOP-prohibition mask — the TT_SRPT
entry (bits 0+1 packed in title_type), the PGC header (offset
0x0008), and the PCI packet (PCI_GI 08) — and a set bit in
any of them inhibits the associated control.
use ;
use ;
use PciPacket;
// `Pgc::uop_mask().iter()` walks the currently-prohibited ops in
// ascending bit order; reserved bits above bit 24 are skipped.
Each accessor wraps a u32 newtype; UopMask::from_bits /
raw() round-trip the on-disc value exactly. fits_level(level)
validates that a mask carries only the bits the spec table marks
present at that level — useful for an IFO sanity-checker.
Reading the DSI cell-elapsed time
Every Nav-Pack carries a DSI_GI block whose 4-byte c_eltm field
is a BCD hh:mm:ss:ff cell-elapsed timestamp plus a 2-bit frame-
rate code (11 = 30 fps, 01 = 25 fps; 00 / 10 are spec-
illegal). The typed accessor decodes the field through the same
PgcTime shape used by the PGC playback-time fields:
use ;
let sector: & = &; // 2048 bytes covering one Nav-Pack
let nav = parse.unwrap;
let t = nav.dsi.cell_elapsed_time;
assert!;
println!;
PgcTime::to_nanoseconds() is also available directly on the
type, returning the rational (frames × 1e9) / fps conversion
without needing the mkv-output feature.
Time-based seek (VTS_TMAPTI + VTS_VOBU_ADMAP)
Once a VtsIfo is parsed, the time_map field carries one time map
per PGC and vobu_admap carries the title-set VOBU sector list. Both
fields are Options; a None indicates the corresponding sector
pointer in VTSI_MAT was zero (the table was elided by the
authoring tool).
use DvdDisc;
let disc = open.unwrap;
let mut reader = open.unwrap;
let vts = disc.parse_vts.unwrap;
// Where does PGC 1's playback timeline sit at the 30-second mark?
if let Some = vts.vobu_sector_at_pgc_time
// Iterate every VOBU in the title-set VOBs.
if let Some = &vts.vobu_admap
VobuAdmap::vobu_containing(sector) performs the inverse lookup —
given a VOB-relative sector, return the 1-based VOBU number whose
range covers it (using a binary partition over the entry list).
Disassembling a NavCommand (Phase 3c precursor)
The nav module decodes each 8-byte PGC command word into a typed
NavInstruction tree without executing anything — useful for disc
debuggers, analysers, and the future Phase-3c executor:
use ;
use NavCommand;
// A JumpSS-to-First-Play command (type=1 jump family, selector=0).
let nc = NavCommand ;
assert_eq!;
The decoder covers the well-defined opcodes in Types 0..3 (NOP,
Goto, Break, SetTmpPML, the full Link family with the 13-entry
link-subset table, Exit, JumpTT, JumpVTS_TT, JumpVTS_PTT, the
four-way JumpSS / CallSS target selector, the SetSystem family,
the plain Set arithmetic family with 12 SET sub-ops × GPRM-or-SPRM
source) AND the compound Type 4..6 forms (SetCLnk, CSetCLnk,
CmpSetLnk) — each surfaces the full operand triple: SET source
(register srs / sr2 or 16-bit immediate per the SET-dir flag),
CMP right-hand side (register cr2 or 16-bit immediate per the
CMP-dir flag), shared selector register (scr for Type 4, sr1
for Types 5+6), CMP left-hand register (Type 5 only — cr1), the
6-bit hl_bn highlight-button override, and the 5-bit Link
subset code. The two "Illegal" red rows (SET-dir=1 AND CMP-dir=1
for Types 5+6) surface as NavInstruction::Invalid per the spec
page's rejection. The Register enum maps an operand byte to
Gprm(0..=15) / Sprm(0..=23) / Invalid(_) per the asterisk
note on mpucoder-vmi.html.
Executing PGC commands (Phase 3c VM)
The vm module wraps the disassembler with an interpreter that
owns the register file (16 GPRMs + 24 SPRMs with spec-defined
defaults) and the navigation-resume stack:
use ;
use NavCommand;
let mut vm = new;
// SPRM defaults loaded per mpucoder-sprm.html.
assert_eq!;
// Run a PGC's pre-command list end-to-end.
let pre: = vec!;
let = vm.run_list;
match action
let _ = pc;
Vm::step handles Type 0..3 instructions (Set / SetSystem /
SetGprmMd / SetStn / SetNvtmr / SetHl_BTNN / SetTmpPml / NOP /
Goto / Break) entirely in-process; the Link / Jump / Call family
mutates persistent register state when relevant (CallSs pushes
the resume frame, RSM pops it) then surfaces the destination as
a typed VmAction for the playback engine. The compound Type
4..6 forms are executed in spec order per
mpucoder-vmi-sum.html:
- Type 4
SetCLnkruns the SET first, then compares the post-SET value ofscragainstcmp_rhs; on atruecompare the inner Link subset surfaces asVmAction::Link(Subset), otherwise the action collapses toVmAction::Continue(the outer command list keeps walking). - Type 5
CSetCLnkcompares first; ontrueit runs SET then fires Link; onfalseneither SET nor Link runs. - Type 6
CmpSetLnkcompares first; ontrueit runs SET; the Link always fires regardless of the compare outcome — that's how Type 6 differs from Type 5.
A compound whose inner Link subset is Nop collapses to
Continue even when the SET / CMP ran; an Rsm subset pops the
same RSM stack as a bare Type-1 LinkSub::Rsm. Runaway Goto
loops are bounded by a step budget so a malformed disc can never
hang the interpreter.
SPRM bitfield-aware accessors
Every SPRM the spec page documents with a non-integer layout has a
typed accessor — bit-packed payloads (SPRM 2 sub-picture state,
SPRM 8 highlighted button, SPRM 11 karaoke mixing, SPRM 14 video
preference, SPRM 15 audio capabilities, SPRM 20 region mask) as well
as the two-byte ISO 639 / ISO 3166 language slots
(SPRM 0 menu language, SPRM 12 parental country, SPRM 16 / 18
preferred audio / sub-picture language) and the sentinel-typed
integer slots (SPRM 1 audio stream 0..=7 + 15-none, SPRM 3 angle
1..=9, SPRM 13 parental level 1..=8 + 15-none, SPRM 17 / 19
language extension enums). The RegisterFile surfaces them all so a
playback engine doesn't re-implement the layouts on each callsite —
refer to docs/container/dvd/application/mpucoder-sprm.html for the
canonical field allocations.
use ;
let vm = new;
// SPRM 2 default = "stream 62 / do-not-display"
let spu = vm.regs.subpicture_stream;
assert!;
assert!;
// SPRM 8 default = button 1
assert_eq!;
// SPRM 14 video preference (4:3 / Normal mode by default)
let vp = vm.regs.video_preference;
assert_eq!;
assert_eq!;
// SPRM 20 region mask — default = no regions enabled
assert!;
// SPRM 1 / 3 sentinels — defaults
assert_eq!;
assert_eq!;
// SPRM 13 parental level — uninitialised raw "0" → `Invalid(0)`
// (the spec defines `1..=8` real, `15` = control-off; the
// "player specific" default leaves the slot zero).
assert_eq!;
// SPRM 16 / 18 language code defaults — `0xFFFF` "not specified"
assert!;
assert!;
// SPRM 17 / 19 extension defaults — "not specified"
assert_eq!;
assert_eq!;
For the language slots, LanguageCode::ascii_bytes() returns
Some([hi, lo]) when both bytes are printable ASCII letters and
as_string() returns the lower-cased ISO 639 / ISO 3166 alpha-2
form. The 0xFFFF value matches the LanguageCode::NOT_SPECIFIED
sentinel and is_not_specified() short-circuits both decoders.
Each accessor decomposes the raw u16 according to the spec
page's bit allocation and preserves the original word on the
returned view's raw field, so a caller that wants to forward
the SPRM verbatim can round-trip it bit-for-bit.
Clean-room sources
This crate was written entirely against:
docs/container/dvd/physical/ECMA-267_3rd_edition_april_2001.pdf— DVD-ROM physical layer.docs/container/dvd/physical/ECMA-268_3rd_edition_april_2001.pdf— DVD-ROM file system specification (UDF 1.02 + ISO 9660 bridge layer constraints).docs/container/dvd/physical/OSTA_UDF_1.02.pdf— OSTA UDF profile used by DVD-Video.docs/container/bluray/ECMA-167_3rd_edition_june_1997.pdf— the underlying UDF base standard (cross-referenced; UDF 1.02 is a strict subset of UDF 2.50 by ECMA-167).docs/container/dvd/application/mpucoder-ifo.html,mpucoder-ifo_vmg.html,mpucoder-ifo_vts.html,mpucoder-pgc.html,stnsoft-vmindx.html— community reverse-engineering references mirrored underdocs/container/dvd/application/for the VIDEO_TS layout, the IFO field layouts (VMGI_MAT / VTSI_MAT / TT_SRPT / VTS_PTT_SRPT / VTS_PGCI / VTS_C_ADT / VTSM_PGCI_UT / VMGM_PGCI_UT / VMG_VTS_ATRT / VMG_PTL_MAIT / VTS_VOBU_ADMAP / VTS_TMAPTI / VTS_TMAP) and the PGC body structure (PGC_GI header, audio/sub-picture stream control, the 16-entry(0, Y, Cr, Cb)subpicture colour-LUT at PGC offset0x00A4, the pre/post/cell command table, program map, Cell Playback Information Table, Cell Position Information Table). Decoding eachNavCommandinto a typedNavInstructiontree lives in thenavmodule; executing the decoded form is the remaining Phase 3c VM work.docs/container/dvd/application/mpucoder-vmi.html,mpucoder-vmi-sum.html,mpucoder-vmi-jmp.html,mpucoder-sprm.html— the VM instruction set (the full opcode table including SET/CMP sub-ops and the link-subset inner table, the plain-English instruction-family summary, the jump/call target table, and the 24-entry SPRM map) feeding thenavmodule'sNavInstructiondecoder.docs/container/dvd/application/mpucoder-spu.html— the Sub-Picture Unit layout (SPUH, the four PXD run-length forms + the end-of-line terminator + per-row byte alignment, the eight SP_DCSQ command codes including theLN_CTLI/PX_CTLIparameter hierarchy ofCHG_COLCON, and the 90 kHz/1024 delay conversion table) feeding thespumodule'sSubPictureUnitdecoder.docs/container/dvd/application/stnsoft-color_pick.html— fixes the subpicture palette's BT.601 studio-swing luma scale (Y = 160 % …Y = 235100 %) used by thespumodule'sycbcr_to_rgb/ RGBA compositor.docs/container/dvd/application/mpucoder-packhdr.html,mpucoder-pes-hdr.html,mpucoder-mpeghdrs.html,mpucoder-pci_pkt.html,mpucoder-dsi_pkt.html,mpucoder-dvdmpeg.html,stnsoft-vobov.html,stnsoft-sys_hdr.html— VOB MPEG-PS pack header, PES header (DVD subset), MPEG-PS stream-ID table, NAV-pack PCI / DSI packet layouts, DVD substream allocations, VOBU / cell / VOB semantics, and the Program Stream System Header used by the Phase 3a VOB demuxer.docs/container/dvd/application/mpucoder-lpcm.html— the 7-byte LPCM audio-pack header layout (quantisation / sample-rate / channel-count fields, first-access-unit pointer, the X/Y dynamic-range coefficients) feeding thelpcmmodule'sLpcmHeaderdecoder.docs/container/dvd/application/stnsoft-LimPcmAud.html— the per-(sample_rate × quantisation × channels)bitrate table and the 6144 kbps DVD-Video ceiling used byLpcmHeader::is_within_dvd_video_limit.docs/container/dvd/application/stnsoft-ac3hdr.html— the AC-3 (Dolby Digital)syncinfo()field layout, thefscodsampling-rate table, the 38-entryfrmsizecodframe-size / nominal-bit-rate table (with separate 32 / 44.1 / 48 kHz word-count columns), and thebsi()field order (bsid/bsmod/acmodwith the conditionalcmixlev/surmixlev/dsurmodpresence rules +lfeon) feeding theac3module'sAc3Headerdecoder.docs/container/dvd/application/mpucoder-uops.html— the 25-row User Operation flag table (bit numbers + per-level applicability matrix + three-level OR-merge rule) feeding theuopsmodule'sUserOp/UopMask/UopLeveldecoder and the typeduop_mask()/is_user_op_allowed()accessors exposed onPgc,PciPacket, andDvdTitleEntry.
The crate is built clean-room from the spec PDFs and the
behavioural-trace HTML pages listed above; no external player or
library source was consulted. The *-COPYING / *-README.md
files in docs/container/dvd/ are licence-trail transparency
markers carried by the docs collaborator, not implementation
references.
License
MIT — see LICENSE.