PS4 Ambilight changelog
v4.0.0 · Oct 28, 2026
PS4 Ambilight 4.0
The big change: the strip can now stay lit outside games too, from the PS4's own Home screen, Settings and quick menu, with the new optional shell feed. The game plugin itself got steadier, and the companion app now tells you when it needs updating.
New: the shell feed (optional, off by default)
- Lights the strip from the PS4's Home screen, Settings and quick menu, and steps aside the moment a game starts.
- Installs from the companion app: turn it on under Set up > Shell feed, then press the main button on Home. The app downloads the files, checks each one's SHA-256, and puts them where they belong.
- Comes with a standalone Ambilight payload that you launch from the app (Launch Ambilight payload) or set to Autoload at boot. Autoload only ever adds its own line to GoldHEN's AutoRun list.
- Confirmed working on firmware 9.00 and 12.52. Other versions are untested.
- With the switch off, the app does nothing shell-related at all.
Game plugin
- Steadier hand-off between a game, the app and the shell feed. They now coordinate over a local connection instead of polling files. A game that crashes can no longer leave the strip stuck.
- No more long stalls. Slow
/datafile access no longer stops the strip, and the plugin does far fewer file operations while you play. - Fixed the launch flicker where the strip went dark for a few seconds at game launch (seen in FC26).
- Lapy's PS4 Player no longer flashes white and blue over part of the strip.
- Everything the plugin and shell feed need now lives in one folder,
/data/ps4-ambilight/. - Plugin and shell feed now show a console notification for problems that used to fail silently. These can be turned off with a switch in the app (a few essential ones always show).
- The shell feed no longer falls back to a built-in WLED address. With no address set, it sends nothing.
Companion app 1.02
- It tells you when a newer app is out, and Triangle on Home downloads the new
.pkgfor you. It checks the file against its published checksum and saves it in/data/pkg. Then install it from GoldHEN > Debug Settings > Package Installer. - A console notification also tells you at launch when an update is available.
- Controls no longer feel sticky. Rebuilt input handling, optimised drawing and smooth scrolling.
- Home now shows whether the Ambilight payload is running. Square quick-saves on Set up and Customization.
- The app checks GoldHEN's Enable Plugins Loader setting first and says so on Home when it's off.
Updating
- Install the new companion app
.pkgfrom the assets below. - Open it and press the main button on Home to update the plugin.
- Optional: turn on the shell feed in Set up and install it from Home.
You'll see a one-time notice after updating the plugin, and an old app can't know a new one exists, so install the new app first.
Full details in the [changelog](../../blob/main/CHANGELOG.md).
v3.9.1 · Oct 1, 2026
v3.9 · Sep 30, 2026
v3.8 · Sep 30, 2026
v3.7.0 · Sep 30, 2026
v3.6.0 · Sep 29, 2026
v3.5.0 · Sep 29, 2026
v3.3.0 · Sep 29, 2026
Plugin v3.3.
- Fixed steady LED flicker on static screens (AC3 Remastered menu) and flashes on all-black load screens (God of War Ragnarok). The sampler was reading the buffer slot the flip hook had just reported, but the flip hooks fire when the game submits a flip, so that slot can still be cleared or half drawn. It now reads the slot of the previous flip (
AMBIENT_SAMPLE_LAG, default 1, costs one flip of latency). Confirmed on real hardware, and the GOWR flashes were caught frame by frame in the slot the fix skips (60 of 60 transients across two captures). The full investigation is in [docs/debugging/framebuffer-flicker.md](docs/debugging/framebuffer-flicker.md), with the details of the change and what's still untested in [buffer-selection.md](docs/debugging/buffer-selection.md). Still open: the letterbox cutscene flicker in the same title, no capture yet. - Fixed a delay on dark screens with a small bright element in the middle (a loading screen with centered text, for example). The letterbox scan only checked 3 fixed points per line (25/50/75%), so on a mostly-black frame all four edges scanned nearly to the search limit before "finding" the text, and the plugin committed a huge border around it.
buildZoneGeometry()then pulled the edge zones in to that margin, so when something flashed in from the real screen edge nothing sampled there and the LEDs only reacted once it had travelled in to the shrunken area, about a second late. Only showed up on dark scenes because bright frames hit non-black on the first row and never get that far. - Letterbox detection now sweeps
EDGE_NUM_SAMPLES(10) points across the whole row/column and only treats the line as bar if 85% of them are black (isRowBlack/isColBlack). A few dozen pixels of text only flip a couple of samples, so the scan walks past it to the real edge. This is the same approach asBorderProcessor.findBorderRgbin the Android project, which every real capture path there uses; the 3-point version this was ported from (findBorderRgba) turns out to only be exercised by that project's unit tests. - Search depth is capped at
MAX_BAR_DEPTH_V/_H(1/6 of the screen, 180px/320px) instead of half the screen. Console output is native 16:9, so the only bars are cutscenes mastered at a narrower ratio: 1.85:1 is ~21px per edge and 2.39:1 is ~138px on a 1080p frame. This also caps how far a misdetection could ever inset the zones. Worst case probe count is about the same as before (~10k vs ~9k) despite the extra samples per line. scan_depthhad no upper bound in the plugin's ini loader (every neighbouring key checked both ends). AddedSCAN_DEPTH_MAX(4). Each step is(2*depth+1)^2tiled reads per zone per pass, so the old ceiling of 10 was roughly 54M tiled-offset computations/sec at 512 zones and 240Hz; 4 brings that to about 10M. A value above 4 in the ini is now rejected and the default (1) is kept, same as the other bounded keys.saturationandcontrastnow top out at 100 (were 300). The color chain is clamped to 0-255 per channel at the end, so most of that range just clipped: over sample colors, +100 already has a channel clipped on ~84% of vivid colors and +300 is ~99.8%; for contrast the 2x factor at +100 clips half the tonal range. Testing 100 against 175 on a real strip showed little difference, which lines up. Unlikescan_depth, these two are clamped to the new cap on load rather than rejected, so an existingsaturation=175becomes 100 instead of silently resetting to 0. NewSATURATION_MAX/CONTRAST_MAXinambient_internal.h.g_pluginVersionbumped to0x00000303for this release, so it doesn't drift behind the changelog again the way it did before v3.1.
Full history: CHANGELOG.md and docs/history.md in the repo.
v3.2.0 · Sep 29, 2026
Plugin v3.2.
- Fixed a real crash: GoldHEN injects every plugin into every title's process, including this project's own companion app -- just another titleid (
SHMY00091) as far as GoldHEN is concerned. Before this fix that was harmless, since the companion app apparently never called the plainsceGnmSubmitAndFlipCommandBufferspath this plugin hooked pre-v3.1. Once v3.1 added thesceVideoOutSubmitFlip/...ForWorkloadhooks, the companion app's own screen flips started getting captured too -- its live UI colors got streamed to the strip, conflicting with whatever real game testing/strip-adjustment session was already running, andambient_sample_threadthen applied this plugin's game-buffer tiling math to the companion app's differently-shaped surface. Confirmed via a real crash report: threadambient_sample_thread, proceboot.bin, AppNamePS4 Ambilight, TitleIDSHMY00091, SIGSEGV on a page fault reading an address that matched neither this project's real GNM buffer addresses seen in other captures. Fixed at the very top ofplugin_load, before anydlsym/hook/thread work: readprocInfo.titleidviasys_sdk_proc_info()and bail out entirely if it'sSHMY00091. One check fixes both the crash and the color conflict, since neither can happen if no hook is ever installed in that process to begin with. **Confirmed on real hardware: the companion app no longer streams its own screen colors to the strip, and no longer crashes on options save/exit.**
Full history: CHANGELOG.md and docs/history.md in the repo.
v3.1.0 · Sep 29, 2026
Plugin v3.1.
- Added a third flip hook,
sceGnmSubmitAndFlipCommandBuffersForWorkload, fixing titles that never light up at all. Shadow of the Tomb Raider (SDR and HDR) never lit the strip because it calls theForWorkloadentry point directly and skips the wrapper the plugin was already hooking. Also addedsceVideoOutSubmitFlipas a second flip hook (it turned out not to be the cause, but it's harmless), plus flip/register counters in the debug telemetry. Confirmed on real hardware. How it was tracked down, including the wrong guesses: [docs/debugging/videoout-hooks.md](docs/debugging/videoout-hooks.md). - Also bumped
g_pluginVersion, which had been stuck at the v2.7.2 comment (0x00000212) since that release, with v2.7.3 through v3.0 landing on top of it unbumped -- caught up now that there's a real reason to touch this file again.
Full history: CHANGELOG.md and docs/history.md in the repo.
v3.0.0 · Sep 29, 2026
Plugin v3.0.
- Removed the manual
capture_margin_top/right/bottom/leftini keys. v2.9's auto letterbox detection can now fully cover what these were for -- a fixed manual number is either wrong during a letterboxed cutscene or wrong for the fullscreen gameplay around it, since almost everything actually renders edge-to-edge with no bars at all -- so rather than carry unused legacy config, they're gone.[layout]'s margin comment block is replaced by theauto_letterbox_*keys. Breaking ini change: an existing config withcapture_margin_*set will have those values silently ignored, not migrated -- if you were using them to trim overscan rather than an actual letterbox (some capture chains show a few pixels of border the display itself would normally crop), auto letterbox threshold/stability won't reproduce that; there's no equivalent setting for it anymore. auto_letterbox_enablednow defaults totrue(wasfalsein v2.9). It's the only capture inset the plugin applies, so leaving it off by default would mean sampling starts at the true edge on every side, unconditionally, for anyone who doesn't know to turn it on.
Full history: CHANGELOG.md and docs/history.md in the repo.
v2.8.0 · Sep 29, 2026
Plugin v2.8.
- WLED heartbeat: the plugin now resends the last known-good color once a second during any foregrounded gap where the pixel format is momentarily unknown or unrecognized, instead of going silent. Closes the remaining cases of the v2.2.3 "occasional flash of an unrelated color" -- that release made the underlying gap less frequent by speeding up the pipeline, but didn't remove it; a long enough gap could still trip WLED's own realtime-timeout fallback. This never invents a new color -- it only repeats the last one the real pipeline already verified -- and does not run while backgrounded/suspended, where going silent is still intentional (v2.4). Write-up: [
docs/debugging/wled-heartbeat.md](docs/debugging/wled-heartbeat.md).
Full history: CHANGELOG.md and docs/history.md in the repo.
v2.7.6 · Sep 29, 2026
Plugin v2.7.6.
- Reverted the v2.7.3 stale-flip guard. It was blanking the strip whenever no flip landed within ~350ms, but menus and static loading screens often throttle or stop flipping while idle, and the gaps would drift back and forth across that threshold -- blank, resume, blank, resume, visible as flicker on anything that stays on screen for a while. Wasn't protecting against anything we'd actually confirmed happens (the real black-screen-shows-color bug turned out to be the v2.7.5 smoothing fix), so pulling it out rather than chasing a threshold that might just move the problem.
Full history: CHANGELOG.md and docs/history.md in the repo.
v2.7.5 · Sep 29, 2026
Plugin v2.7.5.
- Fixed color smoothing getting stuck a few shades above black instead of actually reaching it. Integer division truncates toward zero, so once a channel decayed down to ~3 the per-frame step rounded down to 0 and just stopped -- the strip would hold a faint, permanent glow of whatever was on screen before a cut to black instead of settling the rest of the way. Confirmed on hardware: this was the actual cause of "black screen shows color", not the format/decode stuff chased earlier.
Full history: CHANGELOG.md and docs/history.md in the repo.
v2.7.4 · Sep 29, 2026
Plugin v2.7.4.
- Fixed 4 duplicate LEDs, one at each screen corner. Zone geometry generated each edge inclusive of both endpoints, so the corner shared between two edges got sampled by a zone from each edge -- confirmed on hardware (zone 0 and the last zone were sending bit-identical raw pixel reads, every frame).
Full history: CHANGELOG.md and docs/history.md in the repo.
