VideoAdjustments
The picture controls a viewer expects from a real player: brightness, contrast, saturation, hue and gamma, live, without touching the decoder (mpv's eq). The engine owns the value and every attached renderer is told it, exactly like VideoScale; the renderers apply it per drawn frame, which is why a change is instant and free of pipeline work.
Brightness, contrast, saturation and hue compose into a single affine colour transform, and toColorMatrix is the ONE place that transform is written down, so no two renderers can disagree about what saturation means. gamma is a power curve, which no matrix can express, so it is a second step that runs on the matrix's output.
Not every renderer can apply every control:
The Metal renderer, the Android GPU image renderer and the Apple Core Graphics renderers apply all five.
The Android view renderer and the Compose video draw apply the matrix through the platform's own colour filter. That filter has no power curve, so they ignore gamma.
The desktop AWT renderer, the web canvas renderer and the sample-buffer renderer apply none.
Constructors
Properties
Additive lift, -1 to 1. 0 is neutral; positive lightens.
Rotation about the luma axis in degrees, -180 to 180. 0 is neutral.
True for the neutral value, which renderers use to skip every step entirely.
Colourfulness, 0 to 2. 1 is neutral; 0 is greyscale by the BT.709 weights.
Functions
Brightness, contrast, saturation and hue as one 4x5 row-major colour matrix over non-premultiplied RGBA in the UNIT domain: r' = m[0]r + m[1]g + m[2]b + m[3]a + m[4], rows r, g, b, a. Offsets are in 0..1; a consumer whose convention offsets in 0..255 (Android's ColorMatrix, Compose's) multiplies the fifth column by 255 and changes nothing else.