Retain Rec 2020 Color Space in libvpx-vp9
Retaining the Rec. 2020 color space when transcoding video to the VP9
codec using FFmpeg’s libvpx-vp9 encoder requires explicit
configuration of color metadata. This article provides a straightforward
guide on how to configure your FFmpeg command-line
parameters—specifically pixel format, color primaries, transfer
characteristics, and color space matrix—to ensure your wide color gamut
(WCG) or High Dynamic Range (HDR) metadata is fully preserved during the
conversion process.
Why Color Metadata is Lost During Transcoding
By default, FFmpeg does not always automatically copy or write color space metadata into the output bitstream or WebM container during transcoding. When players read a VP9 file missing this metadata, they usually fall back to standard definition (Rec. 601) or high definition (Rec. 709) color spaces, resulting in washed-out or heavily distorted colors. To prevent this, you must explicitly flag the color properties in your FFmpeg command.
Key FFmpeg Parameters for Rec. 2020
To properly preserve and signal the Rec. 2020 color space, you must include the following four parameters in your FFmpeg command:
-pix_fmt yuv420p10le: Rec. 2020 requires a 10-bit color depth to prevent banding. This flag forces the encoder to use 10-bit YUV 4:2:0.-color_primaries bt2020: Identifies the color gamut as Rec. 2020.-color_trc: Defines the transfer characteristics (gamma curve).- Use
smpte2084for HDR10 (PQ). - Use
arib-std-b67for HLG (Hybrid Log-Gamma). - Use
bt2020-10for SDR (Standard Dynamic Range) 10-bit Rec. 2020.
- Use
-colorspace bt2020nc: Sets the color matrix to Rec. 2020 non-constant luminance, which is the standard for most consumer video.
Step-by-Step Command Examples
Example 1: Transcoding HDR10 (PQ) to VP9
If your source video is HDR10, use the following command to encode it to VP9 while retaining the Rec. 2020 color space and Perceptual Quantizer (PQ) transfer curve:
ffmpeg -i input.mp4 \
-c:v libvpx-vp9 \
-pix_fmt yuv420p10le \
-color_primaries bt2020 \
-color_trc smpte2084 \
-colorspace bt2020nc \
-b:v 5M -crf 18 \
output.webmExample 2: Transcoding HLG to VP9
If your source is HLG, adjust the -color_trc parameter
to match the HLG transfer function:
ffmpeg -i input.mp4 \
-c:v libvpx-vp9 \
-pix_fmt yuv420p10le \
-color_primaries bt2020 \
-color_trc arib-std-b67 \
-colorspace bt2020nc \
-b:v 5M -crf 18 \
output.webmVerifying the Output File
Once the transcoding is complete, you can verify that the Rec. 2020
metadata has been successfully embedded by running ffprobe
on your output file:
ffprobe -select_streams v:0 -show_entries stream=color_space,color_transfer,color_primaries output.webmYour terminal should output the following values, confirming the color space was successfully retained:
color_range=tv
color_space=bt2020nc
color_transfer=smpte2084 (or arib-std-b67)
color_primaries=bt2020