Skip to content

Color Primaries

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

Color primaries say which exact red, green and blue the RGB values refer to, plus the white point. Together they define the gamut: the triangle of colors the signal can express. ffprobe reports them as color_primaries.

Primaries are a separate property from the transfer function and the matrix, but each video system uses a fixed set, so in practice the three tags usually agree: BT.709 everywhere for HD, BT.2020 everywhere for UHD and HDR.

CodeFFmpeg nameSystemWhere you see it
1bt709BT.709; also the sRGB primariesHD video, web video, sRGB images
2unknownNot specifiedUntagged files; the player guesses
4bt470mBT.470 System MObsolete NTSC
5bt470bgBT.470 System B/G, BT.601 625-linePAL/SECAM SD and DVD
6smpte170mSMPTE 170M, BT.601 525-lineNTSC SD and DVD
7smpte240mSMPTE 240M; same as 6Obsolete
8filmGeneric film, illuminant CRare
9bt2020BT.2020 / BT.2100UHD SDR, HDR10, HLG, Dolby Vision
10smpte428CIE 1931 XYZ (SMPTE ST 428-1)Digital cinema distribution masters
11smpte431DCI-P3, DCI white pointCinema
12smpte432P3 with D65 white (P3-D65)Display P3 content, Apple devices
22ebu3213EBU Tech 3213-E / JEDEC P22Rare

The chromaticities you need most often, for example when writing HDR mastering metadata:

PrimariesRed (x, y)Green (x, y)Blue (x, y)White (x, y)
BT.709 / sRGB0.640, 0.3300.300, 0.6000.150, 0.060D65: 0.3127, 0.3290
BT.601 525 (SMPTE 170M)0.630, 0.3400.310, 0.5950.155, 0.070D65
BT.20200.708, 0.2920.170, 0.7970.131, 0.046D65
P3 (DCI and D65)0.680, 0.3200.265, 0.6900.150, 0.060D65, or DCI 0.314, 0.351

SVT-AV1 calls code 6 bt601 and code 7 smpte240; VapourSynth uses 170m, 2020, st432-1, and so on. The number is the same everywhere.

Untagged SD. NTSC and PAL primaries differ slightly from BT.709. Players guess when the tag is missing — mpv picks BT.709 for anything 1280 wide or over 576 high, PAL for 576 lines and NTSC for 480 or 486 — so tag SD encodes with the source system or convert them when upscaling (see the color guide).

BT.2020 is a container, not the content’s real gamut. Most HDR is graded on a P3-D65 monitor and delivered in BT.2020. The stream is tagged bt2020; the mastering-display metadata records P3. Don’t tag such a stream smpte432 because the grade was P3 — the samples are BT.2020 values.

BT.2020 does not mean HDR. UHD SDR also uses BT.2020 primaries. Whether a stream is HDR is decided by the transfer (smpte2084 or arib-std-b67).

P3 variants. DCI-P3 and P3-D65 share primaries but differ in white point. Apple’s Display P3 is P3-D65 primaries with the sRGB transfer, so it is tagged smpte432 plus iec61966-2-1.

Retagging does not change the gamut. Tagging BT.709 pixels as bt2020 makes every color look oversaturated; tagging BT.2020 pixels as bt709 makes them look dull. Going from a wide gamut to a narrow one is a real conversion that has to decide what to do with colors outside the smaller triangle — use zscale, libplacebo or VapourSynth resize with explicit input and output primaries, and tone-map at the same time if the source is HDR (see tone mapping).