CapturedFrame

A screenshot: the newest presented frame, plane-copied at the moment of presentation, owned outright by the caller. This is the documented use of SoftwareReadableFrame: every plane here is a copy taken before the renderer took ownership, so nothing the decoder or the renderer does afterwards can touch it, and close has nothing to release.

These pixels are DECODED, not colour managed

The engine's display paths roll HDR off to standard dynamic range before you see it, and they say so with PlaybackWarning.HdrToneMapped. A captured frame has had none of that done to it. Its samples carry the source's own transfer function, so a PQ or HLG capture converted naively as if it were SDR shows flat highlights and reads dull. colorSpace carries what it actually is; convert accordingly.

This used to be announced as a TonemappingUnavailable warning during playback, which told every viewer about a caveat that only concerns a caller doing its own conversion It lives here now, where that caller will meet it.

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
open override val colorSpace: ColorSpaceInfo

The colour metadata a renderer must honour.

Link copied to clipboard
open override val crop: PictureCrop?

The container's crop of the presented frame, or null (#497). The planes hold the whole stored picture, as they do for a turned one, so a caller that converts them shows only what the crop leaves, as the screen did.

Link copied to clipboard
open override val duration: Pts? = null

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

Link copied to clipboard
open override val generation: Generation

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

Link copied to clipboard
open override val hardwareSurface: HwSurfaceKind? = null

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 override val mirrored: Boolean

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

Link copied to clipboard

The subtitles that were on screen, laid out for THIS frame's own size after its crop and turned by rotationDegrees, or null. Turn and mirror the planes as the frame says, then draw these on top, as the screen did (#428).

Link copied to clipboard
open override val pixelFormat: PlayerPixelFormat

How the pixels are laid out in memory.

Link copied to clipboard
open override val planeCount: Int

How many planes copyPlane can read.

Link copied to clipboard

The pixel format of the planes copyPlane reads.

Link copied to clipboard
open override val pts: Pts

The media time at which this frame is shown.

Link copied to clipboard
open override val rotationDegrees: Int

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
open override 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
open override fun close()

The copies are plain arrays; there is nothing to release.

Link copied to clipboard
open override fun copyPlane(index: Int, into: ByteArray, offset: Int = 0)

Copies plane index into into from offset: planeStride times planeHeight bytes.

Link copied to clipboard
open override fun planeHeight(index: Int): Int

Rows in plane index. A subsampled chroma plane has fewer rows than the picture.

Link copied to clipboard
open override fun planeStride(index: Int): Int

Bytes per row of plane index, which is at least the plane's width in bytes and usually more.