pub struct VideoFrame {
pub pts: Option<i64>,
pub planes: Vec<VideoPlane>,
}Expand description
Uncompressed video frame.
Stream-level properties (pixel format, width, height, time base) are
NOT carried per-frame — read them from the stream’s
CodecParameters. Frames stay lightweight
because real-time playback moves thousands per second per stream.
§Side-channels
VideoFrame (like VideoPlane) is a fully-public struct built by
struct literal throughout the codec crates, so per-frame metadata
cannot be added as new fields without breaking every constructor.
Instead, optional metadata rides in-band as side-channel entries at
the tail of planes: VideoPlane values whose shape is impossible
for an image plane, which makes them unambiguous. Two side-channel
record kinds exist, distinguished by their stride tag:
- Palette —
stride == 0, non-emptydata. Impossible for an image plane because an image plane’sdataisstride × rowslong, so a zero stride forces empty data. Carries the color table for palette-indexed content (PixelFormat::Pal8); seepalette/set_palette. - Per-plane significant bits —
stride == usize::MAX, non-emptydata. Impossible for an image plane becausestride × rowsbytes with any non-zero row count would exceed what aVeccan hold. Carries mixed per-plane bit depths (e.g. 12-bit luma with 10-bit chroma from a wavelet codec’s custom signal range); seesignificant_bits/set_significant_bits.
The two records compose: a frame can carry both at once, in either
order, within the trailing run of side-channel-shaped entries. The
typed accessors find each record by its stride tag regardless of
order, and image_planes /
image_plane_count exclude the whole
trailing run. Frames without any attached side-channel are
byte-for-byte identical to what they always were.
Fields§
§pts: Option<i64>Presentation timestamp in the stream’s time base; None if unknown.
planes: Vec<VideoPlane>One entry per plane (e.g., 3 for Yuv420P). Each entry is (stride, bytes).
May additionally end with side-channel entries (palette,
per-plane significant bits — see the type-level docs). Code that
wants only pixel planes should iterate
image_planes instead of this field.
Implementations§
Source§impl VideoFrame
impl VideoFrame
Sourcepub fn palette(&self) -> Option<&[u8]>
pub fn palette(&self) -> Option<&[u8]>
The frame’s attached palette, if any.
Returns the raw bytes of the palette side-channel (see the
type-level docs): packed 3-byte RGB entries, entry i at bytes
3*i .. 3*i + 3 in R, G, B order. A full
Pal8 table is 256 entries
(768 bytes), but producers may attach fewer when the source
image declares a shorter table; indices at or beyond
len / 3 are undefined by this frame and up to the consumer’s
missing-entry policy (typically black).
Sourcepub fn palette_rgb(&self, index: u8) -> Option<[u8; 3]>
pub fn palette_rgb(&self, index: u8) -> Option<[u8; 3]>
The RGB triplet for palette entry index, or None when no
palette is attached or the attached table is too short to cover
index. Sugar over palette for per-pixel
lookups.
Sourcepub fn set_palette(&mut self, rgb: Vec<u8>)
pub fn set_palette(&mut self, rgb: Vec<u8>)
Attach (or replace) the frame’s palette side-channel.
rgb is packed 3-byte RGB entries — see
palette for the exact layout; pass a length
that is a multiple of 3 (up to 768 bytes for a full 256-entry
Pal8 table). The bytes are stored
verbatim. An empty rgb removes any attached palette instead
(the sentinel requires non-empty data), leaving the frame
exactly as it was before any palette was attached.
Sourcepub fn with_palette(self, rgb: Vec<u8>) -> Self
pub fn with_palette(self, rgb: Vec<u8>) -> Self
Builder-style counterpart to set_palette
for construction chains:
VideoFrame { pts, planes }.with_palette(rgb).
Sourcepub fn take_palette(&mut self) -> Option<Vec<u8>>
pub fn take_palette(&mut self) -> Option<Vec<u8>>
Detach and return the frame’s palette side-channel, if any. Afterwards the frame carries no palette (any other side-channel record is left in place).
Sourcepub fn significant_bits(&self) -> Option<&[u8]>
pub fn significant_bits(&self) -> Option<&[u8]>
The frame’s attached per-plane significant-bits record, if any.
Returns the raw bytes of the significant-bits side-channel (see
the type-level docs): byte k is the number of significant bits
in the samples of image plane k, in plane order. This lets a
producer express mixed per-plane depths that no single
PixelFormat variant can name — e.g. a
wavelet codec’s custom signal range with 12-bit luma and 10-bit
chroma, stored on a Yuv444P12Le surface with an attached
record of [12, 10, 10].
§Semantics
- Values are LSB-anchored: a plane with
bsignificant bits keeps its sample values in the lowbbits of each storage word, with the upper bits zero — the same convention as this crate’s partial-depth formats (Gray10Le,Yuv420P10Le,Gbrp12Le, …, each documented as “uses the low N bits of a 16-bit word”). Full-scale forbsignificant bits is(1 << b) - 1. - Each value must satisfy
1 ≤ b ≤ 8 × storage-word-bytesof the frame’s pixel format (so at most 8 for byte-sized planes, 16 for LE-16-bit-word planes). The record refines the storage format’s significant depth; it never changes the storage word size or plane geometry. - A record shorter than the image-plane count (or a missing record) leaves the uncovered planes at the pixel format’s own documented depth. Bytes are stored verbatim; out-of-range values are a producer bug and consumers may clamp or reject them.
Sourcepub fn plane_significant_bits(&self, plane: usize) -> Option<u8>
pub fn plane_significant_bits(&self, plane: usize) -> Option<u8>
The significant-bit count for image plane plane, or None
when no record is attached or the attached record is too short
to cover plane (fall back to the pixel format’s own depth).
Sugar over significant_bits for
per-plane lookups.
Sourcepub fn set_significant_bits(&mut self, bits: Vec<u8>)
pub fn set_significant_bits(&mut self, bits: Vec<u8>)
Attach (or replace) the frame’s per-plane significant-bits side-channel.
bits holds one byte per image plane, in plane order — see
significant_bits for the exact
semantics (LSB-anchored values, 1 ≤ b ≤ storage word bits).
The bytes are stored verbatim. An empty bits removes any
attached record instead (the sentinel requires non-empty data),
leaving the frame exactly as it was before any record was
attached. Any attached palette is unaffected.
Sourcepub fn with_significant_bits(self, bits: Vec<u8>) -> Self
pub fn with_significant_bits(self, bits: Vec<u8>) -> Self
Builder-style counterpart to
set_significant_bits for
construction chains:
VideoFrame { pts, planes }.with_significant_bits(bits).
Sourcepub fn take_significant_bits(&mut self) -> Option<Vec<u8>>
pub fn take_significant_bits(&mut self) -> Option<Vec<u8>>
Detach and return the frame’s per-plane significant-bits side-channel, if any. Afterwards the frame carries no significant-bits record (any attached palette is left in place).
Sourcepub fn image_planes(&self) -> &[VideoPlane]
pub fn image_planes(&self) -> &[VideoPlane]
The frame’s image planes — planes with the trailing
side-channel entries (palette, significant bits) excluded.
Prefer this over indexing planes directly in code that
handles side-channel-capable frames.
Sourcepub fn image_plane_count(&self) -> usize
pub fn image_plane_count(&self) -> usize
Number of image planes (excludes every side-channel entry).
Matches the stream pixel format’s
plane_count for well-formed
frames.
Trait Implementations§
Source§impl Clone for VideoFrame
impl Clone for VideoFrame
Source§fn clone(&self) -> VideoFrame
fn clone(&self) -> VideoFrame
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more