VP9 10-bit and 12-bit Color Depth in libvpx

This article provides a technical overview of how the libvpx library manages 10-bit and 12-bit color depths for the VP9 video codec. It covers the specific VP9 profiles designated for high bit depths, the build-time requirements for libvpx, how the library represents high bit-depth pixels in memory, and the encoding parameters required to output these formats.

VP9 Profiles for High Bit Depth

The VP9 specification defines four profiles (0 through 3) to handle different color depths and chroma subsampling configurations. Standard 8-bit video uses Profile 0 (4:2:0) and Profile 1 (4:2:2 or 4:4:4). To manage higher color depths, libvpx utilizes Profile 2 and Profile 3: * Profile 2: Supports 10-bit and 12-bit color depth with 4:2:0 chroma subsampling. * Profile 3: Supports 10-bit and 12-bit color depth with 4:2:2 or 4:4:4 chroma subsampling, as well as alpha channel support.

When encoding, the library selects the appropriate profile based on the input color space and specified target bit depth.

Compilation Requirements

To process 10-bit and 12-bit color depths, libvpx must be compiled with high bit-depth support enabled. This is controlled during the build configuration phase. Developers must include the --enable-vp9-highbitdepth flag when configuring the build script. Without this flag, libvpx compiles with an 8-bit optimized codebase to minimize binary size and memory usage, rendering it unable to process 10-bit or 12-bit inputs.

Internal Pixel Representation

When high bit-depth support is enabled, libvpx alters how it represents image data in system memory: * Data Structures: Instead of using standard 8-bit unsigned integers (uint8_t) for pixel values, libvpx transitions to 16-bit unsigned integers (uint16_t) to hold the luma and chroma samples. * Memory Footprint: This transition doubles the memory required to store uncompressed video frames in RAM during the encoding and decoding processes. * SIMD Optimizations: libvpx utilizes specialized assembly and SIMD (Single Instruction, Multiple Data) instructions (such as AVX2 or NEON) specifically written to handle 16-bit array operations efficiently, minimizing the performance penalty of processing larger pixel values.

Encoding Configuration and Parameters

To encode a 10-bit or 12-bit VP9 video using libvpx (via tools like vpxenc or FFmpeg), specific parameters must be passed to the encoder: * Bit Depth Parameter: The --bit-depth parameter in vpxenc must be explicitly set to 10 or 12. * Input Format: The input color space must match the target depth. For 10-bit 4:2:0 video, the pixel format is typically set to yuv420p10le (little-endian). For 12-bit, yuv420p12le is used. * Profile Selection: While libvpx can auto-detect the profile, developers can explicitly force --profile=2 for 10-bit/12-bit 4:2:0 video to ensure compatibility with target hardware decoders.