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:

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.

  1. 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).
  2. Initialization Attempt: libavif calls the initialization function of the preferred backend’s API wrapper.
  3. 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—libavif catches this failure.
  4. 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.