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
76 lines
3.8 KiB
Plaintext
76 lines
3.8 KiB
Plaintext
# resolve_movie_voice_region starts 238 packets LATE for ADV.
|
|
#
|
|
# 2026-08-30. Raised by the port agent, whose arithmetic is the whole reason
|
|
# this was found: the running decoder's three ADV contexts sum to 3 584 000
|
|
# payload bytes, but the resolved region is 3 114 352 -- 15 % too small to
|
|
# hold them. One of the two spans was wrong, and it was the disc side.
|
|
#
|
|
# The gap is a WHOLE NUMBER OF PACKETS, which is what a start offset looks
|
|
# like and corruption does not:
|
|
# ctx0 declares 632 packets = 1 294 336 B
|
|
# the resolver's leading chunk has 394 packets = 806 912 B
|
|
# difference 238 packets = 487 424 B
|
|
#
|
|
# GROUND TRUTH is the running decoder's own byte_sizes. This is not free to
|
|
# fit: the span either lands on all three or it does not.
|
|
#
|
|
resolver says 433930240..437044592 (3114352 B)
|
|
decoder wants [1294336, 1118208, 1171456] = 3584000 B payload
|
|
|
|
- 0 packets (start 433930240): 3 chunk(s) [806912, 1118208, 1171456]
|
|
- 100 packets (start 433725440): 3 chunk(s) [1011712, 1118208, 1171456]
|
|
- 200 packets (start 433520640): 3 chunk(s) [1216512, 1118208, 1171456]
|
|
- 237 packets (start 433444864): 3 chunk(s) [1292288, 1118208, 1171456]
|
|
- 238 packets (start 433442816): 3 chunk(s) [1294336, 1118208, 1171456] <== MATCHES THE DECODER
|
|
- 239 packets (start 433440768): 3 chunk(s) [1296384, 1118208, 1171456]
|
|
- 300 packets (start 433315840): 5 chunk(s) [57344, 45056, 1294336, 1118208, 1171456]
|
|
- 400 packets (start 433111040): 8 chunk(s) [59392, 59392, 47104, 47104, 45056, 1294336, 1118208, 1171456]
|
|
|
|
# -238 is a real boundary, not the end of a sweep: at -300 and -400 the
|
|
# PREVIOUS asset's chunks appear (57344, 45056, ...) while the three ADV
|
|
# sizes stay exactly stable. The stream starts at -238 and something else
|
|
# ends just before it.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# DISC-WIDE (examples/voice_region_start_audit.rs, full table in
|
|
# voice-region-start-audit.txt)
|
|
#
|
|
# 1-chunk regions: 24 of 24 start at a chunk boundary
|
|
# 3-chunk regions: 8 of 10 START MID-STREAM
|
|
#
|
|
# So the defect is specific to the three-stream (multichannel) voice regions.
|
|
#
|
|
# ⚠️ The audit's "243" column is an UPPER BOUND on the clip, not the clip. Its
|
|
# stopping rule is "step back until the chunk COUNT changes", and to_xma_riffs
|
|
# will happily absorb a few packets of the PREVIOUS asset into the first chunk
|
|
# before that happens -- for ADV it reports 243 where the decoder-verified
|
|
# answer is 238. Only ADV has external ground truth.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# WHY (examples/voice_region_start_why.rs), and the FIX (cap_sweep)
|
|
#
|
|
# The resolver picks start = the predecessor cue's trailer, then filters it with
|
|
# .filter(|&s| s < end && end - s < 1_500_000)
|
|
# "only within one bank (~1.5 MB), else this is the first cue in its block and
|
|
# the audio starts at the anchor itself".
|
|
#
|
|
# ADV's predecessor sits 3 618 816 B before `end`. The filter REJECTS it, and the
|
|
# start falls back to `anchor` -- a TOC offset, not a stream boundary:
|
|
#
|
|
# movie id anchor pred(before) span chosen
|
|
# ADV 1600 433930240 433425776 3618816 anchor <- REJECTED
|
|
#
|
|
# predecessor 433425776 + 17 040 B of descriptor/padding = 433442816,
|
|
# which is exactly the -238 packet start measured against the decoder.
|
|
#
|
|
# 17 of 95 resolving movies hit this. Reading from the predecessor instead:
|
|
#
|
|
# anchor (today) start 433930240 -> [806912, 1118208, 1171456]
|
|
# predecessor (proposed) start 433425776 -> [1294336, 1118208, 1171456] MATCHES
|
|
#
|
|
# DISC-WIDE CONSEQUENCE of dropping the cap (voice-region-cap-sweep.txt):
|
|
# unchanged 78 fixed-cleanly 17 would-break 0 skipped 9
|
|
# In all 17 the first chunk GROWS and every later chunk is byte-identical --
|
|
# which is what a corrected start looks like, and what pulling in a neighbouring
|
|
# asset does not.
|