Skip to content

Color Formats

currentMigrated from docs/colorimetry/format.mdx at 37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0

A pixel format says how decoded samples are laid out in memory: the color model and component order, chroma subsampling, bit depth, whether components are packed or planar, and, for samples wider than a byte, the endianness. It says nothing about what the colors mean — that is the job of primaries, transfer, matrix and range. A yuv420p10le file can be SDR BT.709, HDR10 or HLG.

RGB stores red, green and blue directly. It is what displays ultimately show and what most image formats and screen captures use, but it compresses poorly because the three channels are highly correlated.

Y′CbCr, usually called YUV in software, stores luma (Y′, a weighted sum of the gamma-encoded R′G′B′) and two color-difference channels (Cb, Cr). Almost all video codecs work in Y′CbCr because most detail ends up in luma, and the chroma channels can be stored at reduced resolution. The weights come from the matrix coefficients. Y′ is not the same as physical luminance.

Component order is written out in the name: rgb24 stores R, G, B; bgr24 stores B, G, R.

NotationChroma resolutionFFmpeg example
4:2:0Half width, half heightyuv420p
4:2:2Half width, full heightyuv422p
4:4:4Full resolutionyuv444p

4:2:0 is used by DVD, Blu-ray, UHD Blu-ray, broadcast, streaming and almost all camera footage, because the reduced chroma resolution is rarely visible in natural images. 4:2:2 is common in professional cameras and intermediate codecs such as ProRes. 4:4:4 is worth it for screen recordings, game footage with UI, and text overlays, where thin colored edges smear and alias at 4:2:0.

Converting a 4:2:0 source to 4:4:4 doesn’t recover chroma detail — it only makes the file bigger. Encode in the source’s subsampling unless you mean to reduce it, and check that the target profile and players support 4:2:2 or 4:4:4 before using them (most hardware decoders and browsers expect 4:2:0).

Subsampled chroma also has a chroma location: where each chroma sample sits relative to the luma samples. ffprobe reports it as chroma_location (left is the MPEG-2/H.264/HEVC default; topleft is also common). Keep it unchanged when re-encoding and let the scaler know it when resampling.

Bit depth is the number of bits per component sample: 8 for most SDR delivery, 10 for HDR and for many AV1 and HEVC encodes, 12 for some cinema and Dolby Vision masters.

Names can count bits per component or per pixel. RGB888 means 8 bits each for R, G and B; RGB565 means 5, 6 and 5 bits. A per-pixel name such as RGB24 (24 bits in total) or RGB16 doesn’t tell you how the bits are split.

Packed formats interleave the components of each pixel:

RGB RGB RGB RGB …

Planar formats store each component in its own plane:

R R R R …
G G G G …
B B B B …

Planar layouts make per-channel processing and chroma subsampling simple, so video codecs and VapourSynth use them almost exclusively. Packed layouts are common in hardware, capture devices and image APIs. FFmpeg marks planar formats with p (yuv420p, gbrp); rgb24 is packed.

Samples wider than 8 bits are stored in 16-bit words, and the byte order matters. FFmpeg names end in le (little-endian, least significant byte first) or be. yuv420p10le stores each 10-bit sample in the low bits of a little-endian 16-bit word; it is not a tightly packed 10-bit stream. Reading data with the wrong depth, order or endianness produces garbage colors, which is the usual cause when a raw pipe between two programs looks wrong. VapourSynth formats are always in native byte order.

VapourSynthFFmpegLayout
GRAY8grayOne 8-bit plane
GRAY16gray16leOne 16-bit plane
RGB24gbrpPlanar RGB, 8 bits; FFmpeg stores the planes in G, B, R order
—rgb24Packed RGB, 8 bits
RGBSgbrpf32lePlanar RGB, 32-bit float
YUV420P8yuv420pPlanar 4:2:0, 8 bits
YUV422P8yuv422pPlanar 4:2:2, 8 bits
YUV444P8yuv444pPlanar 4:4:4, 8 bits
YUV420P10yuv420p10lePlanar 4:2:0, 10 bits in 16-bit words
YUV422P10yuv422p10lePlanar 4:2:2, 10 bits
YUV444P10yuv444p10lePlanar 4:4:4, 10 bits

ffmpeg -pix_fmts lists every format your build knows. FFmpeg also has yuvj420p and other yuvj variants, which are old aliases for full-range 8-bit Y′CbCr; see color range.