google/ExoPlayer · error · VpxDecoderException
Vpx decoder does not support secure decode.
Error message
Vpx decoder does not support secure decode.
What it means
The VpxDecoder constructor rejects playback when a non-null CryptoConfig is supplied (the stream is DRM-protected) but the loaded libvpx build does not advertise secure decode support (VpxLibrary.vpxIsSecureDecodeSupported() == false). Secure decode requires a specially built libvpx with protected-path support.
Source
Thrown at extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java:84
* @param cryptoConfig The {@link CryptoConfig} object required for decoding encrypted content.
* May be null and can be ignored if decoder does not handle encrypted content.
* @param threads Number of threads libvpx will use to decode.
* @throws VpxDecoderException Thrown if an exception occurs when initializing the decoder.
*/
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);
}View on GitHub (pinned to dd430f7053)
Solutions
- For DRM VP9 content, prefer the platform/MediaCodec secure decoder (setSecureDecoder(true) path) instead of the libvpx extension.
- If you truly need libvpx secure decode, rebuild the extension's native code with secure-decode support so vpxIsSecureDecodeSupported() returns true.
- At track selection, exclude the libvpx renderer for DRM-protected content by inspecting whether the format requires crypto.
- As a last resort allow non-secure playback only if the license permits it (clear-content fallback).
Example fix
// before
// DRM VP9 session routed to LibvpxVideoRenderer -> throws in VpxDecoder ctor
// after
RenderersFactory factory = new DefaultRenderersFactory(context) {
@Override protected void buildVideoRenderers(...) {
// skip LibvpxVideoRenderer when the content uses DRM
if (drmScheme == null) super.buildVideoRenderers(...);
}
}; Defensive patterns
Strategy: validation
Validate before calling
boolean secureVpx = VpxLibrary.isAvailable() && VpxLibrary.vpxIsSecureDecodeSupported();
if (drmContent && !secureVpx) { /* exclude libvpx renderer for this track */ } Prevention
- Route DRM-protected VP9 to MediaCodec secure decoders, not the extension.
- If secure libvpx is required, build the extension with secure-decode support and assert vpxIsSecureDecodeSupported() in tests.
- Mark DRM tracks during track selection and filter renderers by format.cryptoType.
When it happens
Trigger: DrmSessionManager provides a CryptoConfig for the VP9 track (e.g. Widevine L1 secure decoder required) while the extension's libvpx was built without secure decode. Combination of DRM content plus the software VP9 extension.
Common situations: Playing Widevine-protected VP9 through the libvpx extension on a stock extension build; devices where the hardware secure path is unavailable so ExoPlayer falls back to the extension renderer with a CryptoConfig.
Related errors
- Failed to render output buffer to surface: decoder is not in
- Failed to load decoder native libraries.
- Failed to initialize decoder
- Buffer render failed.
- Attempting to open a session using a dummy ExoMediaDrm.
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/6eff3541e083c18c.
Report an issue: GitHub.