How libavif Manages Multiple Encoder and Decoder Backends
The open-source libavif library serves as a portable
middleware layer that allows applications to encode and decode AVIF
images using various underlying AV1 codecs. This article explains how
libavif abstracts different encoder and decoder
backends—such as aom, dav1d, rav1e, and SVT-AV1—managing them
simultaneously through compile-time configuration, a unified internal
API, and dynamic runtime selection.
The Unified Codec Abstraction Layer
At the core of libavif’s multi-backend capability is its
abstraction layer, defined in its internal source code (specifically
within the codec interface headers). Rather than forcing application
developers to write custom code for each AV1 library,
libavif defines a generic interface structure (often
referred to as avifCodec).
Every supported backend has a corresponding wrapper file (e.g.,
codec_aom.c, codec_dav1d.c,
codec_svt.c) that implements this generic interface. These
wrappers translate libavif’s standardized commands for
configuration, image feeding, and compressed payload extraction into the
specific API calls required by the underlying third-party library.
Compile-Time Selection and Configuration
libavif determines which backends are available at
compile time using CMake build flags. Developers can enable or disable
specific encoders and decoders depending on their platform requirements,
licensing constraints, or performance needs.
Common build flags include: * AVIF_CODEC_AOM: Enables
the Alliance for Open Media Reference Encoder/Decoder (supports both
encoding and decoding). * AVIF_CODEC_DAV1D: Enables the
highly optimized dav1d decoder (decoding only). *
AVIF_CODEC_SVT: Enables the SVT-AV1 encoder (encoding
only). * AVIF_CODEC_RAV1E: Enables the Rust-based rav1e
encoder (encoding only).
When these flags are toggled, the CMake build system compiles only
the enabled wrappers and links the corresponding external libraries into
the final libavif binary.
Runtime Selection and Priority Queue
If a binary is compiled with multiple backends enabled simultaneously
(for example, having both aom and dav1d
available for decoding), libavif manages them using an
internal priority list and developer-controlled settings.
Automatic Choice (Default)
By default, libavif uses an internal preference order
optimized for performance. For decoding, it will prioritize
dav1d over aom because dav1d is
generally faster and more resource-efficient. For encoding, it will
choose the first available encoder in its default list (usually
preferring aom or SVT-AV1).
Explicit API Selection
Developers can override the automatic selection at runtime. The
avifEncoder and avifDecoder structures feature
a codecChoice member variable. By setting this variable,
developers can explicitly force the library to use a specific
backend:
AVIF_CODEC_CHOICE_AUTO: Letlibavifchoose.AVIF_CODEC_CHOICE_AOM: Force the use of AOM.AVIF_CODEC_CHOICE_DAV1D: Force the use of dav1d.AVIF_CODEC_CHOICE_SVT: Force the use of SVT-AV1.
If the requested codec is not compiled into the binary,
libavif will return an initialization error, allowing the
application to gracefully fall back to another choice.