Matrix Coefficients
37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0Matrix coefficients define how gamma-encoded R′G′B′ is turned into one luma (Y′) and two color-difference (Cb, Cr) components, and therefore how a player turns them back. For the common systems the matrix is set by two weights, KR and KB: luma is KR·R′ + (1−KR−KB)·G′ + KB·B′. ffprobe reports the matrix as color_space.
The matrix is independent of primaries, transfer and range, although in practice each video system uses a fixed combination of all four.
Code points
Section titled “Code points”| Code | FFmpeg name | Coefficients / meaning | Where you see it |
|---|---|---|---|
| 0 | gbr | Identity: the planes are G, B, R | RGB video, lossless screen captures, 4:4:4 RGB encodes |
| 1 | bt709 | KR 0.2126, KB 0.0722 | HD and most web video |
| 2 | unknown | Not specified | Untagged files; the player guesses |
| 4 | fcc | KR 0.30, KB 0.11 | Obsolete |
| 5 | bt470bg | KR 0.299, KB 0.114 (BT.601) | PAL/SECAM SD; also sYCC and JPEG-style YCbCr |
| 6 | smpte170m | Same coefficients as 5 | NTSC SD, DVD |
| 7 | smpte240m | KR 0.212, KB 0.087 | Early 1990s HDTV; obsolete |
| 8 | ycgco | YCgCo | Rare |
| 9 | bt2020nc | KR 0.2627, KB 0.0593, non-constant luminance | UHD and HDR (HDR10, HLG) |
| 10 | bt2020c | BT.2020 constant luminance | Specified but almost never used |
| 11 | smpte2085 | Y′D′zD′x | Rare |
| 12 / 13 | chroma-derived-nc / chroma-derived-c | Coefficients computed from the signalled primaries | Rare |
| 14 | ictcp | BT.2100 ICtCp | Rare in delivery |
| 15 | ipt-c2 | IPT-C2 | Dolby Vision profile 5 |
| 16 / 17 | ycgco-re / ycgco-ro | Reversible YCgCo | Lossless coding |
Codes 5 and 6 are the same matrix, so for conversion purposes “BT.601” covers both; tag whichever matches the source system. Other tools use other spellings for the same numbers: SVT-AV1 uses bt601 for 6 and bt2020-ncl for 9, VapourSynth uses 170m and 2020ncl.
The BT.601 versus BT.709 mistake
Section titled “The BT.601 versus BT.709 mistake”Decoding with the wrong matrix barely changes grays, but it shifts saturated colors: reds, greens and skin tones are where you notice it. It is easy to miss without the source next to the encode. The usual causes:
- Untagged SD upscaled to HD. The SD source is BT.601. After scaling to 1080p, players that guess by resolution switch to BT.709. mpv, for example, assumes BT.709 when the width is at least 1280 or the height is above 576.
- Tagging instead of converting. Writing
bt709onto BT.601 pixels changes nothing in the pixels; it makes every player decode them wrongly. - RGB sources converted by FFmpeg. Converting PNG frames, screen captures or other RGB input to YUV uses the BT.601 matrix by default and leaves the output untagged, which an HD player then decodes as BT.709.
When the resolution class changes, convert the matrix at the same time as scaling. Commands for FFmpeg zscale and VapourSynth resize are in the color guide. For RGB input, choose the matrix explicitly and tag the result:
ffmpeg -i input.png -vf scale=out_color_matrix=bt709,format=yuv420p,setparams=color_primaries=bt709:color_trc=bt709 -c:v libx264 output.mkvBT.2020 constant and non-constant luminance
Section titled “BT.2020 constant and non-constant luminance”bt2020nc (9) is the normal choice for UHD SDR, HDR10 and HLG; BT.2100 uses the same non-constant-luminance Y′CbCr. bt2020c (10) is a different signal and needs different maths to decode, so changing the tag from 9 to 10, or the reverse, is never a fix. ICtCp (14) is a separate HDR representation from BT.2100, not a variant of BT.2020 Y′CbCr.