Hardware AV1 decode support by device class
A codec is only as good as the silicon that plays it. AV1 compresses beautifully, but on a device without a dedicated AV1 decode block the browser falls back to software decoding — burning CPU, draining battery, and dropping frames on exactly the mobile hardware your compression gains were meant to help. This reference is part of the VP9 vs H.265 vs AV1 codec comparison within Core Media Fundamentals & Next-Gen Formats, and maps hardware AV1 decode across the device classes you actually ship to, then shows how to detect the decode path at runtime and fall back gracefully when it is software.
Why the hardware/software split matters more for AV1
AV1’s decode toolchain is heavier than VP9 or H.264: larger superblocks, more intra modes, the constrained directional enhancement filter (CDEF), and loop restoration all have to be reconstructed per frame. A fixed-function hardware decoder does this at negligible power cost. A software decoder — dav1d, the excellent AV1 software decoder that ships in Chromium and Firefox — is fast for its class, but it still runs on the CPU, and the difference in the field is stark:
- Power: hardware AV1 decode of a 1080p stream draws a fraction of a watt on the media block;
dav1ddoing the same on four little cores can pull 2–4 W, visibly heating a phone and cutting battery life during video-heavy sessions. - Frame stability: software decode of 4K AV1 exceeds the sustained throughput of most 2020-era mobile SoCs, producing dropped frames and jank. At 1080p
dav1dcopes on modern cores but leaves little headroom for the rest of the page. - Thermal throttling: sustained software decode raises SoC temperature, which throttles the CPU, which slows everything else on the page — including your JavaScript and layout.
Warning: Passing the MediaSource.isTypeSupported() check does not mean hardware decode. That API returns true whenever the browser can decode the codec at all — including in software. To distinguish hardware from software you must use the MediaCapabilities API’s powerEfficient flag, covered below.
Hardware AV1 decode matrix by device class
The following reflects the first hardware generation in each family to ship a fixed-function AV1 decode block. Anything older in that family falls back to dav1d software decode.
Desktop and laptop
| Device class | First AV1-decode hardware | Max hardware profile | Notes |
|---|---|---|---|
| Apple Silicon (Mac) | M3 / M3 Pro / M3 Max (2023) | 8K, 10-bit, 4:2:0 | M1/M2 have no AV1 hardware decode — they use dav1d software |
| Intel iGPU | 11th gen Core “Tiger Lake” (2020) | 8K, 10-bit | Xe-LP media engine; also in Arc discrete GPUs |
| AMD GPU | RDNA 2 (RX 6000, 2020) | 8K, 10-bit | Ryzen 6000+ mobile APUs inherit the same VCN block |
| Nvidia GPU | RTX 30 “Ampere” (2020) | 8K, 10-bit | GTX 16-series and RTX 20-series decode AV1 in software only |
| Older desktop (pre-2020) | none | — | Full software decode via dav1d |
Mobile and TV
| Device class | First AV1-decode hardware | Typical ceiling | Notes |
|---|---|---|---|
| Apple (iPhone/iPad) | A17 Pro / iPhone 15 Pro (2023) | 4K, 10-bit | A16 and earlier iPhones have no AV1 hardware decode |
| Qualcomm Snapdragon | 8 Gen 1 (2022) | 4K/8K, 10-bit | Adreno media block; mid-tier 7-series lagged a generation |
| Google Tensor | Tensor G2 / Pixel 7 (2022) | 4K | Pixel 6 (Tensor G1) decodes AV1 in hardware for some profiles |
| MediaTek Dimensity | 1000 / 9000 series (2020–2022) | 4K | Present on many mid-range Android devices |
| Samsung Exynos | 2200 (2022) | 8K | Model-region dependent within the same phone name |
| Smart TV / streaming stick | AV1-badged 2020+ (Amazon Fire TV, many Android TV) | 4K HDR | Netflix/YouTube AV1 rollout drove TV silicon adoption |
| Budget / older mobile (pre-2022) | none | — | Software dav1d; avoid 4K AV1 entirely |
The critical takeaway: the install base is bimodal. Flagship 2022+ phones and 2020+ desktops decode AV1 in hardware, but a very large tail of A16-and-earlier iPhones, M1/M2 Macs, and mid-range Android devices decode it in software. The diagram below shows how a single AV1 source lands on that split, and where the fallback decision belongs:
Detecting the decode path at runtime
The MediaCapabilities.decodingInfo() method is the only reliable, standards-based way to ask the browser not just can you decode this but is it smooth and power-efficient. It returns three booleans: supported, smooth, and powerEfficient. The last one is your hardware-decode proxy.
// Ask the browser whether it can decode AV1 1080p AND do so power-efficiently.
// powerEfficient === true is the practical signal for "hardware decode block present".
async function canPlayAv1Efficiently() {
if (!('mediaCapabilities' in navigator)) return false; // Safari <17 lacks the API
const config = {
type: 'media-source', // use 'file' for progressive <video src>; results can differ
video: {
contentType: 'video/mp4; codecs="av01.0.05M.08"', // AV1 profile 0, level 3.1, Main, 8-bit
width: 1920,
height: 1080,
bitrate: 3_000_000, // ~3 Mbps 1080p; the probe is resolution AND bitrate sensitive
framerate: 24,
},
};
const info = await navigator.mediaCapabilities.decodingInfo(config);
// supported: can decode at all (may be software)
// smooth: expected to keep up with the framerate
// powerEfficient: expected to use a hardware/fixed-function path
return info.supported && info.powerEfficient;
}
Tradeoff: powerEfficient is a browser estimate, not a hardware register read. Chromium derives it from an internal capability table keyed on GPU/SoC; it is accurate on the device classes above but can report conservatively on brand-new silicon the table has not been updated for. Treat powerEfficient: false as “prefer a fallback” rather than an absolute prohibition, and combine it with navigator.hardwareConcurrency and navigator.deviceMemory for low-end heuristics — the same belt-and-suspenders approach the codec comparison guide recommends for isTypeSupported.
Wiring it into source selection
// Choose the codec variant based on the decode-path probe, then set the source.
// This keeps AV1 for devices that decode it in hardware and routes everyone else
// to VP9/WebM or H.264/MP4 to avoid the software-decode battery penalty.
async function pickVideoSource(videoEl, variants) {
// variants = { av1: 'clip.av1.mp4', vp9: 'clip.vp9.webm', h264: 'clip.h264.mp4' }
if (await canPlayAv1Efficiently()) {
videoEl.src = variants.av1;
} else if (MediaSource.isTypeSupported('video/webm; codecs="vp9"')) {
videoEl.src = variants.vp9; // VP9 has far broader hardware decode (2017+ silicon)
} else {
videoEl.src = variants.h264; // universal baseline, always hardware-decoded
}
}
Battery and jank impact of software decode
Quantifying the cost of getting this wrong makes the fallback strategy easy to justify. The figures below are representative of a mid-range 2021 phone (Snapdragon 7-series, no AV1 hardware block) playing a 1080p24 stream in a background loop.
| Decode path | Sustained CPU | Extra power draw | Frame drops (1080p) | Frame drops (4K) |
|---|---|---|---|---|
| Hardware AV1 (SD 8 Gen 1) | ~3% | negligible (media block) | none | none |
Software AV1 (dav1d, mid SoC) |
45–70% | +2 to +4 W | occasional under load | severe / unwatchable |
| Hardware VP9 (2017+ SoC) | ~4% | negligible | none | rare |
| Hardware H.264 (universal) | ~2% | negligible | none | none |
Tradeoff: For a decorative background loop, software-decoded AV1 is almost never worth it — the battery and thermal cost outweighs a 20–30% bandwidth saving the user did not ask for. For primary content the user actively chose to watch (a course video, a product demo), a brief software-decode session at 1080p is tolerable on modern cores, but you should still cap resolution and prefer VP9 when powerEfficient is false.
Fallback strategy that respects the install base
- Encode a three-tier ladder: AV1/MP4 (best compression), VP9/WebM (broad hardware decode), and H.264/MP4 (universal). The AV1-vs-VP9 Lambda encode guide covers producing the first two cheaply.
- Gate AV1 on
powerEfficient, notsupported. Serving AV1 to a software-decode device is the failure mode; the API distinguishes them. - Cap AV1 resolution on uncertain devices. If you must serve AV1 to a
powerEfficient: falsedevice, ceiling it at 1080p — never 4K — because 4K software AV1 exceeds most mobile CPUs’ sustained throughput. - Respect
prefers-reduced-motion. For background video especially, a static poster frame sidesteps the decode question entirely for users who opt out of motion.
Common mistakes and fixes
1. Treating isTypeSupported as a hardware check
Anti-pattern: if (MediaSource.isTypeSupported('...av01...')) videoEl.src = av1;
Effect: Every device with dav1d — which is essentially all modern browsers — passes this check, so you ship AV1 to M1 Macs and A16 iPhones that then decode it in software, heating the device and dropping frames.
Fix: Use decodingInfo() and branch on powerEfficient, as shown above.
2. Assuming Apple Silicon means AV1 hardware decode
Anti-pattern: “It’s an M-series Mac / a Pro iPhone, so AV1 is hardware-accelerated.”
Effect: M1, M2, and A16-and-earlier chips have no AV1 hardware decode block. Only M3+ Macs and the A17 Pro (iPhone 15 Pro) onward added it. A blanket assumption ships software-decoded AV1 to a huge Apple install base.
Fix: Never infer decode capability from the brand. Probe with MediaCapabilities, which returns powerEfficient: false on those chips.
3. Probing without bitrate and resolution
Anti-pattern: Calling decodingInfo() with only a contentType.
Effect: The spec requires width, height, bitrate, and framerate in the video config. Omitting them makes the call reject or return unreliable results, and powerEfficient becomes meaningless.
Fix: Always pass a realistic resolution/bitrate/framerate that matches the variant you would actually serve.
4. Serving 4K AV1 as the only option
Anti-pattern: A single 4K AV1 rendition with no lower tiers.
Effect: Software-decode devices cannot sustain 4K AV1; playback stutters or stalls entirely.
Fix: Always ship a resolution ladder and a VP9/H.264 fallback, and let the <video> source order plus the runtime probe pick the right one.
5. Ignoring the type: 'media-source' vs 'file' distinction
Anti-pattern: Probing with type: 'file' but delivering via MSE (or vice versa).
Effect: The two pipelines can report different powerEfficient values on some browsers; a mismatch means your probe does not describe the path the video actually takes.
Fix: Match the type in decodingInfo() to your delivery method — 'media-source' for MSE/ABR players, 'file' for a plain <video src>.
Related
- VP9 vs H.265 vs AV1: video codec comparison for production pipelines — the full codec-selection and
<video>fallback-ladder context this matrix informs - AV1 vs VP9 encode time on AWS Lambda — producing the AV1 and VP9 renditions this fallback strategy switches between
- Cache-Control headers for image and video assets — caching poster frames and per-codec variants for the fallback ladder
- MIME type configuration for modern media servers — sending the exact
av01codec string so decoders route correctly - Core Media Fundamentals & Next-Gen Formats — parent section covering format strategy across the delivery pipeline