Check VP9 Hardware Decoding Support Programmatically

This article explains how to programmatically detect whether a client device supports hardware-accelerated decoding for the VP9 video codec (libvpx-vp9). You will learn how to implement these checks across different platforms, including web browsers using modern JavaScript APIs, Android devices using native APIs, and desktop environments using system-level queries.

Web Browsers: Media Capabilities API

In web applications, the most reliable way to check for hardware-accelerated VP9 decoding is the Media Capabilities API. Older APIs like HTMLMediaElement.canPlayType() only indicate if a codec can be played, but they do not specify whether the decoding is handled by the CPU (software) or GPU (hardware).

The navigator.mediaCapabilities.decodingInfo() method returns a promise containing a powerEfficient boolean. In browser environments, powerEfficient is the standard indicator for hardware acceleration, as software decoding consumes significantly more battery.

Here is how to perform the check in JavaScript:

async function checkVP9HardwareDecoding() {
  if (!navigator.mediaCapabilities) {
    console.log("Media Capabilities API not supported in this browser.");
    return { supported: false, hardwareAccelerated: false };
  }

  const videoConfig = {
    type: 'file', // Can also be 'media-source' for MSE
    video: {
      contentType: 'video/webm; codecs="vp9"',
      width: 1920,
      height: 1080,
      bitrate: 5000000, // 5 Mbps
      framerate: 60
    }
  };

  try {
    const result = await navigator.mediaCapabilities.decodingInfo(videoConfig);
    console.log(`VP9 Support: ${result.supported}`);
    console.log(`Hardware Accelerated (Power Efficient): ${result.powerEfficient}`);
    console.log(`Smooth Playback: ${result.smooth}`);
    
    return {
      supported: result.supported,
      hardwareAccelerated: result.powerEfficient
    };
  } catch (error) {
    console.error("Error checking media capabilities:", error);
    return { supported: false, hardwareAccelerated: false };
  }
}

checkVP9HardwareDecoding();

Android: MediaCodecList API

On Android, you can query the system’s media codec list to check if a hardware decoder is available for the video/x-vnd.on2.vp9 mime type.

Starting with Android 10 (API level 29), the MediaCodecInfo class provides the isHardwareAccelerated() method. For older versions, you must rely on codec naming conventions (hardware decoders typically start with OMX.google for software fallback, while hardware-backed decoders contain vendor names like OMX.qcom, OMX.Exynos, OMX.MTK, or use the newer c2.android vs c2.hardware naming scheme).

Here is the implementation in Kotlin:

import android.media.MediaCodecList
import android.media.MediaCodecInfo
import android.os.Build

fun hasVP9HardwareDecoder(): Boolean {
    val codecList = MediaCodecList(MediaCodecList.REGULAR_CODECS)
    val codecInfos = codecList.codecInfos

    for (codecInfo in codecInfos) {
        if (codecInfo.isEncoder) continue

        val types = codecInfo.supportedTypes
        for (type in types) {
            if (type.equals("video/x-vnd.on2.vp9", ignoreCase = true)) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    if (codecInfo.isHardwareAccelerated) {
                        return true
                    }
                } else {
                    // Fallback for API < 29: Analyze the codec name
                    val name = codecInfo.name.lowercase()
                    val isSoftware = name.startsWith("omx.google.") || 
                                     name.startsWith("c2.android.") || 
                                     !name.startsWith("omx.") && !name.startsWith("c2.")
                    if (!isSoftware) {
                        return true
                    }
                }
            }
        }
    }
    return false
}

Windows: DirectX Video Acceleration (DXVA2 / D3D11)

For native Windows desktop applications (C++), you must query Direct3D11 or DXVA2 to check if the GPU driver registers a VP9 decoder device.

You can check this by instantiating a ID3D11VideoDevice and calling GetVideoDecoderProfileCount and GetVideoDecoderProfile to iterate through the supported GUIDs. Look for the following VP9 profile GUIDs:

If the driver returns these GUIDs during capabilities discovery, the graphics hardware supports VP9 hardware decoding.