Skip to content

feat(video): add support for legacy MPEG-2 and H.263+ encoders - #5194

Draft
ReenigneArcher wants to merge 5 commits into
masterfrom
feat/legacy-encoders
Draft

ReenigneArcher wants to merge 5 commits into
masterfrom
feat/legacy-encoders

Conversation

@ReenigneArcher

@ReenigneArcher ReenigneArcher commented May 25, 2026 •

Copy link
Copy Markdown
Member

Description

Add opt-in MPEG-2/H.262 and H.263+ streaming for any client implementing the Sunshine codec extension, including Moonlight-XboxOG #194. Enable them in Advanced settings or with mpeg2_mode = 2 and h263p_mode = 2; both remain unadvertised by default.

Sunshine probes and selects each legacy codec's backend independently. Hardware MPEG-2 remains available when H.263+ falls back to software, and legacy probing no longer requires a working H.264 encoder. Hosts advertise H.264 only after a successful probe.

Capture workers are shared within each encoder backend, with separate lifetimes for different backends and monitor-switch requests broadcast to every active group. Regression tests cover both session arrival orders, cleanup/restart, failed startup, legacy-only host advertisements, strict client negotiation, and real software encode/decode round trips for both legacy codecs.

Document the client-independent capability bits, SDP identifiers, and GameStream framing. Explicit capability initialization also fixes the ARM64 Clang -Wmissing-field-initializers failure in the reported job.

The round-trip test computes its buffer size in std::size_t before multiplication, addressing the CodeQL integer-promotion finding.

The moonlight-common-c submodule is pinned to ed6b2da, shared with Moonlight-XboxOG. The nxdk-decoder-choices branch is rebased onto upstream 94c65fd. The shared codec implementation is a single source-only commit.

TODO:

Screenshot

Issues Fixed or Closed

Roadmap Issues

Testing

  • Windows UCRT64: cmake --build cmake-build-release --target sunshine test_sunshine --parallel 4 passed.
  • Full native suite: 921 passed and 12 skipped out of 933 tests, including both legacy codec round trips.
  • Windows x64 Clang syntax checks passed for the rebased video pipeline and codec round-trip test with -Werror=missing-field-initializers.
  • All 219 Web UI tests and the production Vite build passed after refreshing dependencies.
  • Strict Dockle/Doxygen documentation build passed (1,172 HTML pages).
  • uv run --locked lb-update-clang-format and git diff --check passed.
  • A fresh fetch of the pinned common-library commit through the configured upstream submodule URL passed.

Native validation covers the current native source, test, CMake, and submodule trees, which are unchanged by the final package-only master update. Web checks were rerun with the updated lockfile. The display-probing function was verified to match master's platform-specific behavior exactly after conflict resolution.

Native AMD/Quick Sync tests were skipped on this machine. Linux/macOS and ARM64 builds, full network transport, and Xbox hardware streaming were not run locally. The Web UI Markdown test used LF checkout line endings. Hosted CI results are separate from the local validation.

Type of Change

  • feat: New feature (non-breaking change which adds functionality)
  • fix: Bug fix (non-breaking change which fixes an issue)
  • docs: Documentation only changes
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semicolons, etc.)
  • refactor: Code change that neither fixes a bug nor adds a feature
  • perf: Code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • build: Changes that affect the build system or external dependencies
  • ci: Changes to CI configuration files and scripts
  • chore: Other changes that don't modify src or test files
  • revert: Reverts a previous commit
  • BREAKING CHANGE: Introduces a breaking change (can be combined with any type above)

Checklist

  • Code follows the style guidelines of this project
  • Code has been self-reviewed
  • Code has been commented, particularly in hard-to-understand areas
  • Code docstring/documentation-blocks for new or existing methods/components have been added or updated
  • Tests have been added or updated for new or modified functionality, including regression tests for bug fixes

AI Usage

See our AI usage policy.

  • AI tools were used while preparing this PR

AI tools generated much of the feature and assisted with implementation review, backend/capture changes, the shared protocol, rebasing, CI fixes, documentation, and tests.

This pull request was updated by Codex (GPT-6; thinking level not exposed by this session).

@codecov

