google/ExoPlayer · critical · Gav1DecoderException

Failed to initialize decoder. Error: ${gav1GetErrorMessage(g

Error message

Failed to initialize decoder. Error: ${gav1GetErrorMessage(gav1DecoderContext)}

What it means

Gav1DecoderException thrown when gav1Init(threads) returns GAV1_ERROR (or the context is flagged as errored immediately after init), meaning native libgav1 failed to create a decoder context. The message includes gav1GetErrorMessage() output from native code describing the concrete failure.

Source

Thrown at extensions/av1/src/main/java/com/google/android/exoplayer2/ext/av1/Gav1Decoder.java:82

      int numInputBuffers, int numOutputBuffers, int initialInputBufferSize, int threads)
      throws Gav1DecoderException {
    super(new DecoderInputBuffer[numInputBuffers], new VideoDecoderOutputBuffer[numOutputBuffers]);
    if (!Gav1Library.isAvailable()) {
      throw new Gav1DecoderException("Failed to load decoder native library.");
    }

    if (threads == Libgav1VideoRenderer.THREAD_COUNT_AUTODETECT) {
      // Try to get the optimal number of threads from the AV1 heuristic.
      threads = gav1GetThreads();
      if (threads <= 0) {
        // If that is not available, default to the number of available processors.
        threads = getRuntime().availableProcessors();
      }
    }

    gav1DecoderContext = gav1Init(threads);
    if (gav1DecoderContext == GAV1_ERROR || gav1CheckError(gav1DecoderContext) == GAV1_ERROR) {
      throw new Gav1DecoderException(
          "Failed to initialize decoder. Error: " + gav1GetErrorMessage(gav1DecoderContext));
    }
    setInitialInputBufferSize(initialInputBufferSize);
  }

  @Override
  public String getName() {
    return "libgav1";
  }

  @Override
  protected DecoderInputBuffer createInputBuffer() {
    return new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT);
  }

  @Override
  protected VideoDecoderOutputBuffer createOutputBuffer() {
    return new VideoDecoderOutputBuffer(this::releaseOutputBuffer);

View on GitHub (pinned to dd430f7053)

Solutions

  1. Read the appended gav1GetErrorMessage text — it names the native failure (allocation vs invalid argument)
  2. Pass a sane positive thread count (or THREAD_COUNT_AUTODETECT) instead of a computed value that could be <= 0
  3. Catch Gav1DecoderException around renderer construction and fall back to platform AV1 decoding (MediaCodec) when available
  4. Free memory / reduce concurrent decoders if the native allocation fails under pressure

Example fix

// before
int threads = Libgav1VideoRenderer.THREAD_COUNT_AUTODETECT;
Gav1Decoder decoder = new Gav1Decoder(numIn, numOut, initialInputBufferSize, threads);

// after: clamp explicit thread counts and fall back on failure
int threads = Math.max(1, requestedThreads);
try {
  decoder = new Gav1Decoder(numIn, numOut, initialInputBufferSize, threads);
} catch (Gav1DecoderException e) {
  Log.e(TAG, "libgav1 init failed: " + e.getMessage(), e);
  decoder = null; // let the pipeline pick the platform AV1 decoder
}
Defensive patterns

Strategy: try-catch

Validate before calling

int threads = requestedThreads;
if (threads == Libgav1VideoRenderer.THREAD_COUNT_AUTODETECT) {
  threads = Math.max(1, Runtime.getRuntime().availableProcessors());
}
// gav1Init cannot fail on an invalid thread count if threads >= 1 is guaranteed

Try / catch

try {
  Gav1Decoder decoder = new Gav1Decoder(numIn, numOut, initialInputBufferSize, threads);
} catch (Gav1DecoderException e) {
  String msg = e.getMessage(); // contains gav1GetErrorMessage() detail
  Log.e(TAG, "libgav1 init failed: " + msg, e);
  // fall back to platform AV1 renderer by not adding Libgav1VideoRenderer
}

Prevention

When it happens

Trigger: Constructing Gav1Decoder with a resolved thread count <= 0 or absurdly large when THREAD_COUNT_AUTODETECT path produced a bad value; native memory exhaustion when allocating the decoder context; corrupted or mismatched libgav1 build versus the Java bindings.

Common situations: Low-memory devices where the native allocation fails; custom libgav1 builds with an incompatible JNI surface; passing an explicit negative thread count.

Related errors


AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14). Data as JSON: /api/errors/70041db2f47f959d. Report an issue: GitHub.