Skip to content

fix(wgc): don't delay a requested keyframe behind a repeated direct frame - #348

Merged
RamazanKara merged 1 commit into
canaryfrom
fix/wgc-direct-idr-retry
Oct 23, 2026
Merged

RamazanKara merged 1 commit into
canaryfrom
fix/wgc-direct-idr-retry

Conversation

@RamazanKara

Copy link
Copy Markdown
Collaborator

Follow-up to #347.

With direct encoder input, the encoder can pop an image whose pixels it has already sent and skip it as a repeat. If a keyframe request arrived in that same loop iteration, the skip used to carry on and wait for the next capture. The IDR then waited behind a new frame, up to max_frametime on a static desktop, where the copy path would have sent it right away.

The async loop now carries the request into the next iteration, which takes the existing IDR-without-a-new-image path and encodes the last input as the keyframe without waiting. The sync loop encodes the last input as the IDR in the same pass. Both loops decide through policy::retry_idr_after_repeat, covered by ConvertedInputPolicy.RepeatedFrameKeepsARequestedKeyframePending.

Found while reviewing the Vibepollo port of #347. This one is checked by its unit test and CI only; it hasn't had its own stream run.

…rame

With direct encoder input, the async encode loop can pop an image whose
conversion reports pixels the session already sent, and skips it. If a
keyframe had been requested in that iteration, the next iteration started
with the request cleared and waited up to max_frametime in images->pop(),
so on a static desktop the IDR only went out with the next capture or the
minimum-FPS timeout. The copy path encodes it immediately.

The loop now carries the request into the next iteration (retry_idr), which
takes the existing requested-IDR path: no wait, the last input is encoded
as the IDR. If another image is already queued it is popped first, as
before. The decision lives in video::policy::retry_idr_after_repeat, so a
repeat with a keyframe request retries, a plain repeat is a skip, and a
converted frame never retries.

The synchronous loop keeps the pending IDR in the session, so no request
was lost, but it skipped the repeat and only sent the IDR on the next
capture callback. It now encodes the last input as the IDR in the same
pass when a keyframe was requested for that session, with the stamps left
unset like the no-new-frame path.

Follow-up to #347.

Signed-off-by: Ramazan Kara <github@r-kara.de>
@RamazanKara
RamazanKara merged commit 28f086f into canary Oct 23, 2026
17 checks passed
@RamazanKara
RamazanKara deleted the fix/wgc-direct-idr-retry branch October 23, 2026 02:01
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