fix(xmf): emit the first frame immediately to avoid near-empty recordings#80
Merged
irvingouj@Devolutions (irvingoujAtDevolution) merged 5 commits intoJun 18, 2026
Conversation
… next XmfWebM_EncodeXRGB held the first submitted frame as "pending" and only encoded it once a second frame (or a forced Timeout) arrived, so it could measure the first frame's real duration. On short, sparse, or static sessions where a second frame never arrives in time, the stream produced a header-only / near-empty WebM: downstream remux fails with "parser failed" and pipe consumers hit their first-byte timeout (e.g. MsRdpEx -> Gateway recording for a frozen RDP desktop). Emit the very first frame right away using one frame interval as a provisional duration; every subsequent frame keeps the original encode-previous-with-real-duration behavior and the ms_per_frame rate cap. The Timeout (force) path is unchanged. Ref: DVLS-14562. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot started reviewing on behalf of
irvingouj@Devolutions (irvingoujAtDevolution)
June 16, 2026 18:54
View session
There was a problem hiding this comment.
Pull request overview
This PR adjusts XmfWebM_EncodeXRGB’s first-frame behavior so the encoder emits bytes on the very first submitted frame (using a provisional 1000 / frame_rate duration), preventing near-empty/header-only WebM outputs on short or static sessions.
Changes:
- Encode the first submitted frame immediately (instead of waiting for a second frame or timeout).
- Preserve the existing “encode previous frame on next event” behavior for subsequent frames (intended), while keeping the existing rate cap logic in
XmfWebM_EncodeInternal.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Separate the rate-cap throttle (last_encode_time) from the pending frame's display duration by adding a dedicated pending_frame_start_time field, and rename XmfWebM_EncodeInternal to XmfWebM_EncodePendingFrame.
Copilot started reviewing on behalf of
irvingouj@Devolutions (irvingoujAtDevolution)
June 16, 2026 19:35
View session
Comment on lines
+243
to
246
| if (ctx->pending_frame) | ||
| { | ||
| ctx->first_encode_time = XmfTimeSource_Get(&ctx->ts); | ||
| goto convert_frame; | ||
| XmfWebM_EncodePendingFrame(ctx, !srcData); | ||
| } |
Comment on lines
+267
to
+270
| if (!ctx->pending_frame) | ||
| ctx->pending_frame_start_time = ctx->frame_time; | ||
|
|
||
| ctx->pending_frame = true; |
Comment on lines
+261
to
+263
| ctx->first_encode_time = ctx->frame_time; | ||
| XmfWebM_EncodeImage(ctx, ctx->img, ctx->pts, 1000 / ctx->frame_rate); | ||
| ctx->pending_frame = false; |
Marc-André Moreau (mamoreau-devolutions)
approved these changes
Jun 16, 2026
irvingouj@Devolutions (irvingoujAtDevolution)
added a commit
to Devolutions/MsRdpEx
that referenced
this pull request
Jun 18, 2026
Adds a `VideoRecordingFrameRate` extended setting (COM property + `.rdp` entry) for the native recording path. MsRdpEx now submits every captured paint and lets cadeau cap the encode rate to the configured frame rate; the per-paint `Timeout` force-encode is removed because it bypassed that cap and produced ~24fps oversized recordings. The rate is clamped to 30 to match cadeau's recorder max. Note: when the frame rate is unset (0), cadeau falls back to its own default cap rather than the previous force-every-paint behavior. Requires the cadeau eager-first-frame fix (Devolutions/cadeau#80) so static recordings still emit a first frame promptly — the two PRs should ship together. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
We observed that RDM session recording sometimes fails with a recording-policy violation on static recordings. The cause is that the encoder held the first frame until a second one arrived, so a frozen/idle session produced a near-empty WebM and no valid recording ever reached the Gateway. This change emits the first frame eagerly so the Gateway always receives a frame.