How librav1e Maps BT.2020 and sRGB Color Spaces
This article explains how the Rust-based AV1 encoder,
librav1e, handles and maps standard color spaces like
BT.2020 and sRGB. You will learn how the encoder configures color
metadata parameters—specifically color primaries, transfer
characteristics, and matrix coefficients—to ensure playback devices
accurately render the intended colors.
How librav1e Handles Color Spaces
In video encoding, librav1e (the C-compatible library
interface for the rav1e AV1 encoder) does not typically
perform active color space conversion on the raw pixel data. Instead, it
relies on the application feeding it the video frames (such as FFmpeg or
a custom pipeline) to handle the pixel conversions (e.g., RGB to
YUV).
librav1e’s primary job is to write the correct
VUI (Video Usability Information) metadata into the AV1
sequence headers. This metadata tells the decoder precisely how to
interpret the YUV or RGB pixel values.
To define a color space, librav1e utilizes the
ITU-T H.273 / ISO/IEC 23091-2 standard, which breaks
down color description into three distinct variables:
- Color Primaries: Defines the red, green, blue, and white point coordinates (the color gamut).
- Transfer Characteristics: Defines the opto-electronic transfer function (the gamma curve).
- Matrix Coefficients: Defines the mathematical formula used to transition between RGB and YUV color spaces.
Mapping sRGB in librav1e
The sRGB color space is the standard for web graphics, monitors, and
standard-definition digital content. In librav1e, mapping
an sRGB source requires configuring the following metadata values:
- Color Primaries: sRGB shares the exact same
chromaticity coordinates as the ITU-R BT.709 standard. Therefore,
librav1emaps this toColorPrimaries::BT709(Value:1). - Transfer Characteristics: Standard sRGB uses a
specific gamma curve defined by IEC 61966-2-1. In
librav1e, this maps toTransferCharacteristics::SRGB(Value:13). - Matrix Coefficients:
- If the video is converted to YUV (standard practice for
compression), it maps to
MatrixCoefficients::BT709(Value:1). - If the video is encoded as raw RGB (lossless/high-fidelity), it maps
to
MatrixCoefficients::Identity(Value:0).
- If the video is converted to YUV (standard practice for
compression), it maps to
Mapping BT.2020 in librav1e
BT.2020 is the standard for Ultra-High-Definition (UHD) and High Dynamic Range (HDR) video, featuring a much wider color gamut than sRGB. When mapping BT.2020, the configuration depends on whether the content is Standard Dynamic Range (SDR) or High Dynamic Range (HDR).
- Color Primaries: For all BT.2020 content, this is
mapped to
ColorPrimaries::BT2020(Value:9). - Transfer Characteristics:
- For BT.2020 SDR: Mapped to
TransferCharacteristics::BT2020_10(Value:14) orBT2020_12(Value:15). - For HDR (PQ / HDR10): Mapped to
TransferCharacteristics::SMPTE2084(Value:16). - For HDR (HLG): Mapped to
TransferCharacteristics::HLG(Value:18).
- For BT.2020 SDR: Mapped to
- Matrix Coefficients: BT.2020 uses a distinct color
matrix for YUV conversion. This is mapped to
MatrixCoefficients::BT2020NCL(Non-Constant Luminance, Value:9).
Configuring the Parameters in the Code
When programmatically configuring librav1e or using the
rav1e API in Rust, you define these settings inside the
Sequence configuration using the
ColorDescription struct.
use rav1e::prelude::*;
let mut config = Config::default();
// Example: Configuring for HDR BT.2020 (PQ)
config.enc.color_description = Some(ColorDescription {
color_primaries: ColorPrimaries::BT2020,
transfer_characteristics: TransferCharacteristics::SMPTE2084,
matrix_coefficients: MatrixCoefficients::BT2020NCL,
});By explicitly setting these properties in the encoder configuration,
librav1e embeds the correct flags into the AV1 bitstream.
This guarantees that downstream video players, web browsers, and TV
displays read the metadata and map the colors to your screen exactly as
intended.