Releases: vibesoftwarecoder/ApolloVibe
Release list
ApolloVibe 2026.6.1-ms5
This release fixes a permission bypass, a display-mode remapping bug, and rounds out the test suite and docs. Everything from ms4 is included.
Security fix
A client paired with only view permission — the default for every device paired after the first — could terminate the app another user was running. launch()'s permission-downgrade check was meant to exclude terminate requests, but its exclusion clause missed two paths into the terminate branch. A single predicate now covers both, and terminating always requires launch, the same requirement /cancel already had.
Filed upstream as ClassicOldSong/Apollo#1606, since the same code exists there unchanged.
Behaviour change: a view-only client can no longer terminate an app it had joined, by any route.
Display mode remapping fix
A remapping entry with a Requested FPS never matched, so it was silently skipped. Apollo stores the session refresh rate in millihertz, and the comparison used exact struct equality against the entry's plain fps value, which could never match. Remapping now compares by value.
Behaviour change: entries with a Requested FPS that were silently skipped will now apply. An earlier entry can win over a later one, since the first match is used. Clients streaming at a fractional rate such as 59.94 still will not match an integer entry.
Documentation
16 config options that Apollo added over 2024-2025 had no entry in docs/configuration.md, because upstream Apollo never documented them. They are documented now: global_state_cmd, hide_tray_controls, enable_pairing, enable_discovery, enable_input_only_mode, forward_rumble, keep_sink_default, auto_capture_sink, fallback_mode, headless_mode, double_refreshrate, limit_framerate, envvar_compatibility_mode, legacy_ordering, ignore_encoder_probe_failure and nvenc_intra_refresh.
Also from ms4
Early config failures write sunshine-startup-error.log next to the executable and exit with code 2 instead of 0. See the ms4 notes.
How this was checked
The full unit test suite passes: 237 tests, 233 passed, 4 skipped (the Windows-only mouse tests), 0 failed, with audio, encoder, download and external-command tests excluded.
The security and remapping fixes were confirmed in the binary: both changed source files (src/nvhttp.cpp, src/display_device.cpp) were recompiled and linked into this build, checked by object and link timestamps.
Not tested by execution. The permission fix has no existing test harness for launch(); it was verified by hand-tracing every branch, not by running a live server. Nobody has run this build against a real client or display.
Install
apollovibe-windows-x64.zip is the complete portable build: sunshine.exe, assets/ and tools/. MultiSeat's installer pulls it from releases/latest/download/ and needs no change.
SHA-256 of sunshine.exe:
95083822664BCA479C895B935B5A83EFE0D2960986360CB773E8794CD02CCCDF
ApolloVibe 2026.6.1-ms4
Apollo now leaves a trace when its config fails at startup, and it exits with a nonzero code.
The problem
When the config could not be applied, Apollo logged the reason before its log file existed. Started as a service or injected into a session, it slept about ten seconds and exited with no log. It also exited with code 0, so a supervisor saw a clean exit.
This is #3. It came out of MultiSeat #63, where an unwritable config\ directory caused exactly this.
The fix
- A config failure is now appended to
sunshine-startup-error.lognext tosunshine.exe. If that directory is not writable, the file goes in the temp directory. - A failed config now makes Apollo exit with code 2.
- Exit code 0 stays for
--help, service start and shortcut launch.
Testing
- Runtime test with a control, using a config that fails with a filesystem error:
- This build exited with code 2 and wrote the log, including
Failed to apply config: filesystem error: ...andConfig was not loaded; exiting. - The previous installed build exited with code 0 and wrote no log.
- This build exited with code 2 and wrote the log, including
- Not tested: the ApolloVibe unit tests. The test build already fails on drift in
tests/unit/test_http_pairing.cpp, which this release does not touch.
Limits
- Only config failure paths are covered. Other early exits are unchanged.
- The log has no timestamps and never rotates.
- A service's temp directory is
C:\Windows\Temp. - MultiSeat reads no Apollo exit code, so exit 2 changes nothing there. It shows in ProcessInjector's log.
Install
apollovibe-windows-x64.zip is the complete portable build: sunshine.exe, assets/ and tools/. MultiSeat's installer pulls it from releases/latest/download/ and needs no change.
SHA-256 of sunshine.exe:
CCC693F69F0F7DB12AB10FE22858B064B4DB699A035753BF1A8DAD628DDF3BFF
ApolloVibe 2026.6.1-ms3
Fixes a hang that made ApolloVibe unusable on every AMD GPU.
The bug
On AMD hardware ApolloVibe wedged during encoder probing, at startup, before any
client connected. One CPU core pinned at 100% and the process never recovered.
NVIDIA systems were unaffected, which is why this went unreported for so long.
Found and confirmed by @treghart in
#2. He reported it, ran
build after build on his own hardware across five failed hypotheses, uninstalled his
working setup to test a stock Sunshine control, and finally ran an instrumented build
whose log located the defect in a single run. Every one of my own theories before that
was wrong. This fix is his as much as anyone's.
The cause
Upstream Sunshine commit 02036920, "build(deps): Update to FFmpeg 8.0 branch
(#4143)", changed two things at once: it added a drain to the encode session
destructor, and it bumped third-party/build-deps to the FFmpeg 8.0 the drain was
written for.
Apollo took both halves correctly and carried them for seven weeks. Then merge
10fd290b (2025-09-27) resolved third-party/build-deps back to a9a7f863, a pin
from 2025-07-12 that neither parent of that merge points at. So every Apollo-derived
build since then has run a drain written for FFmpeg 8.0 against a pre-8.0 FFmpeg. On
AMF, avcodec_send_frame(ctx, nullptr) never returns. On NVENC it returns
immediately.
This release removes the drain. That costs nothing: it received packets into a local
that was discarded on the next line, so it moved no data — its only effect was letting
the encoder drain before a teardown that destroys everything anyway.
This is an upstream bug
It is inherited from Apollo, not introduced here. Filed upstream as
ClassicOldSong/Apollo#1588,
where the correct fix is restoring the submodule pin rather than deleting the drain.
Testing
- AMD / AMF — confirmed by @treghart on a Vega iGPU: encoder probe completes and
Apollo reachesRegistered Apollo mDNS servicewith the CPU idle. - NVIDIA / NVENC — regression-checked here on an RTX 3080. Six encode sessions
created and destroyed during probe, including one deliberately failing session, with
no hang. Full seat provision/serve/teardown passed 24 of 24 checks. - Not tested: teardown of a live client stream on this build. Both test hosts
verified the probe path, which is where the fault was.
Install
apollovibe-windows-x64.zip is the complete portable build — sunshine.exe,
assets/ and tools/. MultiSeat's installer pulls it from
releases/latest/download/ and needs no change.
SHA-256 of sunshine.exe:
75467310FCABB262E47D707DF79C105415D3A5EBCD7CE3F5225180CA14BC9056
TEST BUILD — no absolute GPU thread priority (not a release)
Not a release. A diagnostic build for ApolloVibe#2.
Upstream Apollo commit 5af771d2 ("Priority hack", 2025-08-12) added SetGPUThreadPriority(0x4000001E) ahead of the existing relative request, at two call sites — the capture device in display_base.cpp and the encoding device in display_vram.cpp. 0x4000001E is 1,073,741,854, far outside the -7..7 range IDXGIDevice::SetGPUThreadPriority documents. Apollo v0.4.6, which predates the commit, issues only SetGPUThreadPriority(7).
This build reverts both call sites to the v0.4.6 behaviour. Nothing else is changed.
Built from f0fefda5 on branch test/no-gpu-priority-hack. sunshine.exe SHA256 begins cf1e76139f81d944.
TEST BUILD — root-cause fix for the AMD/AMF hang (not yet on master)
Candidate fix for ApolloVibe#2, held on a branch pending confirmation.
Upstream Sunshine commit 02036920, "build(deps): Update to FFmpeg 8.0 branch (#4143)", changed two things in one commit: it added a drain to ~avcodec_encode_session_t() and bumped third-party/build-deps from 94369e63 to a21ef2e3. The drain was written for FFmpeg 8.0.
Apollo merged the source half and kept its own older build-deps pin. The version strings prove it — ours and upstream Apollo carry Windows FFmpeg "6400860"; Sunshine after that commit carries "git-2025-08-09-7eaa0f7". On AMD/AMF, avcodec_send_frame(ctx, nullptr) then never returns.
This build removes the drain, restoring Apollo v0.4.6 behaviour. It moves no data — the packets were discarded on the next line.
Built from a358bba8 on fix/no-encoder-flush-on-destroy. sunshine.exe SHA256 begins aa16f9bcb0c9dcc3.
TEST BUILD — AMF options no longer forced (not a release)
Not a release. Built for ApolloVibe#2, held on a branch pending confirmation.
Unlike the two earlier diagnostic builds, this is a real candidate fix rather than a probe.
coderis no longer forced.amd_coderwas the only setting in the AMD config block declared as a plainintwhile every sibling isstd::optional<int>; parsed withint_fit always held a value (autowhen unconfigured), so the option was passed on every AMF encode. It is now optional and set only when configured. Settingamd_coderin config still works exactly as before.profile: highis no longer set for h264 AMF. Sunshine sets a profile for nvenc and qsv but deliberately not for AMF, and Apollov0.4.6didn't either — both are confirmed working on the reporter's hardware.
Built from 7304b18c on fix/amf-dont-force-coder-profile. sunshine.exe SHA256 begins 6c2339cef79ac81d.
DEBUG BUILD — probe path instrumented (not a release, not a fix)
Diagnostic build for ApolloVibe#2. It does not attempt to fix anything — it reports where the hang happens.
Adds [PROBE] markers at info level (not verbose, which enables AMF's own debug output) around init_codec_options, avcodec_open2 entry and success, and every stage of ~avcodec_encode_session_t().
That destructor's drain loop is while (avcodec_receive_packet(...) == 0); — an empty-bodied spin, which is what a pinned core looks like. It is bounded at 200,000 packets here with an explicit abort line, so if it is the fault this build escapes it rather than hanging.
Built from 55231bdf on debug/probe-instrumentation. sunshine.exe SHA256 begins 076ddfee820851fe.
ApolloVibe 2026.6.1-ms2
First release since June. Four source fixes have been sitting unreleased since then, so anyone installing MultiSeat has been getting the June build.
Fixes
30cc3859 |
input: keep the input desktop handle alive instead of closing the one in use |
fb05b1ab |
sudovda: log why virtual display creation fails instead of failing silently |
61f72e57 |
wol_mac option to override the MAC advertised to clients |
84d4ef18 |
sudovda: match added virtual display by adapter LUID and target id |
fb05b1ab is the one worth knowing about if you are debugging seats. Virtual display creation used to fail with nothing in the log. Now it says why.
The download name changed
The asset is now apollovibe-windows-x64.zip, with no version in it. It can be fetched from a permanent URL that always resolves to the newest release:
https://github.com/vibesoftwarecoder/ApolloVibe/releases/latest/download/apollovibe-windows-x64.zip
The version used to be part of the filename, so MultiSeat's installer had to hardcode both the tag and the filename. Every release needed a matching edit in another repository. That is exactly why this release is three months late. It will not happen again.
Identifying this build
sunshine.exe SHA256 9DE593107687F956830E37BB2361A07E...
master, the commit hash is no longer appended, so every build reports 2026.6.1.dirty. Use the SHA256.
Base and testing
Built on upstream ClassicOldSong/Apollo at adc5c5a0, which has been dormant since 2026-05-21. We are 47 commits ahead and 0 behind.
Smoke-tested on the reference host: a seat provisions, gets its own session, listens on all three ports and completes a TLS handshake, then tears down cleanly.
30cc3859, which changes input handling and needs a real client sending input to exercise.
TEST BUILD — h264_amf without async_depth (not a release)
It exists to test one thing for issue #2, where the AMD H.264 encoder encodes a single frame and then spins one CPU core forever.
What is different
Exactly one line is removed. The AMD H.264 encoder is no longer given the async_depth option:
{"async_depth"s, 1}, // removed in this build onlyEverything else is identical to v2026.6.1-ms2.
Why that line
The Apollo release that does not show the problem, v0.4.6 from July 2025, passes three fewer options to the AMD H.264 encoder than current builds do: async_depth, coder, and profile. async_depth controls how many frames may be in flight before the encoder waits. That is the one whose behaviour matches the symptom, so it is being tested first and on its own.
The other two remain in this build. If the problem persists, they are next.
Notes
- Windows x64 only.
- Not marked as the latest release, so nothing that installs ApolloVibe automatically will pick it up.
- It will be deleted once the question is answered.
ApolloVibe v2026.6.1-multiseat.1
Catch-up rebase release. The branch was rebased onto ClassicOldSong/Apollo HEAD on 2026-06-01.
What's new vs v2026.5.15-multiseat.1
- Security: picks up upstream merge of
WatchKitty/Apollo#1496— backport of fix for GHSA-ph75-mgxh-mv57. - All MultiSeat-specific work (mic passthrough via Steam Streaming Microphone,
disable_rtsp_encryptionconfig option with RTSP at port 48010, NVENC perf tuning, ApolloVibe rebrand) is replayed on top — no behavioural changes fromv2026.5.15-multiseat.1apart from the upstream merges.
Build info
- Source: branch
apollovibe-dev, commit6b98d106 - Built 2026-06-01 with MSYS2 UCRT64 + GCC 15.2 + Ninja
- Binary:
2026.6.1.6b98d106.dirty
Install
Extract over an existing Apollo install:
Stop-Service ApolloService -ErrorAction SilentlyContinue
Get-Process sunshine -ErrorAction SilentlyContinue | Stop-Process -Force
Expand-Archive apollovibe-v2026.6.1-multiseat.1-windows-x64.zip -DestinationPath "C:\Program Files\Apollo" -ForceThe zip contains only sunshine.exe; existing config, web UI, and bundled SudoVDA driver files in the install directory are untouched.