Skip to content

Releases: vibesoftwarecoder/ApolloVibe

ApolloVibe 2026.6.1-ms5

Choose a tag to compare

@vibesoftwarecoder vibesoftwarecoder released this 28 Sep 18:00
5fbe014

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

Choose a tag to compare

@vibesoftwarecoder vibesoftwarecoder released this 25 Sep 14:14
57a1f6a

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.log next to sunshine.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: ... and Config was not loaded; exiting.
    • The previous installed build exited with code 0 and wrote no log.
  • 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

Choose a tag to compare

@vibesoftwarecoder vibesoftwarecoder released this 06 Sep 21:12

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 reaches Registered Apollo mDNS service with 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)

Choose a tag to compare

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.

⚠️ Pre-release on purpose. Nothing that installs ApolloVibe automatically will pick this up, and the asset name is distinct so it cannot be mistaken for a real release.

TEST BUILD — root-cause fix for the AMD/AMF hang (not yet on master)

Choose a tag to compare

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.

⚠️ Pre-release on purpose. The properly aligned fix is bumping build-deps, which belongs upstream.

TEST BUILD — AMF options no longer forced (not a release)

Choose a tag to compare

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.

  • coder is no longer forced. amd_coder was the only setting in the AMD config block declared as a plain int while every sibling is std::optional<int>; parsed with int_f it always held a value (auto when unconfigured), so the option was passed on every AMF encode. It is now optional and set only when configured. Setting amd_coder in config still works exactly as before.
  • profile: high is no longer set for h264 AMF. Sunshine sets a profile for nvenc and qsv but deliberately not for AMF, and Apollo v0.4.6 didn'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.

⚠️ Pre-release on purpose — nothing that auto-installs ApolloVibe will pick this up.

DEBUG BUILD — probe path instrumented (not a release, not a fix)

Choose a tag to compare

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.

⚠️ Pre-release on purpose — nothing that auto-installs ApolloVibe will pick this up.

ApolloVibe 2026.6.1-ms2

Choose a tag to compare

@vibesoftwarecoder vibesoftwarecoder released this 05 Sep 22:01

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...

⚠️ Do not rely on the version string to tell builds apart. Since both branches were collapsed to 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.

⚠️ That proves the binary is not broken. It does not prove 30cc3859, which changes input handling and needs a real client sending input to exercise.

TEST BUILD — h264_amf without async_depth (not a release)

Choose a tag to compare

⚠️ This is a diagnostic build, not a release. Do not use it as your normal install.

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 only

Everything 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

Choose a tag to compare

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_encryption config option with RTSP at port 48010, NVENC perf tuning, ApolloVibe rebrand) is replayed on top — no behavioural changes from v2026.5.15-multiseat.1 apart from the upstream merges.

Build info

  • Source: branch apollovibe-dev, commit 6b98d106
  • 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" -Force

The zip contains only sunshine.exe; existing config, web UI, and bundled SudoVDA driver files in the install directory are untouched.