[DVLS-14562] Add frame rate control to video recording#169
Merged
irvingouj@Devolutions (irvingoujAtDevolution) merged 6 commits intoJun 18, 2026
Merged
Conversation
The native recorder previously honored only VideoRecordingQuality, so it recorded at the full desktop resolution and the native paint cadence, ignoring the FPS/resolution configured by the client. - RdpSettings: parse and expose new VideoRecordingFrameRate / VideoRecordingWidth / VideoRecordingHeight extended properties (and .rdp file entries), mirroring VideoRecordingQuality. - ApiHooks: forward the new values to the OutputMirror. - OutputMirror: downscale the captured frame to the requested resolution via StretchBlt before encoding, drive the encoder frame rate, and throttle the paint-driven encode cadence to the configured FPS. No cadeau/xmf change required (the encoder already exposes SetFrameRate / SetFrameSize). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dropped the resolution downscaling work (StretchBlt scaled DIB and the VideoRecordingWidth / VideoRecordingHeight extended properties) to keep the change focused. Only the VideoRecordingFrameRate extended property and the paint-cadence throttle remain, plus frame-rate input clamping/validation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Submit every captured paint and rely on cadeau's frame-rate cap (ms_per_frame) instead of a per-paint Timeout force-encode, which bypassed the cap and produced ~24fps oversized recordings. The frame rate is conveyed once via SetFrameRate in Init.
Match the existing VideoRecordingQuality idiom: remove the redundant VariantToNonNegativeUInt32 helper, clamp the frame rate once at the input boundary, and stop re-clamping in the output mirror. Also revert an unrelated PowerShell packages.lock.json change.
Copilot started reviewing on behalf of
irvingouj@Devolutions (irvingoujAtDevolution)
June 16, 2026 20:38
View session
There was a problem hiding this comment.
Pull request overview
This PR adds a configurable frame-rate control for native RDP video recording by introducing a new extended setting (VideoRecordingFrameRate), propagating it through the capture hook layer, and applying it to the recording pipeline.
Changes:
- Added
VideoRecordingFrameRateto extended settings (COM property +.rdpentry), including validation and an upper bound. - Forwarded the configured frame rate from
ApiHooksinto theOutputMirror. - Applied the frame rate to the underlying recorder initialization and adjusted per-paint recording behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| include/MsRdpEx/RdpSettings.h | Adds the VideoRecordingFrameRate getter and backing field to extended settings. |
| dll/RdpSettings.cpp | Parses/returns the new extended property and reads it from .rdp files. |
| include/MsRdpEx/OutputMirror.h | Adds an API to pass frame-rate configuration into OutputMirror. |
| dll/ApiHooks.cpp | Reads VideoRecordingFrameRate from settings and forwards it to OutputMirror. |
| dll/OutputMirror.c | Stores/applies the configured FPS to the recorder and changes paint-driven encode behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Clamp VideoRecordingFrameRate to 30 to match cadeau's recorder max (was 60, which the encoder silently capped). Read intVal for VT_I4 and treat negatives as 0 so .rdp-parsed values are not reinterpreted as large unsigned numbers.
Marc-André Moreau (mamoreau-devolutions)
approved these changes
Jun 16, 2026
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.
Adds a
VideoRecordingFrameRateextended setting (COM property +.rdpentry) 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-paintTimeoutforce-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.