VideoRenderer
Draws frames.
The renderer owns its thread and its GPU context. The engine never touches a graphics API and never assumes which thread it is on.
The rules below are stated explicitly because this is the interface libmpv makes hardest to use correctly, and its failure mode is a deadlock rather than an error:
The engine calls present from the video scheduler coroutine. A renderer may hand the work to its own thread and return at once, or do it inline. Either is correct.
The renderer owns the frame from the moment present is called, including when it fails, and closes it exactly once.
A renderer must never call synchronously back into the player from inside present.
vsyncIntervalNanos is advisory. Returning null costs smoothness on a high refresh display and nothing else.
Losing a surface is an event, not an exception. Playback continues, video frames are counted as dropped, and audio keeps playing, because a minimised window should not stop the sound.
A renderer may be attached and detached at any time, including while playing. Ordinary video decoding does not depend on one existing. A renderer-coupled decoder is considered only when its renderer is attached before the media session opens; attaching later does not replace the active decoder.
Properties
Surface loss, surface return, refresh changes, colour limits, hard failure.
The surface this renderer draws into, in PHYSICAL pixels, or null when it cannot say.
True when this renderer draws the picture it holds again by itself after a change of its look: scale mode, adjustments, framing, render quality or the subtitle overlay. False makes the engine decode the held picture once more after such a change while the player is paused or ended, so the change shows at once rather than with the next frame (#463). Read at each change, so the answer may follow the picture: Android's renderers answer false while a MediaCodec frame shows, because it goes to the Surface and leaves no copy, and the surface renderer answers true while a software picture it keeps shows (#541). Defaulted to true, for a renderer that keeps its picture.
True when this renderer, on the display it draws to now, shows HDR as HDR under io.github.yuroyami.kiteplayer.HdrPolicy.Auto, rather than tone mapping it (#447). The engine reads it when it chooses an adaptive stream's variant, so an HDR display gets the HDR version and a standard one the SDR version. Defaulted to false, for a renderer that always tone maps.
Functions
True when this renderer can show frames of shape, asked before they exist: at open, to pass over a decoder whose frames it cannot show, and at attach, to refuse a renderer that cannot show the running decoder's frames.
No picture plays any more, so the one on screen must go.
Presents frame, aiming for targetNanos on the engine's monotonic clock.
The picture controls (brightness, contrast, saturation, hue), as the engine's one colour matrix law. Told on attach and on every change, exactly like setScaleMode. Defaulted so an existing renderer keeps compiling; a renderer that draws colour overrides it.
How HDR video reaches the screen. A renderer that can show HDR as HDR does so under io.github.yuroyami.kiteplayer.HdrPolicy.Auto and reports RendererEvent.HdrShown. The default ignores it, for a renderer that always tone maps.
Composited above the video. Replaced wholesale rather than diffed.
How much work to spend on the picture beyond decoding it correctly.
How the picture should occupy the surface. Defaulted so an existing renderer keeps compiling and keeps its Fit behaviour; a renderer that can crop or stretch overrides it.
The framing controls (aspect override, zoom, pan), folded into the same geometry pass the scale mode drives. The same delivery law as setScaleMode; defaulted the same way.
The output surface changed size. Subtitles are laid out again after this.
Hardware surface kinds this renderer can present without a download to main memory.
True when this renderer can draw a frame in format at all.
Decoder factories that require this renderer's surface or graphics context.
Display refresh interval in nanoseconds, or null when the platform does not report it.