fix(alerts): wire the frame-rate probe so alert-clip VIDEO paces to real time
The 12:35 live session proved the decoder healthy (frames=240 audioChunks=156 failed=False both clips, alert audio in the mix at peakMix 0.277→0.733) yet the creator still saw 'no video plays / you lost the video'. Root cause: pacing, not decode. AlertClipDecoderFor built the decoder with no frameRateProbe, so RunAsync computed frameDuration = TimeSpan.Zero and RunVideoAsync's pace step was dead code — all 240 frames of the 10s clip dumped through the pipe in the first ~1-2s (130MB as fast as ffmpeg read), then the box froze on the LAST frame while audio chunk-paced its real-time ~7.8s. Reads exactly like a dead decoder on screen. The media path already wired this seam (MainViewModel.cs:308); the alert factory never supplied one. Derivative fix (media/decoder plumbing, cited in broad consensus of players): pass FfmpegFrameRateProbe into the per-play alert decoder exactly like MediaVideoSource does. Good Dog: AlertClipDecoderTests.AlertClipDecoder_PacesVideoFramesToTheProbedFrameRate — real AlertClipDecoder via the fake-process/fake-probe/delay-recorder seam; red on the old factory (zero pacing delays), green with the probe (one ~10ms delay per frame at 100fps). Full suite 321/322, one known-env flake (RealMouseDrag reorder). Docs in this commit: task-47 addendum, MyMistakes.md (a decoder that drops data faster than wall-clock looks identical to a dead one), HANDOFF rewrite.
This commit is contained in:
@@ -177,6 +177,34 @@ idle. This lands the corpus at 321, with the one known-env flake (RealMouseDrag
|
||||
passes with no fullscreen windows up) — unrelated to this change. Unit was the direct
|
||||
lineage of bug surface: **a decoder booth production failure surfaces as dead air.**
|
||||
|
||||
## Video-frame pacing fix (2026-09-26)
|
||||
|
||||
Second creator repro after the fallback commit (12:35 session): decoder HEALTHY —
|
||||
`Alert clip start: box …` → `Alert clip end: … frames=240 audioChunks=156 failed=False`
|
||||
twice, alert audio in the live mix (`peakMix 0.277 → 0.733`, mic/loop 0.000) — yet
|
||||
"no video plays in the web-alert box", "like you lost the video". The hole was never
|
||||
decode: **the video pipe was unpaced.** `AlertClipDecoderFor` (MainViewModel.Chat.cs:113)
|
||||
built the decoder with no `frameRateProbe`, so `RunAsync` computed
|
||||
`frameDuration = TimeSpan.Zero` and `RunVideoAsync`'s pace (`if (frameDuration > 0)`)
|
||||
was skipped — all 240 frames (a 10s, 680×200 clip, ~130MB) dumped through the pipe in
|
||||
the first ~1-2s as fast as ffmpeg read them, then the box sat on the LAST frame frozen
|
||||
for the remaining ~6-8s while the audio chunk-pacer (50ms/chunk × 156) ran out its
|
||||
real-time cadence. To the eye: a blur then a dead frame = "no video / you lost the
|
||||
video". The media path already wired exactly this seam (`MediaVideoSource` gets
|
||||
`frameRateProbe: new FfmpegFrameRateProbe(…)`, MainViewModel.cs:308) — the alert
|
||||
factory just never supplied one.
|
||||
|
||||
Fix (commit `…`): `AlertClipDecoderFor` now passes
|
||||
`frameRateProbe: new FfmpegFrameRateProbe(new FfmpegLocator(), () => new FfmpegDecodeProcess())`
|
||||
so the 240 frames pace at the clip's native ~24fps (10s real-time), matching the audio
|
||||
cadence. Good Dog test `AlertClipDecoderTests.AlertClipDecoder_PacesVideoFramesToTheProbedFrameRate`
|
||||
drives the REAL `AlertClipDecoder` through the same fake-process/fake-probe seam the
|
||||
media test uses (3 frames, probe 100fps → one ~10ms pacing delay per frame) — red on
|
||||
the old factory (no delay), green with a probe. Full suite 321/322, one known-env flake
|
||||
(RealMouseDrag reorder). **Derivative lesson → `MyMistakes.md`: a decoder that reads
|
||||
faster than wall-clock needs an explicit pace; "plays but you don't see it" is pacing,
|
||||
not decode.**
|
||||
|
||||
## Open follow-ups (NOT this unit)
|
||||
|
||||
- TASK 3 item 20 (RewardEvent SQLite persistence half) and item 16 (Text source) remain
|
||||
|
||||
Reference in New Issue
Block a user