NV21 (source code)

= NV21
{c}

\b[NV21] is an eight-bit <YCbCr> <semiplanar pixel format> using 4:2:0 <chroma subsampling>. It has a full-resolution <luma (video)> plane followed by interleaved colour-difference samples in \b[Cr, Cb] order. <NV12> uses the reverse pair order, Cb, Cr. The separately allocated Linux variant is <NV21M>.<Planar YUV formats in the Linux Kernel documentation>[Semi-Planar overview table; NV12/NV21/NV12M/NV21M subsection]{ref}

An original $4\times2$ tightly stored image has eight luma <bytes> followed by four colour-difference bytes. Suppose the latter are `200 40 150 90`. Under NV21, the two pairs are $(C_r,C_b)=(200,40)$ and $(150,90)$. Reading the same bytes as <NV12> instead assigns $(C_b,C_r)=(200,40)$ and $(150,90)$. The buffer length remains correct while its colour-difference channels are exchanged.

Converting this declared NV21 buffer to <NV12> requires swapping adjacent bytes in the interleaved plane, giving `40 200 90 150`, while retaining the luma data. This is a layout conversion, not a conversion to the <RGB color model>. The numerical colour interpretation still depends on the declared <YCbCr> encoding.

The active footprint is $3WH/2$ <bytes> for even width $W$ and height $H$ under eight-bit 4:2:0 sampling. <Framebuffer stride> can add padding, so the next row need not start immediately after the last active sample. A converter must apply the actual row and plane boundaries: swapping pairs across padding or across the luma plane would corrupt the image rather than exchange the intended channels.