google/ExoPlayer · critical · RuntimeException

Error instantiating AV1 extension

Error message

Error instantiating AV1 extension

What it means

DefaultRenderersFactory reflectively instantiates the optional AV1 decoder renderer (com.google.android.exoplayer2.ext.av1.Libgav1VideoRenderer) when extension renderers are enabled. ClassNotFoundException (extension not built) is expected and ignored, but any other exception while resolving the constructor or creating the instance proves the extension is present yet unusable, so the factory throws a RuntimeException with the original cause. This prevents a corrupted extension build from silently degrading playback.

Source

Thrown at library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java:432

          clazz.getConstructor(
              long.class,
              android.os.Handler.class,
              com.google.android.exoplayer2.video.VideoRendererEventListener.class,
              int.class);
      Renderer renderer =
          (Renderer)
              constructor.newInstance(
                  allowedVideoJoiningTimeMs,
                  eventHandler,
                  eventListener,
                  MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);
      out.add(extensionRendererIndex++, renderer);
      Log.i(TAG, "Loaded Libgav1VideoRenderer.");
    } catch (ClassNotFoundException e) {
      // Expected if the app was built without the extension.
    } catch (Exception e) {
      // The extension is present, but instantiation failed.
      throw new RuntimeException("Error instantiating AV1 extension", e);
    }
  }

  /**
   * Builds audio renderers for use by the player.
   *
   * @param context The {@link Context} associated with the player.
   * @param extensionRendererMode The extension renderer mode.
   * @param mediaCodecSelector A decoder selector.
   * @param enableDecoderFallback Whether to enable fallback to lower-priority decoders if decoder
   *     initialization fails. This may result in using a decoder that is slower/less efficient than
   *     the primary decoder.
   * @param audioSink A sink to which the renderers will output.
   * @param eventHandler A handler to use when invoking event listeners and outputs.
   * @param eventListener An event listener.
   * @param out An array to which the built renderers should be appended.
   */
  protected void buildAudioRenderers(

View on GitHub (pinned to dd430f7053)

Solutions

  1. Inspect the wrapped cause exception to identify whether it is a signature mismatch (NoSuchMethodException) or a native load failure (UnsatisfiedLinkError).
  2. Pin core, exoplayer-av1 (libgav1) and any UI/extension modules to the same release version.
  3. Add ProGuard keep rules so com.google.android.exoplayer2.ext.av1.Libgav1VideoRenderer and its constructor survive shrinking.
  4. Ship the extension native library for every ABI you support, or disable the extension renderer mode.

Example fix

// before
new DefaultRenderersFactory(context)
    .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER);

// after
try {
  player = new ExoPlayer.Builder(new DefaultRenderersFactory(context)
      .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER))
      .build(context);
} catch (RuntimeException e) {
  // Extension present but broken — fall back to core-only renderers.
  player = new ExoPlayer.Builder(
      new DefaultRenderersFactory(context)
          .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF))
      .build(context);
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean av1Usable = false;
try {
  Class.forName("com.google.android.exoplayer2.ext.av1.Libgav1VideoRenderer")
      .getConstructor(long.class, android.os.Handler.class,
          com.google.android.exoplayer2.video.VideoRendererEventListener.class, int.class);
  av1Usable = true;
} catch (ReflectiveOperationException ignored) {
}

Try / catch

try {
  renderersFactory = withAv1Extension(context);
} catch (RuntimeException e) {
  if (e.getCause() instanceof UnsatisfiedLinkError) {
    renderersFactory = coreOnlyFactory(context); // no AV1 extension
  } else { throw e; }
}

Prevention

When it happens

Trigger: EXTENSION_RENDERER_MODE_ON/PREFER with the ext.av1 module on the classpath whose (long, Handler, VideoRendererEventListener, int) constructor is missing (version drift), not accessible, or whose construction throws (native libgav1 .so fails to load).

Common situations: Core and extension artifacts from different ExoPlayer releases; obfuscated/shrunk release builds that altered the constructor signature; device ABI without the bundled libgav1 native library; multiple conflicting extension versions on the dependency graph.

Related errors


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