codecov Bot commented May 25, 2026 •

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 2.07kB (0.09%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
sunshine-esm 799.62kB 2.07kB (0.26%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: sunshine-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/createLucideIcon-*.js 994 bytes 358.31kB 0.28%
assets/config-*.js 1.07kB 70.55kB 1.54%

Files in assets/createLucideIcon-*.js:

  • ./src_assets/common/assets/web/public/assets/locale/en.json → Total Size: 41.17kB

Files in assets/config-*.js:

  • ./src_assets/common/assets/web/config.html → Total Size: 0 bytes

  • ./src_assets/common/assets/web/configs/tabs/Advanced.vue → Total Size: 11.72kB

@codecov

codecov Bot commented May 25, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 41.28440% with 128 lines in your changes missing coverage. Please review.
✅ Project coverage is 18.05%. Comparing base (f81a495) to head (0b8181d).
⚠️ Report is 152 commits behind head on master.

Files with missing lines Patch % Lines
src/video.cpp 44.50% 70 Missing and 36 partials ⚠️
src/rtsp.cpp 0.00% 8 Missing and 6 partials ⚠️
src/nvhttp.cpp 0.00% 4 Missing ⚠️
src/config.cpp 0.00% 0 Missing and 2 partials ⚠️
src/video.h 71.42% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #5194      +/-   ##
==========================================
+ Coverage   17.85%   18.05%   +0.19%     
==========================================
  Files         111      111              
  Lines       24605    24793     +188     
  Branches    10894    10973      +79     
==========================================
+ Hits         4393     4476      +83     
- Misses      14945    16698    +1753     
+ Partials     5267     3619    -1648     
Flag Coverage Δ
Archlinux 11.33% <26.14%> (+0.14%) ⬆️
FreeBSD-amd64 13.51% <30.97%> (+0.27%) ⬆️
Homebrew-ubuntu-24.04 13.36% <27.45%> (+0.14%) ⬆️
Linux-AppImage 12.25% <26.79%> (+0.14%) ⬆️
Windows-AMD64 15.08% <28.10%> (+0.16%) ⬆️
Windows-ARM64 13.40% <24.26%> (+0.20%) ⬆️
macOS-arm64 19.36% <27.81%> (+0.23%) ⬆️
macOS-x86_64 18.86% <27.81%> (+0.25%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/config.h 0.00% <ø> (ø)
src/config.cpp 3.05% <0.00%> (-0.01%) ⬇️
src/video.h 61.40% <71.42%> (+1.40%) ⬆️
src/nvhttp.cpp 18.80% <0.00%> (-0.13%) ⬇️
src/rtsp.cpp 1.99% <0.00%> (-0.04%) ⬇️
src/video.cpp 33.88% <44.50%> (+1.52%) ⬆️

... and 56 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f81a495...0b8181d. Read the comment docs.

@ReenigneArcher
ReenigneArcher force-pushed the feat/legacy-encoders branch 2 times, most recently from 4b0586b to 0b8181d Compare June 24, 2026 02:56
@codecov

codecov Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 2.05kB (0.21%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
sunshine-esm 1.0MB 2.05kB (0.21%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: sunshine-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/index-*.js 990 bytes 409.41kB 0.24%
assets/Config-*.js 1.06kB 88.09kB 1.22%

Files in assets/index-*.js:

  • ./src_assets/common/assets/web/public/assets/locale/en.json → Total Size: 61.6kB

Files in assets/Config-*.js:

  • ./src_assets/common/assets/web/configs/tabs/Advanced.vue → Total Size: 11.45kB

  • ./src_assets/common/assets/web/configs/config_tabs.json → Total Size: 4.21kB

@SunshineStream SunshineStream deleted a comment from sonarqubecloud Bot Nov 13, 2026
@codecov

codecov Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 67.84741% with 118 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.54%. Comparing base (8b5ffde) to head (0659a74).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/video.cpp 58.24% 89 Missing and 25 partials ⚠️
src/rtsp.cpp 85.18% 4 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #5194      +/-   ##
==========================================
+ Coverage   50.30%   50.54%   +0.24%     
==========================================
  Files         146      149       +3     
  Lines       31717    32630     +913     
  Branches    13449    13814     +365     
==========================================
+ Hits        15954    16492     +538     
- Misses      12963    14472    +1509     
+ Partials     2800     1666    -1134     
Flag Coverage Δ
Alpine-aarch64 34.34% <32.69%> (+0.19%) ⬆️
Alpine-x86_64 34.45% <32.69%> (+0.18%) ⬆️
Archlinux 35.04% <32.43%> (+0.18%) ⬆️
FreeBSD-amd64 35.10% <33.96%> (+0.25%) ⬆️
Homebrew-macos-15 48.88% <35.63%> (+0.07%) ⬆️
Homebrew-macos-26 49.28% <36.36%> (+0.13%) ⬆️
Homebrew-ubuntu-24.04 37.35% <24.42%> (-0.03%) ⬇️
Linux-AppImage-aarch64 40.16% <33.84%> (+0.15%) ⬆️
Linux-AppImage-x86_64 40.37% <33.08%> (+0.12%) ⬆️
PowerShell 100.00% <ø> (ø)
Web-UI 58.13% <100.00%> (+0.38%) ⬆️
Windows-AMD64 40.75% <35.38%> (+0.25%) ⬆️
Windows-ARM64 34.63% <30.89%> (?)
macOS-arm64 41.90% <33.33%> (+0.19%) ⬆️
macOS-x86_64 40.80% <32.01%> (+0.21%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/config.cpp 62.97% <100.00%> (-0.19%) ⬇️
src/config.h 65.00% <ø> (ø)
src/nvhttp.cpp 68.39% <100.00%> (+0.26%) ⬆️
src/rtsp.h 71.42% <ø> (ø)
src/thread_safe.h 83.65% <100.00%> (+2.55%) ⬆️
src/video.h 79.16% <100.00%> (+3.62%) ⬆️
src/video_capture_groups.h 100.00% <100.00%> (ø)
...assets/common/assets/web/configs/tabs/Advanced.vue 87.71% <100.00%> (+9.94%) ⬆️
...ets/common/assets/web/public/assets/locale/en.json 100.00% <ø> (ø)
src/rtsp.cpp 36.29% <85.18%> (+1.23%) ⬆️
... and 1 more

... and 56 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8b5ffde...0659a74. Read the comment docs.

@github-actions

github-actions Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Last Updated 2026-11-13 17:42:54 UTC
Source Run CI Run #6745
Commit 0659a7418cf0e0d113910fb9d301dab6c6c52ba8

Screenshot Comparison

PR #5194 screenshots vs screenshots baseline.

Matrix: AppImage-aarch64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: AppImage-x86_64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: Windows-AMD64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: Windows-ARM64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: macOS-arm64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

Matrix: macOS-x86_64

Image Baseline PR
sunshine_tray_initial.png
sunshine_tray_menu.png
sunshine_tray_pairing_request.png
sunshine_tray_paused.png
sunshine_tray_stopped.png
sunshine_tray_streaming.png
sunshine_tray_tooltip.png

@sonarqubecloud

Copy link
Copy Markdown

This branch has not been deployed

No deployments
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