changelog: 1.8.0 release notes

This commit is contained in:
Matthew Jackson
2026-10-04 18:28:23 -07:00
parent 561a757b60
commit 0a96b1ca81
+5
View File
@@ -54,6 +54,10 @@
### Added
- DVD: the region mask from the VMG (`DvdInfo.region_mask`, `DiscRegion::Unknown`), stream labels from the audio and subpicture code-extension byte, chapter names from the TXTDT text data, and a probe of each title's subpictures for forced-display (`FSTA_DSP`) commands.
- HD DVD: AACS decryption per pack, keyed by each EVOBU's CPI; AACS-wrapped playlists and features split across `PEVOB_n` files.
- AACS: a Class II MKB is reported as an unsupported class (E7109) instead of as a missing key.
- UHD: HDR10 mastering metadata is kept when content light level is absent; `hdr_plus_flag` is read from the HEVC stream attributes; the Dolby Vision enhancement-layer track's `dvcC` carries `bl_present=0`.
- `mpg://` as a source and a destination: a DVD-Video / MPEG-2 program stream file reads through the decryption stage and the DVD sector pipeline (a scrambled `.vob` is cracked once, `--raw` keeps the ciphertext; a clear MPEG-1 or stuffed MPEG-2 stream is no longer read as scrambled, and a scrambled pack with no key fails E7023). `MpgSink` writes an H.222.0 program stream with P-STD pack timing, system header and PSM; `Error::MpgNoVideoTrack` (E9074), `Error::MpgUnpacketized` (E9075). `FileSectorSource::open_padded` zero-pads a partial tail sector.
- `keys` module: `KeyRing::acquire(evidence, sampler, sources, opts, ctx)` (`KeyScope::{None, Titles, WholeDisc}`, `AcquireOptions`, `KeyResolution`) asks the key sources once before any output and proves each held key against the disc's ciphertext per stream file; keys and the Volume ID stay in memory (`Debug` redacts). Also `title_reader`, `whole_disc_reader`, `decrypt_status`, `check_decryptable`, `KeySetStatus`, `ForensicState`, `DecryptStatus`, `ProofCache`. A piece that cannot be proven up front is proven on first read; a unit no held key opens stops a title rip with E7022; in an image or folder it is blanked, warned and counted. `ResolveCtx::halt()` / `progress()` give sources the Stop token; key-service retries back off 1 s to 8 s. `MediaKeyVariantError::code()` returns E7100-E7108.
- `disc_root_of(path)`: the AACS disc folder a loose Blu-ray clip sits in (`<root>/BDMV/STREAM/x.m2ts` with `<root>/AACS`), so a caller can resolve the clip's keys on `dir://<root>`.
@@ -73,6 +77,7 @@
### Changed
- **DVD titles are `ContentFormat::DvdPs`**, set only by the DVD scan; `MpegPs` now means HD DVD or a plain program-stream file. DVD-only steps (cell filter and clock joins, CSS title-key crack, forced-subtitle probe) no longer run on HD DVD or `mpg://`. The `json://` `format` field reads `"DvdPs"` for DVD titles.
- **AACS damage policy (E7013):** a flagged AACS unit no key opens (no TS sync, zero-filled or garbled head, lone FMTS verify failure, off-grid) is zero-filled, warned and counted on every path (ISO mux, live mux, extract, whole-disc reader) instead of failing with E7013, with an end-of-rip "N damaged AACS units blanked" log. A wrong key still fails: E7013 at resolve (or when two or more FMTS units fail under one key with none verifying), E7022 on arrival in a title rip (an image or folder blanks the unit instead).
- A BD-TS mux with no AACS key set fails E7022 on the first AACS-flagged unit instead of writing ciphertext; an AACS HD DVD session with no set fails `NoDiscKey`. A key-set stop (E7022) is never shrunk, recovered or skipped.
- A Stop during a mux is always `completed = false, halted = true` (`MuxOutcome::halted`), whether it lands during the open or the pump: `mux_with_keys` no longer returns `Err(Halted)` from a stopped open. A Stop reaches `iso://` and `dir://` sources inside a blocked read, the image scan and the CSS crack (it was seen only between frames), and `iso://`, `dir://` and `mpg://` URL muxes report read progress like the disc arms. A stopped read is a stop, not a skipped sector. A read error repeats on every later `read()` of the highway stream. A halted `PrefetchedSectorSource` close is `Err(Halted)`, not EOF.