Skip to main content

Crate colconv

Crate colconv 

Source
Expand description

SIMD-dispatched per-row color-conversion kernels for the FFmpeg AVPixelFormat space.

§Design

Every source pixel format has its own kernel (yuv420p_to, nv12_to, bgr24_to, …) that walks the source row by row and hands each row to a caller-supplied PixelSink. The Sink decides what to derive — luma only, RGB only, HSV only, all three, or something custom — and writes into whatever buffers it owns.

The row the Sink receives (Self::Input<'_>) has a shape that reflects the source format: source::Yuv420pRow carries Y / U / V slices plus matrix / range metadata; packed‑RGB row types (e.g. source::Rgb24Row, source::Bgr24Row) carry a single packed slice; etc. Each source family declares a subtrait (Yuv420pSink: PixelSink<Input<'_> = Yuv420pRow<'_>>) so kernel signatures stay sharp.

For the common case — “give me RGB / Luma / HSV or any subset” — the crate ships sinker::MixedSinker, configured via with_rgb / with_luma / with_hsv to select which channels to derive.

§Supported source formats

Shipped (4:1:1, 4:2:0, 4:2:2, 4:4:0, and 4:4:4 subsampling):

FamilyBit depthSubsamplingPackingFFmpeg name
[Yuv411p]84:1:1planar (DV-NTSC legacy)yuv411p
Yuv420p84:2:0planaryuv420p
Yuv422p84:2:2planaryuv422p
Yuv440p84:4:0planaryuv440p
Yuv444p84:4:4planaryuv444p
Nv1284:2:0semi-planar UVnv12
Nv2184:2:0semi-planar VUnv21
Nv1684:2:2semi-planar UVnv16
Nv2484:4:4semi-planar UVnv24
Nv4284:4:4semi-planar VUnv42
Yuv420p994:2:0planar, low-packedyuv420p9le
Yuv420p10104:2:0planar, low-packedyuv420p10le
Yuv420p12124:2:0planar, low-packedyuv420p12le
Yuv420p14144:2:0planar, low-packedyuv420p14le
Yuv420p16164:2:0planaryuv420p16le
Yuv422p994:2:2planar, low-packedyuv422p9le
Yuv422p10104:2:2planar, low-packedyuv422p10le
Yuv422p12124:2:2planar, low-packedyuv422p12le
Yuv422p14144:2:2planar, low-packedyuv422p14le
Yuv422p16164:2:2planaryuv422p16le
Yuv440p10104:4:0planar, low-packedyuv440p10le
Yuv440p12124:4:0planar, low-packedyuv440p12le
Yuv444p994:4:4planar, low-packedyuv444p9le
Yuv444p10104:4:4planar, low-packedyuv444p10le
Yuv444p12124:4:4planar, low-packedyuv444p12le
Yuv444p14144:4:4planar, low-packedyuv444p14le
Yuv444p16164:4:4planaryuv444p16le
P010104:2:0semi-planar, high-packedp010le
P012124:2:0semi-planar, high-packedp012le
P016164:2:0semi-planarp016le
P210104:2:2semi-planar, high-packedp210le
P212124:2:2semi-planar, high-packedp212le
P216164:2:2semi-planarp216le
P410104:4:4semi-planar, high-packedp410le
P412124:4:4semi-planar, high-packedp412le
P416164:4:4semi-planarp416le
V210104:2:2packed (3 x 10-bit/u32)v210
Y210104:2:2packed, MSB-aligned u16y210le
Y212124:2:2packed, MSB-aligned u16y212le
Y216164:2:2packed, full-range u16y216le
V410104:4:4packed (one 32-bit word)v410
V30X104:4:4packed (one 32-bit word)v30xle
Xv36124:4:4packed u16 quadruplexv36le
Vuya84:4:4packed byte quadruple, source αvuya
Vuyx84:4:4packed byte quadruple, α-as-paddingvuyx
Ayuv64164:4:4packed u16 quadruple, source αayuv64le
Gbrp84:4:4planar GBR (3 planes)gbrp
Gbrap84:4:4planar GBR + A (4 planes, source α)gbrap
Xyz12124:4:4packed CIE XYZ (3 x u16, high-bit-packed: bits [15:4])xyz12le / xyz12be

Xyz12 is the DCP / digital-cinema source format. Decoding it requires a SMPTE ST 428-1 §8 inverse OETF, a 3x3 matrix to one of three target gamuts (DcpTargetGamut::DciP3 / DcpTargetGamut::Rec709 / DcpTargetGamut::Rec2020), then a sRGB-shape forward OETF and integer narrow. Every backend is native SIMD; the OETFs run scalar per lane to preserve the 0-ULP scalar↔SIMD parity contract.

§RAW (Bayer) sources

raw::Bayer (8-bit) and raw::Bayer16<BITS> (10/12/14/16-bit low-packed u16, range [0, (1 << BITS) - 1]) feed bilinear demosaic + white balance + 3x3 color-correction in a single per-row kernel. Caller supplies raw::BayerPattern (BGGR / RGGB / GRBG / GBRG), raw::WhiteBalance gains, and a raw::ColorCorrectionMatrix. See raw for the full design and parameter docs.

Scope: colconv covers demosaic onwards. Producing the Bayer plane itself is the upstream pipeline’s job — vendor-SDK camera-RAW decoders (R3D / BRAW / NRAW) for compressed camera bitstreams, or FFmpeg’s AV_PIX_FMT_BAYER_* pixel formats / bayer_* decoders for already-uncompressed Bayer sources. Once you have a BayerFrame / BayerFrame16, hand it to raw::bayer_to / raw::bayer16_to with your sink of choice.

§YUVA sources (alpha-drop)

Every shipped 4:2:0 / 4:2:2 / 4:4:4 planar family also covers its yuva* alpha variant by alpha-drop: the caller hands the Y / U / V slices from a 4-plane YUVA buffer to the matching Yuv*p*Frame constructor and ignores the alpha plane. This works today for yuva420p, yuva420p9le, yuva420p10le, yuva420p16le, yuva422p, yuva422p9le, yuva422p10le, yuva422p16le, yuva444p, yuva444p9le, yuva444p10le, and yuva444p16le (the full set of YUVA pixel formats FFmpeg produces). RGBA pass-through (preserving the alpha channel into the output) is the dedicated Ship 8 work item — it adds with_rgba / with_rgba_u16 accessors on MixedSinker plus native YUVA frame types.

§Kernel families

  • Q15 i32 family — 8-bit kernels (yuv_420_to_rgb_row, yuv_444_to_rgb_row, nv12_to_rgb_row, nv24_to_rgb_row etc.) and 10/12/14-bit kernels (yuv_420p_n_to_rgb_*<BITS>, yuv_444p_n_to_rgb_*<BITS>, p_n_to_rgb_*<BITS>). Native SIMD on every backend (NEON / SSE4.1 / AVX2 / AVX-512 / wasm simd128). Yuv422p (and the Yuv422p10 / Yuv422p12 / Yuv422p14 family) reuses Yuv420p’s per-row kernels (4:2:2 differs only in the vertical walker); same for Nv16Nv12. Yuv444p and Yuv444p10 / Yuv444p12 / Yuv444p14 use a dedicated 4:4:4 kernel family (no horizontal chroma duplication step); Nv24 and Nv42 share a 4:4:4 kernel family via a SWAP_UV const generic.
  • 16-bit family — dedicated yuv_420p16_to_rgb_*, yuv444p16_to_rgb_*, p16_to_rgb_*. Yuv422p16 reuses the 4:2:0 16-bit kernels by shape equivalence. The u8-output kernels stay on i32 (output-range scaling keeps coeff x u_d within i32). The u16-output kernels widen the chroma matrix multiply-add to i64 to avoid the ~2.31·10⁹ chroma-channel sum overflowing i32 at BITS == 16; the Y path also widens to i64 to handle limited-range unclamped samples.

§SIMD coverage

Every format above has a native SIMD backend for each supported target (NEON on aarch64; SSE4.1 / AVX2 / AVX-512 on x86_64; wasm simd128). Every u8-output and u16-output path has a native implementation on every backend — including the 16-bit u16-output paths for Yuv420p16, P016, and Yuv444p16, which use the backend-native i64 arithmetic (native _mm512_srai_epi64 on AVX-512 and i64x2_shr on wasm; srai64_15 bias trick on SSE4.1 and AVX2 because those ISAs lack native i64 arithmetic right shift).

§Not yet shipped (follow-up)

  • Bayer SIMD backends — Tier 14 currently dispatches to the scalar reference path on every target; NEON / SSE4.1 / AVX2 / AVX-512 / wasm simd128 follow-ups will land per the established backend-symmetry pattern.
  • Cinema-camera RAW source formats — vendor-decoded sensor RGB in camera-native log + gamut (LogC4 / S-Log3 / REDLog3G10 / Canon Log 2/3 / BMD Film Gen 5 / V-Log / F-Log) → working-space conversion via inverse-OETF + 3x3 matrix + sRGB OETF. Roadmap tracked in docs/superpowers/plans/2026-05-07-be-rollout-tracking.md under “Cinema Camera RAW Support Roadmap”. Mirrors the Tier 12 (source::Xyz12) shape: per-vendor source format, full MixedSinker output coverage, polynomial OETF, 5 SIMD backends.
  • Higher-quality Bayer demosaic — current scalar Bayer kernel does bilinear demosaic; AHD / Malvar / DCB are quality levers for cinema-grade proxies (CinemaDNG / DJI Inspire workflows).
  • 3D LUT (.cube) row kernel — for OCIO-style color management in cinema pipelines.

See source for the per-format module-level breakdown and frame for the validated frame types plus the BITS const generic on the high-bit-depth families (Yuv420pFrame16<BITS> and PnFrame<BITS>).

Modules§

frame
Frame primitives + the typed source-format *Frame<'a, BE> borrow types.
raw
RAW (Bayer) source kernels.
row
Crate-internal row-level primitives.
sinker
PixelSink implementations shipped with the crate.
source
Source pixel-format kernels — marker ZSTs, per-row borrow types (*Row<'a>), per-format Sink subtraits, and walker fns that iterate crate::frame::*Frame<'a, BE> row-by-row dispatching to a PixelSink.

Structs§

Ayuv64yuv-444-packed
Zero-sized marker for the packed AYUV64 source format (AV_PIX_FMT_AYUV64{LE,BE}). <const BE: bool> defaults to false (LE); the alias Ayuv64 resolves to Ayuv64<false>.
Ayuv64Frameyuv-444-packed
Validated wrapper around a packed YUV 4:4:4 16-bit AYUV64 plane.
Ayuv64Rowyuv-444-packed
One row of an Ayuv64 source — width × 4 u16 elements (4 channels per pixel: A, Y, U, V; the A slot is real source alpha).

Enums§

Ayuv64FrameErroryuv-444-packed
Errors returned by Ayuv64Frame::try_new.
ColorMatrix
Color matrix coefficients per ITU-T H.273 MatrixCoefficients (Table 4) / ISO/IEC 23001-8.
DcpTargetGamut
Target RGB gamut for the XYZ → RGB matrix step in the source::Xyz12 source pipeline (xyz12_to).

Traits§

Ayuv64Sinkyuv-444-packed
Sinks that consume rows of this source format. The <const BE> parameter encodes the source byte-order — sinkers typically impl for one specific BE matching their stored MixedSinker<Marker<BE>> monomorphization. The Row type does not carry BE; the BE-aware kernel dispatch happens inside process via the sinker’s own <const BE> parameter.
PixelSink
Base trait for sinks that consume rows of a source pixel format.
SourceFormat
Sealed marker trait identifying a source pixel format.

Functions§

ayuv64_toyuv-444-packed
LE-only back-compat wrapper preserving the pre-Phase-4 packed walker signature. Forwards to the const-generic helper with BE = false.