How Libvpx Separates VP8 and VP9 Codebase

This article provides an overview of how the Google-maintained libvpx repository structures its codebase to cleanly separate the VP8 and VP9 video codec implementations. We will examine the top-level directory layout, the internal folder structures for each codec, the shared utility libraries, and how the public API routes calls to the appropriate codec version.

The Top-Level Directory Layout

The primary method of separation in the libvpx codebase is directory-based segregation at the root of the repository. Rather than mixing the algorithms for both standards, the developers isolated the source code for each codec into its own dedicated directory:

Internal Codec Structures

Within both the vp8/ and vp9/ root folders, the code is further subdivided using a consistent architecture. Each codec directory contains three core subfolders:

  1. common/: Contains code that is utilized by both the encoder and the decoder. This includes color space conversion, block-size partitioning logic, quantization parameters, loop filtering algorithms, and basic entropy coding structures.
  2. encoder/: Contains the code exclusive to video compression. This includes motion estimation, rate control, mode decision algorithms, and bitstream packaging.
  3. decoder/: Contains the code exclusive to video decompression. This includes bitstream parsing, inverse transform logic, and motion compensation.

Shared Infrastructure: vpx_dsp and vpx_scale

While VP8 and VP9 are distinct video standards, they share low-level math operations and hardware acceleration routines. To avoid code duplication, libvpx isolates these shared components outside of the vp8/ and vp9/ directories:

API Layer Routing

The public interface for libvpx is located in the vpx/ directory. It exposes unified headers like vpx_codec.h, vpx_encoder.h, and vpx_decoder.h.

The codebase separates the implementation at the binary level using function pointers. When a developer initializes an encoder, they pass a specific algorithm interface structure, such as vpx_codec_vp8_cx() or vpx_codec_vp9_cx(). These interfaces map the general API functions (like vpx_codec_encode) to the corresponding internal functions inside either the vp8/encoder/ or vp9/encoder/ directory, keeping the runtime execution paths of both codecs entirely independent.