The cause, and the fix, with a disc-wide check. resolve_movie_voice_region picks start = the predecessor cue's trailer, then filtered it with 'end - s < 1_500_000' -- 'only within one bank'. ADV's predecessor sits 3 618 816 B before end, so the filter rejected it and start fell back to anchor, which is a TOC offset and not a stream boundary. That explains the shape of the defect exactly: it strikes regions larger than 1.5 MB, which is why the three-stream multichannel regions are hit and single-stream ones never are. 17 of 95 resolving movies took the fallback. ADV's predecessor trailer at 433 425 776 plus 17 040 B of descriptor and padding is 433 442 816 -- the -238-packet start measured against the decoder, to the byte. Dropping the cap: unchanged 78, fixed cleanly 17, changed in any other way ZERO. In all 17 the only difference is a larger first chunk with every later chunk byte-identical, which is what a corrected start looks like and what pulling in a neighbouring asset does not. Regression test pinned to the RUNNING DECODER's byte_sizes rather than to this crate's own output. That is the point of it: every internal check passed happily while a third of a stream was missing, so only an external number could have caught this class of bug. sylpheed-formats: 136 tests pass, 0 fail (the one still running at commit time is an unrelated long mesh test). Exact clips for the other 16 are not independently verified -- the sweep is strong but ADV is the only one with a decoder measurement behind it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
41 lines
1.8 KiB
Rust
41 lines
1.8 KiB
Rust
//! Would keeping the predecessor (instead of falling back to `anchor`) recover
|
|
//! the streams the running decoder actually decodes?
|
|
//!
|
|
//! `voice_region_start_why.rs` shows the failing branch: the start filter
|
|
//! `end - s < 1_500_000` rejects `ADV`'s predecessor because its span is 3.6 MB,
|
|
//! so `start` falls back to `anchor` — a TOC offset, not a stream boundary.
|
|
//!
|
|
//! This does NOT patch the resolver. It asks the one question that decides whether
|
|
//! raising that cap is the fix: **from the predecessor, does `to_xma_riffs` return
|
|
//! the decoder's own byte_sizes?** For `ADV` those are known, so this is a test and
|
|
//! not a fit.
|
|
//!
|
|
//! cargo run -p sylpheed-formats --example voice_region_fix_test
|
|
|
|
use sylpheed_formats::media::{DirectorySource, DiscSource};
|
|
use sylpheed_formats::slb;
|
|
|
|
const ADV_PRED: u64 = 433_425_776;
|
|
const ADV_ANCHOR: u64 = 433_930_240;
|
|
const ADV_END: u64 = 437_044_592;
|
|
/// What the running decoder reported.
|
|
const WANT: [usize; 3] = [1_294_336, 1_118_208, 1_171_456];
|
|
|
|
fn main() {
|
|
let disc = std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC");
|
|
let src = DirectorySource::new(std::path::PathBuf::from(&disc));
|
|
for (label, start) in [("anchor (today)", ADV_ANCHOR), ("predecessor (proposed)", ADV_PRED)] {
|
|
let bytes = src
|
|
.read_segment_range("dat/sound", start, (ADV_END - start) as usize)
|
|
.expect("region");
|
|
let sizes: Vec<usize> = slb::to_xma_riffs(&bytes).iter().map(|r| r.len() - 60).collect();
|
|
let hit = sizes.len() == 3 && sizes.iter().zip(WANT.iter()).all(|(a, b)| a == b);
|
|
println!(
|
|
"{label:24} start {start} span {:>9} -> {:?}{}",
|
|
ADV_END - start,
|
|
sizes,
|
|
if hit { " <== MATCHES THE DECODER" } else { "" }
|
|
);
|
|
}
|
|
}
|