libfreemkv: rc.5.1 DVD correctness fixes

- CSS: unlock scrambled-sector reads on enforcing drives via bus-auth
  only; classify sense 6F/03 as CSS-locked; early-bail on a fully locked
  scan; gate the AACS handshake off DVD discs.
- DVD first-play menu no longer prepended to the feature: read the title
  VOBS base from vtstt_vobs (0xC4), not the menu VOBS vtsm_vobs (0xC0).
- Interlaced field-duration (DefaultDecodedFieldDuration) written as a
  direct TrackEntry child rather than inside Video, so Windows reports
  the correct frame rate.
- Audio channel count read from the AC-3 bitstream; FieldOrder set to
  TFF; per-track BPS tags.
- Structured disc diagnostics at --log-level 3; reduced per-operation
  log spam.
This commit is contained in:
Matthew Jackson
2026-06-24 14:34:55 -07:00
parent 315276dd13
commit 6592f2a590
18 changed files with 1938 additions and 120 deletions
+21 -4
View File
@@ -1291,8 +1291,16 @@ impl Disc {
// AACS handshake (Blu-ray/UHD). Acquires the Volume ID via the
// cert-based mutual-auth handshake (the OEM route); drive unlock
// itself runs separately behind the pluggable `Unlocker` seam.
tracing::info!(target: "freemkv::scan", "phase: AACS handshake");
let (handshake, handshake_error) = Self::do_handshake(session, opts);
// AACS is Blu-ray/UHD only. A DVD uses CSS — skip the AACS handshake
// entirely (the drive already classified the disc as DVD at init), so a
// DVD never issues AACS OEM-VID / cert SCSI against the drive before the
// CSS bus-auth runs.
let (handshake, handshake_error) = if session.disc_is_dvd() {
(None, None)
} else {
tracing::info!(target: "freemkv::scan", "phase: AACS handshake");
Self::do_handshake(session, opts)
};
tracing::info!(target: "freemkv::scan", handshake = handshake.is_some(), "phase: handshake done");
// Request max read speed — removes riplock on DVD
@@ -1660,7 +1668,7 @@ impl Disc {
elapsed_ms = scan_with_t0.elapsed().as_millis() as u64,
"end"
);
Ok(Disc {
let disc = Disc {
volume_id: udf_fs.volume_id.clone(),
meta_title,
format,
@@ -1677,7 +1685,16 @@ impl Disc {
// which set this when they observe scrambled-but-uncracked content.
css_error: None,
content_format,
})
};
// Structured scan diagnostic block (--log-level 3). Emits the
// per-title / per-stream / decision / AACS rows under the
// `freemkv::diag` target; a no-op unless that target is enabled.
// (DVD per-cell category rows are emitted earlier from the IFO scan,
// before the per-cell detail is lowered away.)
crate::diag::dump_disc(&disc);
Ok(disc)
}
// ── Internal helpers ────────────────────────────────────────────────────