Skip to content
This repository was archived by the owner on Jun 4, 2025. It is now read-only.

Experimental feature: Black crush mitigation - #525

Draft
utopiafallen wants to merge 28 commits into
moonlight-stream:masterfrom
utopiafallen:black-crush-mitigation
Draft

Experimental feature: Black crush mitigation#525
utopiafallen wants to merge 28 commits into
moonlight-stream:masterfrom
utopiafallen:black-crush-mitigation

Conversation

@utopiafallen

Copy link
Copy Markdown
Contributor

Experimental feature: Black crush mitigation

The OLED display on my Lenovo Chomebook Duet 5 suffers from black crush so this experimental feature adds a custom gamma curve to boost dark values and alleviate the worst of the black crush.

Since this is forked from my master branch, there's a bunch of identical changes as my other pull request. I'm not even sure this "feature" is desirable so I'm leaving the PR in draft mode.

@moonlight-stream

bob and others added 28 commits October 20, 2022 06:52
Pepper SDK and NaCl in general is EOL for Chrome, although still supported for Chrome Apps.
This means that the Pepper Gamepad API was never updated with rumble support so in order
to add rumble support, rumble messages from Gamestream have to be forwarded to JavaScript
and handled with gamepad.vibrationActuator.playEffect().

Side note, Chrome limits the duration of playEffect to 5 seconds and requesting more than
that causes the vibration request to be rejected.
Moonlight's fullscreen requests generally conflict with
what ChromeOS is trying to do automatically for the app, especially when
using tablet mode. Just remove it for now and let the OS handle
fullscreen.
Otherwise, Esc breaks out of fullscreen instead of being sent to the streaming app.
Adding fullscreen class to the #listener seems to fix the game stream
getting stuck in a black screen. I suspect that #main-content isn't
recomputing its layout when #listener is resized.
Shader is compiling successfully, but the required data not yet hooked up.
A lot of plumbing is set up but Chrome seems sensitive to certain OGL calls
hanging the NaCl module. I don't understand what's happening but this is
version at least draws the video stream again, even if it's messed up.
Finally back to a no-op equivalent state.
XYZ space doesn't automatically adjust chromaticity when luminance changes
meaning colors can shift when Y is changed.
Rumble events may be received for controllers that are no longer present or attached
so they should be dropped instead of being forwarded to JS for handling.
- Black crush now runs in gamma space and does far less work to achieve roughly the same
thing. Unfortunately, there is visual corruption still to be figured out.
- Fixed UI button not reflecting the mitigation state.
Video compression can introduce false colors since all compressors are lossy, and when that
happens, the false colors can be emphasized by the black crush mitigation. To fix this,
the shader explicitly neutralizes pixels below a threshold (currently 4/255) before
applying any compensation curves.
Turns out, the supplied texture can contain negative RGB values. I'm assuming that
compression artifacts are causing the invalid channel values so now I make sure to clamp
input RGB to [0,1] range before computing lookup coordinates for the gamma ramp.

Also simplified the gamma index to be based on max RGB value instead of luminance. Just
seeing if this produces more visually pleasing results.
- Move gamepad index check to the JS side to simplify the code
- Handle gamepads that don't support haptics
Getting weird artifacting with black crush enabled on high contrast areas,
probably need to tune the curve behavior to better hide compression artifacts.
For now, the shader fully skips the curve look up if the mitigation is disabled.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants