DRM and codecs
Why some phones play HD and others do not: DRM security levels and codec capabilities are hardware claims, not software features, and the platform can only expose what the silicon supports.
Streaming video on a phone is a negotiation between four parties: the app, the platform's DRM framework, the studio's licence server, and the silicon. The last one is the one users never see and the one that decides whether a phone gets HD.
TL;DR#
- MediaDrm is the platform API for DRM. It is a container for a DRM scheme, not a scheme itself.
- Widevine is the scheme Android devices ship, with security levels tied to where the keys and the decode path live.
- A device's DRM level is a hardware property; software cannot upgrade it. This is why two phones on the same Android version stream different quality.
- MediaCodec capabilities are likewise per device. The platform exposes what the vendor declares.
- AV1, HEVC and other codecs are supported only where the hardware or a performant software decoder exists; the platform does not ship a universal decoder for everything.
Mental model#
Think of a cinema with a projector, a film canister and a licence.
The film is the content. The projector is the codec. The licence is the DRM scheme, enforced by the studio. The vault is the secure hardware where the keys live.
A cinema with a cheap projector can still show the film, but the studio may refuse to send the high-quality print because the projector cannot guarantee the print will not be copied. That refusal is the security level.
Where the analogy breaks#
A cinema has one projector. A phone's decode path can be partly hardware and partly software, and the DRM system may accept a hardware path for one resolution and reject it for another. The levels are per-resolution in practice, which is why "HD" and "4K" can have different requirements.
The big picture#
Text description of this diagram
A six-stage pipeline. The app opens a MediaDrm session for a scheme, generates a key request, and sends it to the licence server. The server evaluates the device's attestation and security level and returns a licence with keys and policy. The app provides the licence bytes to the session, which keeps the keys where the security level puts them. The decoder then decrypts into a protected buffer that the app cannot read, and the compositor displays the frames. Screenshots of protected content are black because the secure path is working as designed.
The comparison is the whole DRM story in one line: it is not about whether the phone can decode the stream, it is about whether the content owner trusts the path the frames take.
Deep dive#
MediaDrm: a container for a scheme#
MediaDrm is deliberately generic. It takes a UUID identifying a DRM scheme and provides:
- key request/response exchange with a licence server,
- session management,
- secure decoder selection,
- provisioning.
The platform ships Widevine as the standard scheme, but the API is not Widevine-specific. The point of the abstraction is that a device or a region can use a different scheme without the app's playback code changing.1
Security levels, and why they matter to users#
Widevine defines security levels that describe where keys and decoding happen. The distinction that matters commercially:
- A software level means the keys and decoded frames are accessible to the OS. Content owners typically allow lower resolutions here.
- A hardware level means keys are held in a TEE and the decode path is protected. HD and 4K licences generally require this.
An app cannot change the level. It can only ask what the device supports and request a licence accordingly. That is why the same Netflix account streams HD on one phone and SD on another: the licence server saw a different level.
The secure decode path#
When a hardware DRM level is in use, the decoder is configured to write into a protected buffer that the normal graphics pipeline cannot read. The compositor can still put it on screen — it has to, or the user would see nothing — but the app's process cannot read the pixels.
This is why screen recording and screenshotting of protected content produce black frames. It is not an app restriction; it is the hardware path working as designed.
Codecs: what "supported" means#
MediaCodecList reports the codecs a device exposes, with:
- the MIME type,
- whether it is a hardware or software codec,
- the profiles and levels it supports,
- the maximum resolution and frame rate,
- whether it supports secure playback.
A codec's presence is a vendor decision. The platform's CDD sets a floor — certain codecs must be present for certain device classes — but everything above the floor is optional.1
Why AV1 is different#
AV1 is a modern codec with excellent compression, and its support on Android is uneven because it is expensive to decode in software. A device with an AV1 hardware decoder can play it cheaply; a device without one may decode it on the CPU, which drains the battery and drops frames at high resolution.
The platform's approach is to let the device declare what it can do. An app that wants AV1 should
query MediaCodecList for a hardware decoder and fall back to another codec when there is none. This
is why adaptive streaming manifests list several codecs: the player picks one the device can actually
sustain.
Adaptive streaming and the codec negotiation#
In practice, an app does not choose a codec directly. It hands a manifest to a player, and the player chooses a variant based on:
- the codecs the device reports,
- the DRM level the licence server will accept,
- the current bandwidth,
- the display's resolution and HDR capability.
That negotiation is why "why does my phone stream at 720p" has so many possible answers. The player may have chosen 720p because the device lacks a hardware decoder for the 1080p codec, or because the DRM level only permits SD/HD, or because the network measured lower than it is.
HDR, and one more capability layer#
HDR adds another dimension: the display must support the transfer function and colour space, the codec must support the HDR profile, and the DRM path must permit it. A phone can have an HDR display and still receive SDR streams because the decode path is not certified for the HDR profile.
This is the general pattern of the module: media quality is the minimum of several independent capability claims, not the maximum.
How it evolved#
| API | Version | What changed |
|---|---|---|
| 18 | 4.3 Jelly Bean |
|
| 23 | 6.0 Marshmallow |
|
| 28 | 9 Pie |
|
| 30 | 11 |
|
| 31 | 12 |
|
| 33 | 13 Tiramisu |
|
| 37 | 17 Cinnamon Bun |
|
Under the hood#
- the MediaDrm implementation and plugin loading
- the Codec2 framework
- MediaDrm.javathe app-facing DRM API
- MediaCodecList.javacodec enumeration
Curiosity corner#
- A screenshot of protected video is black on purpose. The secure path is working; the app never had the pixels.
- DRM is why some phones cannot play a trailer in 4K but can record 4K. Recording and playback have different trust requirements.
- The licence server, not the app, decides the quality tier. The app asks; the server looks at the device's attestation and answers.
Try it#
adb shell cmd media.codec list
adb shell dumpsys media.drm | head -40
adb shell dumpsys media.player | grep -i codec | head -20
Example output
MediaCodecList:
video/avc c2.qti.avc.decoder hardware secure: true
video/av01 c2.android.av1.decoder software secure: false
MediaDrm:
vendor: Google name: Widevine securityLevel: L1The securityLevel line is the answer to "why is this phone SD only": if it reports a software level,
no app can talk the licence server into HD.
Check yourself#
Check yourself
What are the four stages the media framework separates?
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- docsMedia framework overviewsource.android.comaccessed 2026-10-27↩
- docsMedia mainline modulesource.android.comaccessed 2026-10-27↩
- docsMedia3 overviewdeveloper.android.comaccessed 2026-10-27↩
- docsAPK signature schemesource.android.comaccessed 2026-10-27↩
- docsCameraX overviewdeveloper.android.comaccessed 2026-10-27↩