google/ExoPlayer · error · Gav1DecoderException
Failed to render output buffer to surface: decoder is not in
Error message
Failed to render output buffer to surface: decoder is not initialized.
What it means
Gav1DecoderException thrown by Libgav1VideoRenderer.renderOutputBufferToSurface when its decoder field is null, i.e. renderOutputBufferToSurface was called before the renderer initialized the decoder (during init) or after it was released/reset. It is a state/lifecycle misuse guard on the renderer, not a decode failure.
Source
Thrown at extensions/av1/src/main/java/com/google/android/exoplayer2/ext/av1/Libgav1VideoRenderer.java:167
/** {@inheritDoc} */
@Override
protected final Gav1Decoder createDecoder(Format format, @Nullable CryptoConfig cryptoConfig)
throws Gav1DecoderException {
TraceUtil.beginSection("createGav1Decoder");
int initialInputBufferSize =
format.maxInputSize != Format.NO_VALUE ? format.maxInputSize : DEFAULT_INPUT_BUFFER_SIZE;
Gav1Decoder decoder =
new Gav1Decoder(numInputBuffers, numOutputBuffers, initialInputBufferSize, threads);
this.decoder = decoder;
TraceUtil.endSection();
return decoder;
}
@Override
protected void renderOutputBufferToSurface(VideoDecoderOutputBuffer outputBuffer, Surface surface)
throws Gav1DecoderException {
if (decoder == null) {
throw new Gav1DecoderException(
"Failed to render output buffer to surface: decoder is not initialized.");
}
decoder.renderToSurface(outputBuffer, surface);
outputBuffer.release();
}
@Override
protected void setDecoderOutputMode(@C.VideoOutputMode int outputMode) {
if (decoder != null) {
decoder.setOutputMode(outputMode);
}
}
@Override
protected DecoderReuseEvaluation canReuseDecoder(
String decoderName, Format oldFormat, Format newFormat) {
return new DecoderReuseEvaluation(
decoderName,View on GitHub (pinned to dd430f7053)
Solutions
- Only invoke renderOutputBufferToSurface after the renderer's initialization has produced a decoder (i.e. within the normal renderer callback lifecycle)
- Serialize renderer lifecycle operations (init/flush/release) on the playback thread so no render call overlaps release
- Null-check the decoder in derived code before calling this protected method
Example fix
// before
renderer.renderOutputBufferToSurface(buffer, surface);
// after: guard in subclasses / callers
if (renderer != null && isRendererInitialized()) {
renderer.renderOutputBufferToSurface(buffer, surface);
} Defensive patterns
Strategy: validation
Validate before calling
// In subclasses/callers of Libgav1VideoRenderer: confirm init ran before render
// (decoder is created in createDecoder during renderer initialization)
if (renderer.isInitialized() && !renderer.isReleased()) { // your own lifecycle flags
renderer.renderOutputBufferToSurface(buffer, surface);
} Try / catch
try {
renderer.renderOutputBufferToSurface(outputBuffer, surface);
} catch (Gav1DecoderException e) {
if (e.getMessage() != null && e.getMessage().contains("not initialized")) {
// lifecycle race: renderer was released/reset mid-render; drop the buffer
outputBuffer.release();
} else {
throw e;
}
} Prevention
- Never call renderer render methods outside the playback thread lifecycle (onEnabled -> onDisabled)
- Serialize release with in-flight renders on the same thread
- Treat 'decoder is not initialized' as a signal of a lifecycle race, not a decode bug
When it happens
Trigger: Calling renderOutputBufferToSurface from outside the normal playback pipeline before onEnabled/onInit completed; concurrently releasing the renderer while a render call is in flight; renderer.reset/disable set decoder = null between operations.
Common situations: Custom player code driving renderer methods directly on the wrong thread; races during stopPlayback where release nulls the decoder while a queued buffer is being rendered.
Related errors
- Invalid output mode.
- Failed to load decoder native library.
- Failed to initialize decoder. Error: ${gav1GetErrorMessage(g
- Buffer render error: ${gav1GetErrorMessage(gav1DecoderContex
- Passed buffer is not a direct ByteBuffer
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/0752f7e2bdf2b11b.
Report an issue: GitHub.