Skip to content

fix(video): black flash / black-on-connect at the canvas→sink handoff#270

Open
rmounce wants to merge 2 commits into
selkies-project:comprehensive-fixesfrom
rmounce:rmounce/cf-sink-handoff
Open

fix(video): black flash / black-on-connect at the canvas→sink handoff#270
rmounce wants to merge 2 commits into
selkies-project:comprehensive-fixesfrom
rmounce:rmounce/cf-sink-handoff

Conversation

@rmounce

@rmounce rmounce commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

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 — 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.

Reproduced both symptoms and verified the fix on an lsio-based image (Firefox and Chrome clients, Intel laptop, software x264).

🤖 Generated with Claude Code

ehfd and others added 2 commits July 7, 2026 13:17
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>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@ehfd ehfd force-pushed the comprehensive-fixes branch 2 times, most recently from 155eb0b to de77558 Compare July 7, 2026 10:25
@ehfd

ehfd commented Jul 7, 2026

Copy link
Copy Markdown
Member

Fixes incorporated in de77558, linuxserver/pixelflux@b32a178, linuxserver/pcmflux@0cbadcb.

@ehfd ehfd force-pushed the comprehensive-fixes branch 18 times, most recently from 3bab531 to 4de4c8a Compare July 9, 2026 07:07
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.

2 participants