Runtime bitrate endpoint + ABR capability negotiation (Foundation/Moonlight V+ compatible)#273
Runtime bitrate endpoint + ABR capability negotiation (Foundation/Moonlight V+ compatible)#273AsafMah wants to merge 1 commit into
Conversation
Lets Foundation/Moonlight V+ clients change the encoder bitrate mid-stream
without reconnecting.
Endpoints (HTTPS, paired client, View permission):
- GET /bitrate?bitrate=<kbps> apply a new encoder bitrate to the caller's
active session. Clamped to config max_bitrate and an absolute 500 Mbps ceiling.
Returns <root status_code=200><bitrate>N</bitrate></root> (0 = failure), the
shape V+ NvHTTP.setBitrate() parses (and verifyResponseStatus requires the
status_code attribute).
- GET /api/abr/capabilities reports {supported:false,...}; verified against
AdaptiveBitrateService.kt this makes V+ run its local ABR controller, which
drives the host via /bitrate. Server-side ABR decisioning (/api/abr,
/feedback) is intentionally out of scope.
Apply path: a per-session mail event (dynamic_bitrate), coalesced to the latest
value on the encode thread. NVENC reconfigures the live encoder via
nvEncReconfigureEncoder (no hitch; ported from foundation-sunshine, adapted to
Vibepollo's runtime-versioned NVENC structs). avcodec encoders (AMD/Intel/
software) report set_bitrate()==false and fall back to an encode-session rebuild
via the existing reinit path -- correct, but produces a brief hitch per change.
Not yet compiled (needs the MSYS2/MinGW toolchain); review/runtime test pending.
|
Thanks for putting this together. The runtime bitrate path looks like the right direction for Moonlight V+ / Foundation-compatible clients, and I agree with keeping the paired-client I do want to call out one integration issue before this lands: any non-RTSP / Web UI-facing controls need to be registered through the normal API route layer, not only through the NvHTTP server. Right now these endpoints are registered directly on the GameStream/NvHTTP server:
That is fine for the Moonlight-compatible paired-client path, because those requests authenticate with the paired client certificate and For the Web UI/admin/API-token surface, I think we should add a separate managed API route, for example:
That route should be registered with The split I would like to see is:
One other compatibility note: this PR does not make stock/legacy Moonlight clients client-driven adaptive bitrate clients. Stock Moonlight negotiates bitrate at stream startup and does not call this endpoint. Legacy clients can still benefit from server-driven runtime bitrate changes if the host changes encoder bitrate transparently, but any manual slider or client-side ABR behavior requires a client that knows how to call This comment was AI generated, but has been peer reviewed by the repository owner. |
|
Thanks — and agreed on the split. To confirm scope: this PR is intentionally paired-client only. Both For an admin/Web-UI bitrate control I'm happy to add a separate managed route in Fully agree on the compatibility note: stock Moonlight negotiates bitrate at startup and never calls this, so manual-slider / client-ABR behavior needs a client that knows the endpoint (V+). Legacy clients only benefit from host-driven changes. This comment was drafted with an AI assistant and reviewed by me before posting. |
|
Update: this is now runtime-verified (updated the description's Verification section). On Windows with NVENC (AV1), driving the bitrate from Moonlight V+ applies changes in place via the live The avcodec reinit-fallback path (AMD/Intel/SW) still hasn't been exercised — if anyone runs one of those backends, the same flow should log This comment was drafted with an AI assistant and reviewed by me before posting. |
Implements #272 — runtime (mid-stream) bitrate changes so Foundation / Moonlight V+ clients can adjust encoder bitrate without reconnecting.
Endpoints (HTTPS, paired client, View permission)
GET /bitrate?bitrate=<kbps>— apply a new encoder bitrate to the caller's active session. Clamped tomax_bitrateand an absolute 500 Mbps ceiling. Returns<root status_code=200><bitrate>N</bitrate></root>(0= failure) — the exact shapeNvHTTP.setBitrate()parses (and itsverifyResponseStatusrequires thestatus_codeattribute).GET /api/abr/capabilities— returns{"supported":false,"version":1,"features":["runtime_bitrate"]}. Verified againstAdaptiveBitrateService.kt:supported:falsemakes V+ run its local ABR controller, which drives the host through/bitrate. So both the manual slider and adaptive mode work. Server-side ABR decisioning (POST /api/abr,/feedback) is intentionally out of scope.Apply mechanism
A per-session mail event (
dynamic_bitrate), coalesced to the latest value on the encode thread:nvEncReconfigureEncoderusing saved init params (ported from foundation-sunshine, adapted to Vibepollo's runtime-versioned NVENC structs /api::reconfigure_params_version). Seamless, no hitch.set_bitrate()==falseand fall back to an encode-session rebuild via the existing reinit path. Correct, but a brief hitch per change. Backend-native AMF/QSV reconfigure is a possible follow-up (mirrors foundation staging NVENC first, AMF later).Clamping/overflow: rejects
<=0, clamps tomax_bitrate(when set) and an absolute ceiling;set_bitrate()also rejects>800000 kbpssokbps*1000cannot overflow the 32-bit rate-control fields.Files
globals.h(event),stream.{h,cpp}(set_bitrate_for_sessions, per-session event),video.{h,cpp}(encode_session_t::set_bitrate, NVENC override, both encode paths),nvenc/nvenc_base.{h,cpp}(set_bitratelive reconfigure),nvhttp.cpp(routes).Verification
ninja sunshine→sunshine.exelinks cleanly (no undefined symbols from the new functions). NVENC reconfigure struct fields/version confirmed against the bundledffnvcodec/nvEncodeAPI.h.NvHTTP/AdaptiveBitrateServicesource.nvEncReconfigureEncoderpath is exercised: as the client's bitrate control moved (e.g. 20000↔21000 kbps), the host applied each change in place — no encoder rebuild, no reconnect. Host log:resetEncoder+forceIDR); no full reinit. The avcodec reinit-fallback path (AMD/Intel/SW) hasn't been exercised yet.Client reference:
qiin2333/moonlight-vplus(NvHTTP.setBitrate,getAbrCapabilities,AdaptiveBitrateService). Server reference:AlkaidLab/foundation-sunshine(#193/bitrate+ NVENC reconfigure, #571/api/abr/*, ClassicOldSong#690max_bitrateclamp).