Resolve the forensic key map once per disc, not once per playlist
resolve_content_key_map loops every title into resolve_mux_key_map, which called resolve_fmts_key_map FIRST — before the CpsUnitCache — and on an FMTS disc returned immediately. So every playlist re-derived facts that belong to the DISC: a full UDF walk plus /AACS/IndividualSegment.tbl, and on an FMTS disc the anchor probe, the 32-index phase probe, and a fetch.fmts_indexes round trip. On a 60-playlist disc, measured on a synthetic fixture: 840 -> 14 metadata reads, 2,400 -> 40 probe reads, and 60 -> 1 key-service calls. Worst case before was up to 256 probe reads and 32 key-service calls per title. The 60 redundant key-service round trips are a strong candidate for the keyserver storm seen in the field. Two memos behind a pub(crate) DiscKeyCache. The table memo (UDF walk + tbl parse) is disc-invariant outright — nothing in that path mentions the title — and runs on EVERY disc, so a plain BD benefits too. Only the deterministic negatives are memoised as "not FMTS"; a DiscRead fault propagates uncached so a later title retries. A blind once-per-disc hoist of the PROBES was rejected as unsafe, and this is the load-bearing reasoning: the title enters through clip_byte_to_lba, which decides which segments are addressable and which LBA every probed clip byte reads from, so two titles with different extent lists probe different physical bytes. A hoist would serve title B an answer derived from title A's media and could silently turn a per-title FmtsKeyMissing into a success. The extent list is the ONLY per-title input, so keying on it is exactly sufficient — matching the ForcedProbeCache precedent. Result-identity was proved, not assumed: NEITHER probe reads the key pool. Verified here independently — probe_fmts_index_keys takes no keys parameter at all; index keys come from `fetch`, and the anchor's reply feeds the phase probe. So the pool's growth across titles, the one thing that does change between calls, cannot move a memoised value, and the result is order-independent. A test resolves three titles through a shared memo and through fresh memos and asserts both the per-title ranges and the final key pool (keys, slots, order) are identical. Not memoised, deliberately: fail-loud FmtsKeyMissing, and any run where an index hit a read fault — that is a property of a transient drive fault, not of the extents, and caching it would spread one bad read across 59 playlists. A fully-memoised title now does zero I/O, which made the old in-loop halt polls unreachable for it, so a check_halt on entry was added with a test that cancels after warming the memos. Also corrects my own overstatement from last round: the CpsUnitCache doc now says plainly that on an FMTS disc it removes NO reads, because this function returns before the extent loop ever runs. Five mutations, all verified red. Pre-existing bug flagged but not fixed: filter_addressable_segments only checks that a segment's START byte maps to some LBA in the title, so a play-all playlist can pass the filter while mapping segment bytes into the wrong clip, whose anchor then returns empty and aborts the sweep.
This commit is contained in:
@@ -41,6 +41,20 @@
|
||||
|
||||
### Fixed
|
||||
|
||||
- **The FMTS (AACS 2.1) forensic key resolution now runs once per disc, not once
|
||||
per title.** `Disc::resolve_content_key_map` resolves every title, and the FMTS
|
||||
branch ran ahead of everything else — so each playlist re-walked the UDF
|
||||
filesystem to re-read `/AACS/IndividualSegment.tbl`, re-ran the forensic anchor
|
||||
probe and the per-index phase probe, and **re-asked the key service for the
|
||||
disc's index-key set**. On a 60-playlist AACS 2.1 disc that was 60 identical
|
||||
key-service round trips (a key-server storm) and tens of thousands of random
|
||||
6144-byte reads for one disc-wide answer. The UDF walk is now memoised for the
|
||||
whole disc and the index keys + phases per distinct extent list — the only
|
||||
per-title input to the probes. A read-faulted phase probe is deliberately never
|
||||
memoised, so one bad read is not spread across the remaining playlists. The
|
||||
per-title UDF walk was paid on **every** disc, FMTS or not, so a plain BD sweep
|
||||
loses ~59 full-stroke seeks too. The multi-CPS extent memo added in 1.6.0 is
|
||||
also reachable on an FMTS disc for the first time.
|
||||
- **Mux correctness pass** (the `v1.4.0..HEAD` 10-phase audit): DTS core-header
|
||||
false-drops that dropped good DTS frames; the TrueHD channel-correction probe
|
||||
now runs correctly on AACS discs (7.1/Atmos no longer understated as 5.1);
|
||||
|
||||
Reference in New Issue
Block a user