Fix TrueHD channel-correction probe on AACS discs; delete dead reactive key-fetch path

The mux's TrueHD 7.1/Atmos channel-correction probe built its
DecryptingSectorSource with no key map. Since AACS now decrypts only via
the resolved map, the mapless probe read failed loud on the first unit
and the correction was silently skipped on every AACS disc — 7.1/Atmos
stayed understated as the MPLS-declared 5.1. The probe now resolves the
same up-front key map the mux read installs (non-fatal on failure).

Delete the reactive per-read key-fetch recovery path
(DecryptingSectorSource::with_key_fetch, the recovery field/cipher
scratch, and sector/recovery.rs). It was unreachable: AACS resolves its
full key map up front, so a mapless AACS read is a bug, not a
recover-mid-read case. KeyFetch itself stays — it is the up-front
resolver fetch used by resolve_mux_key_map.
This commit is contained in:
Matthew Jackson
2026-07-23 14:03:08 -07:00
parent 88e58bfc95
commit e632874665
4 changed files with 43 additions and 441 deletions
+28 -3
View File
@@ -439,9 +439,34 @@ pub fn input(url: &str, opts: &InputOptions) -> io::Result<Box<dyn crate::pes::S
// raw output isn't decoded anyway).
if !opts.raw {
match crate::io::file_sector_source::FileSectorSource::open(path) {
Ok(probe) => {
let mut dec =
crate::sector::DecryptingSectorSource::new(probe, keys.clone());
Ok(mut probe) => {
// The probe DECRYPTS the title head, so it needs the SAME
// up-front key map the mux read installs below. An AACS
// `DecryptingSectorSource` with no map fails loud on the
// first unit (`decrypt_sectors_mapped` is the only AACS
// decrypt path) — without resolving one here the correction
// is silently skipped on every AACS disc and 7.1/Atmos stays
// understated as the MPLS-declared 5.1. Resolution failure is
// non-fatal (`.ok()`): leave channels uncorrected, never
// fail the mux.
let mut probe_keys = keys.clone();
let probe_title = disc.titles[idx].clone();
let probe_map = match &probe_keys {
crate::decrypt::DecryptKeys::Aacs { .. } => resolve_mux_key_map(
&mut probe,
&probe_title,
&mut probe_keys,
opts.key_fetch.as_ref(),
disc.content_format,
)
.ok()
.map(std::sync::Arc::new),
_ => None,
};
let mut dec = crate::sector::DecryptingSectorSource::new(probe, probe_keys);
if let Some(map) = probe_map {
dec = dec.with_key_map(map);
}
crate::disc::correct_truehd_channels(&mut dec, &mut disc.titles[idx]);
}
Err(e) => {