How libavif Handles Codec Fallbacks
This article explains how the libavif library manages
fallback mechanisms when a preferred AV1 codec backend fails or is
unavailable. It covers compilation-time configuration, runtime codec
selection priorities, and how the library transitions to alternative
codec backends to ensure seamless AVIF image decoding and encoding.
Codec Backend Availability
libavif does not implement the AV1 video standard
directly. Instead, it relies on external third-party codec libraries
(backends) to perform the actual encoding and decoding of AV1
bitstreams. Common decoding backends include dav1d (highly
optimized for speed) and aom. Common encoding backends
include aom, rav1e, and
SVT-AV1.
At compile-time, developers configure which backends to build into
libavif using CMake flags (e.g.,
AVIF_CODEC_DAV1D=ON or AVIF_CODEC_AOM=ON).
Multiple backends can be compiled into a single binary, providing the
foundation for fallback mechanisms.
Runtime Codec Selection and Priority
When decoding or encoding an AVIF image, libavif must
choose which compiled-in backend to use. This choice is governed by the
avifCodecChoice enum, which can be configured via
avifDecoderSetCodecChoice() or
avifEncoderSetCodecChoice().
By default, this is set to AVIF_CODEC_CHOICE_AUTO. Under
the auto setting, libavif uses a hardcoded priority list to
select the best available backend:
- For Decoding:
libavifprioritizesdav1ddue to its superior decoding speed. Ifdav1dis not compiled into the library, it falls back toaom. - For Encoding:
libavifprioritizesaom, followed byrav1e, and thenSVT-AV1.
How Fallback Occurs During Initialization
The fallback mechanism in libavif is primarily an
initialization-time fallback. When a decode or encode
operation is triggered, the library attempts to initialize the
first-choice codec backend determined by the priority list.
- Check Capability: The library queries the preferred codec to verify if it supports the specific image configuration (such as the required bit depth or chroma subsampling format).
- Initialization Attempt:
libavifcalls the initialization function of the preferred backend’s API wrapper. - Fallback Trigger: If the preferred backend fails to
initialize—either because it was not successfully compiled, lacks
support for the specific profile, or fails to allocate internal
memory—
libavifcatches this failure. - Alternative Selection: Instead of returning an immediate error to the calling application, the library loops to the next available backend in its priority list and attempts initialization again.
This process continues until a backend initializes successfully or
all available backends have been exhausted, at which point the library
returns AVIF_RESULT_NO_CODEC_AVAILABLE.
Mid-Stream Failures and Error Handling
It is important to distinguish between initialization-time fallback and mid-operation fallback.
If a codec backend successfully initializes but encounters a critical
error during the actual decoding or encoding of a frame (such
as a corrupted bitstream or memory exhaustion mid-process),
libavif does not automatically switch to a
different backend.
Attempting to switch backends mid-stream on a failing block of data
is highly inefficient and can lead to inconsistent state. In this
scenario, libavif halts the operation and immediately
returns an explicit error code to the application, such as
AVIF_RESULT_DECODE_COLOR_FAILED or
AVIF_RESULT_BMFF_PARSE_FAILED. The calling application must
then decide whether to re-attempt the operation with a manually forced
alternative codec.