{"record":{"id":"26dcfec4dee9535c","repo":"google/ExoPlayer","slug":"buffer-render-failed","errorCode":null,"errorMessage":"Buffer render failed.","messagePattern":"Buffer render failed\\.","errorType":"exception","errorClass":"VpxDecoderException","httpStatus":null,"severity":"error","filePath":"extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java","lineNumber":208,"sourceCode":"    lastSupplementalData = null;\n    vpxClose(vpxDecContext);\n  }\n\n  /**\n   * Sets the output mode for frames rendered by the decoder.\n   *\n   * @param outputMode The output mode.\n   */\n  public void setOutputMode(@C.VideoOutputMode int outputMode) {\n    this.outputMode = outputMode;\n  }\n\n  /** Renders the outputBuffer to the surface. Used with OUTPUT_MODE_SURFACE_YUV only. */\n  public void renderToSurface(VideoDecoderOutputBuffer outputBuffer, Surface surface)\n      throws VpxDecoderException {\n    int getFrameResult = vpxRenderFrame(vpxDecContext, surface, outputBuffer);\n    if (getFrameResult == -1) {\n      throw new VpxDecoderException(\"Buffer render failed.\");\n    }\n  }\n\n  private native long vpxInit(\n      boolean disableLoopFilter, boolean enableRowMultiThreadMode, int threads);\n\n  private native long vpxClose(long context);\n\n  private native long vpxDecode(long context, ByteBuffer encoded, int length);\n\n  private native long vpxSecureDecode(\n      long context,\n      ByteBuffer encoded,\n      int length,\n      @Nullable CryptoConfig mediaCrypto,\n      int inputMode,\n      byte[] key,\n      byte[] iv,","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java#L190-L226","documentation":"VpxDecoder.renderToSurface calls the native vpxRenderFrame to push a decoded YUV buffer to a Surface (OUTPUT_MODE_SURFACE_YUV only) and throws when the native call returns -1. The render failed inside libvpx/JNI — typically because the Surface is invalid (released consumer), dimensions changed, or the context/Surface pairing broke.","triggerScenarios":"vpxRenderFrame(vpxDecContext, surface, outputBuffer) == -1 while using OUTPUT_MODE_SURFACE_YUV. Happens when the Surface was destroyed/replaced, when rendering after decoder release, or when the buffer format does not match the surface buffers.","commonSituations":"SurfaceView surface detached during playback; switching surfaces without resetting output mode; backgrounding the app mid-frame; using surface-YUV mode with a Surface from an ImageReader of mismatched size.","solutions":["Prefer the default OUTPUT_MODE_YUV with a VideoDecoderOutputBufferRenderer instead of OUTPUT_MODE_SURFACE_YUV.","Ensure the Surface stays valid while rendering: only call setVideoSurface with a live surface, and clear it (null) before releasing it.","If the surface is replaced, re-initialize the decoder/surface pairing before further render calls.","Catch VpxDecoderException at the player level and re-prepare playback to recover."],"exampleFix":"// before\nplayer.setVideoSurface(surface);\nsurface.release(); // then a frame arrives -> vpxRenderFrame fails\n\n// after\nplayer.setVideoSurface(null);\nsurface.release();\n// later, attach a new valid surface before playback resumes\nplayer.setVideoSurface(newSurface);","handlingStrategy":"try-catch","validationCode":"// Ensure surface is valid before attaching:\nif (!surface.isValid()) { player.setVideoSurface(null); }","typeGuard":null,"tryCatchPattern":"catch (VpxDecoderException e) { player.setVideoSurface(null); player.prepare(); } // recover by re-preparing on a fresh surface","preventionTips":["Prefer OUTPUT_MODE_YUV with a VideoDecoderOutputBufferRenderer.","Detach the surface (setVideoSurface(null)) before releasing it.","Re-attach a new surface after SurfaceTexture/Surface replacement instead of rendering to the dead one."],"tags":["vp9","libvpx","surface","render","exoplayer-extension"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}