google/ExoPlayer · error · Gav1DecoderException
Invalid output mode.
Error message
Invalid output mode.
What it means
Gav1DecoderException thrown by Gav1Decoder.renderToSurface when outputBuffer.mode is not C.VIDEO_OUTPUT_MODE_SURFACE_YUV. renderToSurface is only valid when the decoder was configured to render YUV frames directly onto a surface; buffers produced in buffer-output mode (or default mode 0) cannot be pushed to the surface path.
Source
Thrown at extensions/av1/src/main/java/com/google/android/exoplayer2/ext/av1/Gav1Decoder.java:177
* @param outputMode The output mode.
*/
public void setOutputMode(@C.VideoOutputMode int outputMode) {
this.outputMode = outputMode;
}
/**
* Renders output buffer to the given surface. Must only be called when in {@link
* C#VIDEO_OUTPUT_MODE_SURFACE_YUV} mode.
*
* @param outputBuffer Output buffer.
* @param surface Output surface.
* @throws Gav1DecoderException Thrown if called with invalid output mode or frame rendering
* fails.
*/
public void renderToSurface(VideoDecoderOutputBuffer outputBuffer, Surface surface)
throws Gav1DecoderException {
if (outputBuffer.mode != C.VIDEO_OUTPUT_MODE_SURFACE_YUV) {
throw new Gav1DecoderException("Invalid output mode.");
}
if (gav1RenderFrame(gav1DecoderContext, surface, outputBuffer) == GAV1_ERROR) {
throw new Gav1DecoderException(
"Buffer render error: " + gav1GetErrorMessage(gav1DecoderContext));
}
}
/**
* Initializes a libgav1 decoder.
*
* @param threads Number of threads to be used by a libgav1 decoder.
* @return The address of the decoder context or {@link #GAV1_ERROR} if there was an error.
*/
private native long gav1Init(int threads);
/**
* Deallocates the decoder context.
*View on GitHub (pinned to dd430f7053)
Solutions
- Ensure setOutputMode(C.VIDEO_OUTPUT_MODE_SURFACE_YUV) is invoked on the decoder before any renderToSurface call (Libgav1VideoRenderer.setDecoderOutputMode does this, but only when decoder != null)
- Set the decoder output mode immediately after constructing the decoder, before processing any buffers
- If you need raw frames, use the buffer path (decodeToOutputBuffer) instead of the surface path
Example fix
// before decoder.renderToSurface(outputBuffer, surface); // throws if mode never set // after decoder.setOutputMode(C.VIDEO_OUTPUT_MODE_SURFACE_YUV); decoder.renderToSurface(outputBuffer, surface);
Defensive patterns
Strategy: validation
Validate before calling
if (outputBuffer.mode == C.VIDEO_OUTPUT_MODE_SURFACE_YUV) {
decoder.renderToSurface(outputBuffer, surface);
} else {
// wrong path: consume the buffer via decodeToOutputBuffer() instead
outputBuffer.release();
} Try / catch
try {
decoder.renderToSurface(outputBuffer, surface);
} catch (Gav1DecoderException e) {
if (e.getMessage() != null && e.getMessage().contains("Invalid output mode")) {
decoder.setOutputMode(C.VIDEO_OUTPUT_MODE_SURFACE_YUV); // correct state and retry once
decoder.renderToSurface(outputBuffer, surface);
} else {
throw e;
}
} Prevention
- Set the output mode immediately after decoder construction, before any buffers flow
- Treat renderToSurface as valid only in SURFACE_YUV mode per its javadoc
- Centralize mode selection in one place so the renderer and decoder cannot disagree
When it happens
Trigger: Calling renderToSurface without first calling setOutputMode(C.VIDEO_OUTPUT_MODE_SURFACE_YUV) on the decoder; calling it while the renderer operates in decoder-output-buffer mode; renderer called setDecoderOutputMode before the decoder instance existed, so the mode was never applied.
Common situations: Custom renderer code that renders to a SurfaceView-backed surface but never sets the output mode; switching between output modes mid-playback; using Libgav1VideoRenderer with a surface while another component forced buffer mode for screenshot/processing.
Related errors
- Buffer render error: ${gav1GetErrorMessage(gav1DecoderContex
- Failed to render output buffer to surface: decoder is not in
- Failed to load decoder native library.
- Failed to initialize decoder. Error: ${gav1GetErrorMessage(g
- Passed buffer is not a direct ByteBuffer
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/d37f2d92012e0e63.
Report an issue: GitHub.