fix(video): black flash / black-on-connect at the canvas→sink handoff#270
Open
rmounce wants to merge 2 commits into
Open
fix(video): black flash / black-on-connect at the canvas→sink handoff#270rmounce wants to merge 2 commits into
rmounce wants to merge 2 commits into
Conversation
The full-frame H.264 presenters hide the main canvas the moment the first frame is written to the takeover sink (<video> track generator or the worker's OffscreenCanvas). At that point the sink usually hasn't rendered anything yet: a track frame written before the <video> starts playing back isn't shown until the next frame arrives, and the worker draws its first transferred frame asynchronously. The result is a black flash at the canvas->sink handoff (Firefox / worker canvas), and on Chromium — where frames go to the main-thread MediaStreamTrackGenerator from the very first frame, so the canvas never has content — a black screen on connect that lasts until the next screen update (indefinitely on a static desktop). Gate the canvas hide on the sink provably rendering: a requestVideoFrameCallback for the <video> sinks, and a one-time 'presented' message from the worker after its first drawImage. Until then the main-thread MSTG path also keeps painting incoming frames onto the canvas, so a fresh connection shows content immediately. Browsers without requestVideoFrameCallback keep the old behavior. Both symptoms reproduced on the comprehensive-fixes stack on an lsio-based image (Firefox handoff flash, Chromium black-on-connect). Co-authored-by: Claude <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Code Review
This pull request introduces a handoff gate mechanism to prevent a black flash when transitioning from the main canvas to a takeover sink (such as a
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
155eb0b to
de77558
Compare
Member
|
Fixes incorporated in de77558, linuxserver/pixelflux@b32a178, linuxserver/pcmflux@0cbadcb. |
3bab531 to
4de4c8a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The full-frame H.264 presenters hide the main canvas the moment the first frame is written to the takeover sink (
<video>track generator, or the worker's OffscreenCanvas). At that point the sink usually hasn't rendered anything yet: a track frame written before the<video>starts playing isn't shown until the next frame arrives, and the worker draws its first transferred frame asynchronously. On Firefox (worker canvas) this is a brief black flash a few seconds after connecting, when the first screen update lands; on Chromium — where frames go to the main-thread MediaStreamTrackGenerator from the very first frame, so the canvas never has content — the stream is black from connect until the next screen update, which on a static desktop can be indefinitely.Fix: gate the canvas hide on the sink provably rendering —
requestVideoFrameCallbackfor the<video>sinks, and a one-timepresentedmessage from the worker after its firstdrawImage. Until then the main-thread MSTG path also keeps painting incoming frames onto the canvas, so a fresh connection shows content immediately. Browsers withoutrequestVideoFrameCallbackkeep the old behavior.Reproduced both symptoms and verified the fix on an lsio-based image (Firefox and Chrome clients, Intel laptop, software x264).
🤖 Generated with Claude Code