镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

TST fix intermittent blank frame in the MP4 playback check - #767

Open
kroq-gar78 wants to merge 2 commits into
devfrom
tst-mp4-playback-race
Open

kroq-gar78 wants to merge 2 commits into
devfrom
tst-mp4-playback-race

Conversation

@kroq-gar78

@kroq-gar78 kroq-gar78 commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

test_rendering_downloads_an_mp4 fails intermittently on CI with:

AssertionError: {'width': 320, 'height': 240, 'duration': 0.2, 'lit': 0}

indicating that the rendered frame is blank.

Likely cause

The MP4 is fine, but the check that plays it back is racy. The test loads the file into a <video> and draws it into a canvas on loadeddata. Chromium can fire loadeddata before the first decoded frame reaches the element, so drawImage draws nothing and every pixel reads as unlit.

Evidence, from playing one saved MP4 repeatedly with the old page under load (16 playbacks at once on 24 cores):

  • lit == 0 in 10 of 400 runs. The other 390 drew the full frame from the same file.
  • Each failure left the canvas fully transparent. A black frame from the encoder would be opaque, since the muxer paints black under every frame. So these failures drew nothing at all.
  • It only occurs with several cores in use. Heavy load on a single core never triggered it, which fits a race between threads.
  • 40 MP4s rendered by the test under the same load all decode with every frame lit in FFmpeg.

Fix

The playback page now waits for video.requestVideoFrameCallback, which fires once a frame has been presented, and then draws it once. If no frame arrives within 10 s, it returns an error. A frame normally arrives within 20 ms; the slowest run under load took 141 ms.

Under the same load the new page drew the full frame in 400 of 400 runs. Bad files still fail: an all-black video fails the lit check, and truncated or garbage files fail with a decode error.

Annotate test_rendering_downloads_an_mp4 and the helpers it uses:
_render_setup, _mp4_boxes, _find_box, _play_mp4, _js_value and _js_attrs.
A recursive _Box alias describes the MP4 box tree. _find_box now asserts
that the box it returns holds data rather than child boxes, and the test
asserts that fps is a number, so the rest type-checks under mypy.
The playback check drew the video into a canvas on loadeddata, but
Chromium can fire loadeddata before the first decoded frame is ready to
draw. drawImage then paints nothing, and the test failed intermittently
with lit == 0 although the file was well formed. Wait instead for
requestVideoFrameCallback, which fires once a frame has been presented,
and report an error if none is within 10 s.

Under contention (16 concurrent playbacks on 24 cores) the loadeddata
page gave lit 0 in 10 of 400 runs, each time with a fully transparent
canvas, i.e. nothing drawn rather than a black frame. The
requestVideoFrameCallback page gave the full frame in 400 of 400. A
black H.264 video still fails on lit, and truncated or garbage files
fail with a decode error.
@kroq-gar78 kroq-gar78 changed the title Tst mp4 playback race TST fix intermittent blank frame in the MP4 playback check Oct 22, 2026
@kroq-gar78
kroq-gar78 marked this pull request as ready for review October 23, 2026 00:17

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant