re: FFmpeg stops on the LAST frame — my "partial decode" claim was wrong
I had been discarding FFmpeg's stderr with Stdio::null(). It says exactly what happens: an unimplemented "Reserved bit", then a negative bit-skip -- and the failing frame index is always the last one. bank packets frames fr/packet fails at VOICE_D_450 8 45.7 5.71 44 VOICE_D_452 7 29.4 4.21 28 VOICE_D_453 22 198.9 9.04 198 VOICE_D_454 29 287.5 9.92 287 So the previous entry's "the decodes are visibly partial" is wrong, and it was mine. I read "samples per input byte ranges 2.10-4.96" as truncation; it is ordinary XMA1 variable bitrate. Only the final frame of each stream is lost. The decode is essentially complete. The sample rate still does not converge. I tried the obvious repair -- counting the whole bank, leading region plus RIFF sub-waves, since the two split the audio very differently per bank. Two banks then agreed at a tidy ~2.1x ratio pointing near 22 kHz, and the third refuted it: implied rates are 39742, 20563 and 23108 Hz. So the container is identified, the decode is essentially complete, and the duration still does not reconcile -- which moves suspicion to the other side of the comparison. movie_subtitle::track_voice_cues returns (u32, f32) and I have been reading that f32 as SECONDS on the strength of the format notes describing mm:ss.cc cue text. If it is centiseconds, a frame index or a per-page offset, every "audio missing" verdict inherits the error. Recorded as the next thing to check, and to be checked BEFORE any more audio work. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
This commit is contained in:
@@ -1075,9 +1075,22 @@ premise was wrong.**
|
||||
converge** — 21 665 Hz for `D_453` (temptingly near 22 050, and I nearly wrote
|
||||
it down) but **5 844 Hz** for `D_450`. The decodes are partial: samples per
|
||||
input byte ranges 2.10–4.96 where a clean decode would be near-constant.
|
||||
▶️ Next: find why FFmpeg stops early — likely the packet/subframe fields in the
|
||||
synthesised `fmt`, which are hardcoded (`SubframeData = 4`, `NumStreams = 1`).
|
||||
See
|
||||
✅ **(same day) Why FFmpeg stops is captured** — I had been discarding its
|
||||
stderr. It reports an unimplemented "Reserved bit" and a negative bit-skip, and
|
||||
the failing frame is always the **last** one (44 of 45.7, 28 of 29.4, 198 of
|
||||
198.9, 287 of 287.5). ❌ **That corrects my own previous claim**: "the decodes
|
||||
are visibly partial" was wrong — the 2.10–4.96 samples-per-byte spread is
|
||||
ordinary XMA1 variable bitrate (4.21–9.92 frames per packet), and only the
|
||||
final frame is lost. ❌ The sample rate still does not converge, including
|
||||
after counting leading region + RIFF together: 39 742 / 20 563 / 23 108 Hz for
|
||||
the three banks with a usable cue. Two of them agreed at a tidy ~2.1× ratio and
|
||||
the third refuted it.
|
||||
🟡 **▶️ Check the OTHER side of the comparison first.**
|
||||
`movie_subtitle::track_voice_cues` returns `(u32, f32)` and I have been reading
|
||||
that `f32` as seconds. If it is centiseconds, a frame index, or a per-page
|
||||
offset, every "audio missing" verdict inherits the error. Cheap to settle
|
||||
against a movie of independently known length, and it should be settled before
|
||||
any further audio work. See
|
||||
[`voice-bank-leading-region.md`](voice-bank-leading-region.md).
|
||||
* ❌ **(2026-08-25) My own boot-nav diagnosis, MEASURED AND WITHDRAWN.** I said
|
||||
the run died because `skip_intro.sh` gates the title test at `rmse <= 1500`
|
||||
|
||||
@@ -173,7 +173,31 @@ its leading region is the all-zero one.
|
||||
The sample rate and channel mask make **no difference to the decoded byte
|
||||
count** — as expected, since they set playback speed rather than sample count.
|
||||
|
||||
## ❌ Solving for the sample rate from the subtitle cue — does NOT converge
|
||||
## ✅ Why FFmpeg stops — and a correction to my own claim
|
||||
|
||||
I had been discarding FFmpeg's stderr. It says exactly what happens:
|
||||
|
||||
```
|
||||
Reserved bit is not implemented. …your file has a feature which has not been implemented.
|
||||
frame[198] would have to skip -2070 bits
|
||||
```
|
||||
|
||||
And the frame index is always the **last** one:
|
||||
|
||||
| bank | packets | frames decoded | frames/packet | fails at frame |
|
||||
|---|---|---|---|---|
|
||||
| `VOICE_D_450` | 8 | 45.7 | 5.71 | **44** |
|
||||
| `VOICE_D_452` | 7 | 29.4 | 4.21 | **28** |
|
||||
| `VOICE_D_453` | 22 | 198.9 | 9.04 | **198** |
|
||||
| `VOICE_D_454` | 29 | 287.5 | 9.92 | **287** |
|
||||
|
||||
❌ **So the previous entry's "the decodes are visibly partial" is WRONG, and it
|
||||
was mine.** I read "samples per input byte ranges 2.10–4.96" as evidence of
|
||||
truncation. It is not: XMA1 is variable-bitrate, frames per packet genuinely
|
||||
range 4.21–9.92 here, and the only thing actually lost is the **final frame** of
|
||||
each stream. The decode is essentially complete.
|
||||
|
||||
## ❌ Solving for the sample rate from the subtitle cue — still does NOT converge
|
||||
|
||||
`decoded samples / last subtitle cue` should give the real rate if the decode
|
||||
were complete. It does not agree with itself:
|
||||
@@ -184,12 +208,35 @@ were complete. It does not agree with itself:
|
||||
| `VOICE_D_450` | 23 378 | 4.00 s | **5 844 Hz** |
|
||||
|
||||
21 665 Hz is temptingly close to 22 050, and I nearly wrote that down. The second
|
||||
bank refutes it: no single rate explains both. The decodes are also visibly
|
||||
**partial** — decoded samples per input byte ranges 2.10 to 4.96 across the
|
||||
banks, where a clean decode would be near-constant — so FFmpeg is not consuming
|
||||
these streams to the end.
|
||||
bank refutes it: no single rate explains both.
|
||||
|
||||
So: the container is identified, the duration is not.
|
||||
I then tried the obvious repair — count the **whole bank**, leading region plus
|
||||
RIFF sub-waves, since the two split the audio very differently per bank (`D_450`
|
||||
is mostly RIFF, `D_453` mostly leading region). Two banks then agreed at a
|
||||
suspiciously tidy ~2.1× ratio, which would put the rate near 22 kHz. The third
|
||||
refutes that too:
|
||||
|
||||
| bank | leading | RIFF | total samples | cue | implied |
|
||||
|---|---|---|---|---|---|
|
||||
| `VOICE_D_450` | 23 378 | 135 589 | 158 967 | 4.00 s | **39 742 Hz** |
|
||||
| `VOICE_D_451` | 448 | 75 636 | 76 084 | 3.70 s | **20 563 Hz** |
|
||||
| `VOICE_D_453` | 101 824 | 6 784 | 108 608 | 4.70 s | **23 108 Hz** |
|
||||
|
||||
So: the container is identified, the decode is essentially complete, and the
|
||||
duration still does not reconcile.
|
||||
|
||||
## 🟡 Where the tension probably is now
|
||||
|
||||
The audio side has stopped looking suspect: mono XMA1, decoded to the last
|
||||
frame. The link I have *not* checked is the other one — `movie_subtitle::
|
||||
track_voice_cues` returns `(u32, f32)`, and I have been reading that `f32` as
|
||||
seconds because the format notes describe `<mm:ss.cc>` cue text. If it is
|
||||
anything else — centiseconds, a frame index, a per-page offset — every "audio
|
||||
missing" verdict above inherits the error.
|
||||
|
||||
**That is the next thing to check, and it should be checked before any more work
|
||||
on the audio.** It is cheap: a cue on a movie whose length is known independently
|
||||
would settle the unit.
|
||||
|
||||
## ❔ The first attempt at this — inconclusive, and for a boring reason
|
||||
|
||||
|
||||
Reference in New Issue
Block a user