Skip to main content

mediaframe/source/
nv16.rs

1//! NV16 — semi‑planar 4:2:2 (`AV_PIX_FMT_NV16`).
2//!
3//! Layout: one full‑size Y plane + one interleaved UV plane at half
4//! width and **full height** (one UV row per Y row, vs NV12's one UV
5//! row per two Y rows). Each UV row is `U0, V0, U1, V1, …`.
6//!
7//! Per‑row kernel reuses [`super::Nv12`]'s `nv12_to_rgb_row` verbatim
8//! — the half‑width interleaved UV layout is identical. The 4:2:0 →
9//! 4:2:2 difference is purely vertical: Nv12 reads UV row `r / 2`,
10//! Nv16 reads UV row `r`. The sinker calls
11//! [`crate::row::nv12_to_rgb_row`] directly.
12
13use crate::frame::Nv16Frame;
14
15walker! {
16  semi_planar {
17    /// Zero‑sized marker for the NV16 source format. Used as the `F` type
18    /// parameter on `MixedSinker`.
19    #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
20    marker: Nv16,
21    frame: Nv16Frame<'_>,
22    row: Nv16Row,
23    sink: Nv16Sink,
24    walker: nv16_to,
25    elem_type: u8,
26    chroma_field: uv,
27    chroma_plane: uv,
28    chroma_stride: uv_stride,
29    chroma_elems_per_row: |w| w,
30    chroma_v: full,
31    row_doc: "One output row of an NV16 source handed to an [`Nv16Sink`].\n\n\
32              Carries borrows to the source slices (full-width Y, half-width interleaved\n\
33              UV) plus the row index and matrix/range carry-throughs. Unlike NV12, no two\n\
34              Y rows share a UV row.",
35    walker_doc: "Converts an NV16 frame by walking its rows and feeding each one to\n\
36                 the [`Nv16Sink`]. Chroma advances every row (vs NV12's `row / 2`).",
37  }
38}