Hardware vs Software Decoding: Two Roads to Playback
A coworker’s video plays fine on your phone but stutters into a slideshow on an older tablet; another video stutters even on the new phone. The devices are usually fine — the player took different decode routes: hardware or software. Understanding the two roads gives stutter troubleshooting a handle.
What the two routes are
Hardware decoding runs on dedicated silicon: the media engine in a phone SoC or the decode unit in a GPU. These pipelines are built for specific codecs — H.264, HEVC, VP9, AV1 — and never touch general CPU cores. Efficient and cool-running, they handle 4K easily, but only for codecs on the chip’s list.
Software decoding runs the decode algorithm on general-purpose CPU: any codec with an algorithm implementation can be decoded, no format discrimination; the price is full CPU load, heat, battery drain, and dropped frames when the resolution outruns the compute. ffmpeg.wasm in a browser is software decoding running on WebAssembly.
Codec generations vs chip support
The hardware list is divided by chip generation: H.264, a decade-plus standard, is supported nearly everywhere; HEVC needs mid-to-high-end chips from 2015 on; VP9 spread through recent devices; AV1 only the newest generation. This is why HEVC video will not open on an old phone — not corruption, just absence from the chip’s list.
Within a codec there are further splits: the same H.264 in Baseline/Main/High Profile may decode differently across devices, and 10-bit H.264 lacks hardware support on many older chips. A player’s capability is really a two-dimensional table: codec × profile × bit depth.
A stutter troubleshooting order
When playback stutters or shows a black screen, first inspect the file’s parameters (codec, profile, resolution, bitrate) with a detection tool, then match: codec missing from the device list → convert to H.264; resolution beyond the device’s decode capability (4K stutter on older devices) → downsize to 1080p; parameters all fine → check the bitrate, and the storage card’s read speed as a possible bottleneck.
One more easily missed cause: a broken or end-placed index in the container (moov box at the tail), which breaks seeking during streaming — a container problem, not a decode problem; remuxing fixes it.
The browser-local reality
Processing video with ffmpeg.wasm in a browser is pure software decoding: decode, filters and encode all run on the CPU via WebAssembly. The upside is broad format coverage, unbound by chip lists; the cost is speed bounded by CPU performance, so high-bitrate files take noticeably longer.
The browser’s other road is WebCodecs: the browser exposes hardware encoders/decoders to web apps, and eligible tool paths call the hardware encoder first for near-native speed. The same tool may take different paths on different browsers and devices — automatic environment detection at work, not a bug.
Choosing codecs by the viewer’s device
Picking a codec for “who will watch” is really picking from their hardware list: content for an unknown audience belongs in H.264 (near-universal support); known-modern audiences can take HEVC/AV1 for better compression; archival masters may use efficient codecs, accepting software-decode cost on playback.
The reverse also holds: when a file will not play or stutters, the first question is whether the codec is on the viewer’s hardware list — not whether the file is broken. Inspect first, convert second, and most “won’t play” cases resolve within minutes.
Common misconceptions
One: hardware decoding looks worse than software. Modern hardware decoders match standard implementations; edge cases exist on old chips for nonstandard profiles, which is “unsupported,” not “worse quality.” Two: stutter means a bad device — it is more often a file-side issue: codec off the list, bitrate over capability, or a tail-placed index. Check the file before blaming the device.
Three: browser video processing is always slow. Software decode is CPU-bound, but the hardware encode path (when WebCodecs is available) approaches desktop software speed. Processing time depends on which route was taken and on the source’s codec and resolution.