google/ExoPlayer · error · VpxDecoderException

Failed to initialize decoder

Error message

Failed to initialize decoder

What it means

The native vpxInit(...) call returned 0, meaning libvpx could not allocate a decoder context. The native libraries loaded fine, but context creation failed — most commonly a threading/memory issue (threads count invalid or out of memory) or an incompatible libvpx build.

Source

Thrown at extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java:89

  public VpxDecoder(
      int numInputBuffers,
      int numOutputBuffers,
      int initialInputBufferSize,
      @Nullable CryptoConfig cryptoConfig,
      int threads)
      throws VpxDecoderException {
    super(new DecoderInputBuffer[numInputBuffers], new VideoDecoderOutputBuffer[numOutputBuffers]);
    if (!VpxLibrary.isAvailable()) {
      throw new VpxDecoderException("Failed to load decoder native libraries.");
    }
    this.cryptoConfig = cryptoConfig;
    if (cryptoConfig != null && !VpxLibrary.vpxIsSecureDecodeSupported()) {
      throw new VpxDecoderException("Vpx decoder does not support secure decode.");
    }
    vpxDecContext =
        vpxInit(/* disableLoopFilter= */ false, /* enableRowMultiThreadMode= */ false, threads);
    if (vpxDecContext == 0) {
      throw new VpxDecoderException("Failed to initialize decoder");
    }
    setInitialInputBufferSize(initialInputBufferSize);
  }

  @Override
  public String getName() {
    return "libvpx" + VpxLibrary.getVersion();
  }

  @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. Retry playback with fewer decode threads (LibvpxVideoRenderer constructor parameter) or leave the default.
  2. Free memory / release other decoders before initializing; catch VpxDecoderException and fall back to MediaCodec VP9.
  3. If building from source, ensure the JNI vpxInit wrapper matches the Java signature and libvpx version.
  4. Enable decoder fallback (DefaultRenderersFactory.setEnableDecoderFallback(true)) so playback continues with another decoder.

Example fix

// before
LibvpxVideoRenderer renderer = new LibvpxVideoRenderer(0, handler, listener, 16, threads); // threads too high

// after
int threads = Math.min(4, Runtime.getRuntime().availableProcessors());
LibvpxVideoRenderer renderer = new LibvpxVideoRenderer(0, handler, listener, 16, threads);
Defensive patterns

Strategy: retry

Validate before calling

int threads = Math.min(4, Runtime.getRuntime().availableProcessors()); // sane value before constructing the renderer

Try / catch

catch (VpxDecoderException e) on init -> optionally retry once with fewer threads, else fall back to MediaCodec.

Prevention

When it happens

Trigger: vpxInit(false, false, threads) == 0 in the VpxDecoder constructor. Seen with invalid thread counts, low-memory conditions on entry-level devices, or a mismatched JNI wrapper/libvpx pairing in custom builds.

Common situations: Custom builds of the extension where the JNI signature changed; devices under memory pressure during codec initialization; passing an extreme number of decode threads from LibvpxVideoRenderer's constructor argument.

Related errors


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