C.W.K.
Stream
Lesson 09 of 10 · published

Color Space — BT.709, BT.2020, and Not Breaking HDR

~12 min · color, hdr, bt709, bt2020

Level 0Viewer
0 XP0/73 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

Three color metadata fields that have to match

Every video has three color metadata fields and they have to be consistent for playback to be accurate.

  • color_primaries — the chromaticity of the RGB primaries (which red, green, blue does the camera think it's capturing?). BT.709 = HD/sRGB. BT.2020 = UHD/HDR.
  • color_transfer — the gamma curve. BT.709 = SDR. PQ (smpte2084) = HDR10. HLG (arib-std-b67) = broadcast HDR.
  • colorspace — the YUV→RGB matrix. BT.709 SDR. BT.2020nc UHD.

The HDR trap

If you encode an HDR source and FFmpeg doesn't write the metadata, players default to BT.709 SDR — your beautiful HDR clip looks washed-out gray. Always tag explicitly when working with HDR.

Code

Tag SDR / HDR correctly·bash
# SDR (BT.709) — explicit tagging
ffmpeg -i in.mp4 \
  -c:v libx264 -crf 20 -preset slow -pix_fmt yuv420p \
  -color_primaries bt709 -color_trc bt709 -colorspace bt709 \
  out_sdr.mp4

# HDR10 (BT.2020 + PQ)
ffmpeg -i hdr_in.mov \
  -c:v libx265 -crf 22 -preset slow -tag:v hvc1 \
  -pix_fmt yuv420p10le \
  -color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc \
  -x265-params "hdr-opt=1:repeat-headers=1:colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc" \
  out_hdr.mp4
Convert HDR → SDR when uploading to platforms that hate HDR·bash
# Tone-map HDR PQ → SDR BT.709
ffmpeg -i hdr.mov \
  -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
  -c:v libx264 -crf 20 -preset slow \
  -color_primaries bt709 -color_trc bt709 -colorspace bt709 \
  -c:a copy \
  out_sdr.mp4

External links

Exercise

Take an SDR clip and a tagged HDR clip. Probe both for color_primaries, color_transfer, colorspace. Re-encode each preserving the color metadata explicitly. If you don't have an HDR source, find one on YouTube tagged with 'HDR' (yt-dlp downloads preserve the tags) and run ffprobe on the result.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.