VideoFrame

A decoded video frame.

The pixels are not in Kotlin memory and this interface gives no way to read them. A frame is a handle to whatever the decoder produced: an AVFrame, a CVPixelBuffer, a MediaCodec output buffer, a VA surface, a browser VideoFrame.

That is not an omission. A 1080p frame in yuv420p is 3.11 MB and a 4K 10-bit frame is 24.9 MB. Copying either into a ByteArray sixty times a second is between 187 MB/s and 1.5 GB/s of pure waste, plus an allocation per frame, and the destination is a GPU texture that could have been filled from the original pointer. Reading pixels is a renderer's job, and a renderer is chosen to match the decoder that produced the frame, so it knows how.

Ownership. Whoever receives a frame closes it. Exactly once. A frame may be moved between threads but must not be used from two at once. VideoRenderer.present takes ownership, including when it fails.

Inheritors

Properties

Link copied to clipboard

The closed captions this picture carried, the cc_data of its ATSC A/53 data, three bytes per caption pair, as broadcast H.264, HEVC and MPEG-2 carry them inside the video, or null when it carried none (#236). Read once by the engine as the frame leaves its decoder, so a decoder hands out frames in the order they are shown, which is the order the captions were written in.

Link copied to clipboard

The colour metadata a renderer must honour.

Link copied to clipboard
open val crop: PictureCrop?

The edges of the stored picture that are not part of the image, as its container states, or null when it states none (#497). See PictureCrop.

Link copied to clipboard
abstract val duration: Pts?

The decoder's own duration for this frame, when it has one.

Link copied to clipboard
abstract val generation: Generation

The epoch this frame belongs to. A frame from a superseded generation is never presented.

Link copied to clipboard

Set when the frame lives in GPU or hardware memory and needs a matching renderer.

Link copied to clipboard

The static HDR metadata of this frame, or of its stream when the frame carries none, or null. A renderer that tone maps reads the content's peak from it.

Link copied to clipboard
open val mirrored: Boolean

True when the display matrix also mirrors the picture, as a front camera can record it.

Link copied to clipboard

How the pixels are laid out in memory.

Link copied to clipboard
abstract val pts: Pts

The media time at which this frame is shown.

Link copied to clipboard

Clockwise rotation a renderer applies before the picture is shown, in degrees.

Link copied to clipboard
open val sceneMaxNits: Float?

The brightest level of this frame's scene in nits, from dynamic HDR metadata that travels with the frame, such as Dolby Vision's level 1, or null when the frame carries none.

Link copied to clipboard
abstract val size: VideoSize

The size the frame is stored at, before rotationDegrees turns it.

Link copied to clipboard

The content peak a tone mapper rolls this frame off from, in nits: the scene's brightest level when the frame carries one between 100 and 10000 nits, held at most at the title's own peak, else the title's peak from VideoFrame.hdr, else null for the 1000 nits a PQ master is assumed to have.

Link copied to clipboard

The size of the picture this frame shows: VideoFrame.size with VideoFrame.crop's edges taken away, before the turn, which still swaps width and height for a renderer.

Functions

Link copied to clipboard
expect abstract fun close()