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
- Read the appended gav1GetErrorMessage text — it names the native failure (allocation vs invalid argument)
- Pass a sane positive thread count (or THREAD_COUNT_AUTODETECT) instead of a computed value that could be <= 0
- Catch Gav1DecoderException around renderer construction and fall back to platform AV1 decoding (MediaCodec) when available
- 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
- Always clamp thread counts to >= 1 before constructing the decoder
- Log the appended native message — it distinguishes allocation failure from bad arguments
- Keep a platform-decoder fallback path when software AV1 init fails
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
- Failed to load decoder native library.
- Buffer render error: ${gav1GetErrorMessage(gav1DecoderContex
- Initialization failed.
- Invalid output mode.
- Failed to render output buffer to surface: decoder is not in
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/70041db2f47f959d.
Report an issue: GitHub.