Widevine DRM implements resolution constraints through hardware security tiers. The system categorizes devices into L1, L2, and L3 based on their hardware protection mechanisms for cryptographic operations and video processing.

Content providers set resolution ceilings in DRM licenses according to device security levels. Widevine verifies these constraints during playback through cryptographic checks. The tiered model allows content distribution across devices while preventing unauthorized quality upgrades. Hardware capabilities dictate the maximum supported resolution for each security level.

Widevine Security Levels and Resolution Control

Widevine DRM applies content protection using discrete security levels (L1, L2, and L3). Each of them defines cryptographic isolation, media pipeline integrity, and maximum permissible resolution.

Level 1 (L1)

Execution: All decryption and processing occur inside the device's Trusted Execution Environment (TEE).

Resolution Support: Up to 4K UHD (3840x2160).

Requirements: Full hardware-based protection for both keys and the media decoding pipeline.

Usage: Mandatory for playback of high-value content (e.g., 4K movies on licensed OTT platforms).

Level 2 (L2)

Execution: Decryption happens in TEE, but video decoding is handled in software outside the secure environment.

Resolution Support: Capped at 720p or 1080p, depending on the license policy.

Usage: Some mid-range or older SoCs that lack full secure video pipelines.

Level 3 (L3)

Execution: The entire process (including key management and decoding) occurs in software without any hardware-based isolation.

Resolution Support: Limited to SD (480p or lower).

Usage: Emulators, uncertified devices, or devices without Widevine L1/L2 certification.

Banner for Secure Video Upload

License Configuration and Resolution Limits

The license server response can limit resolution via the allowed_track_types or key control parameters.

Example License Policy Snippet (JSON-like format):

code
{
code
"keys": [
code
{
code
"key_id": "abc123...",
code
"track_type": "SD",
code
"security_level": "L3"
code
},
code
{
code
"key_id": "xyz789...",
code
"track_type": "HD",
code
"security_level": "L1"
code
}
code
]
code
}

Explanation:

  • key_id: 32-byte KID (hex/Base64URL) derived from PSSH must match encrypted media segment ID.
  • track_type: Resolution constraint tag ("SD," "HD," "UHD1," or "UHD2") overrides player capability negotiation.
  • security_level: L1 (TEE-backed, HDCP-bound) or L3 (software-only, fallback).

Resolution Filtering in DASH Manifests

DASH manifests include multiple representations (bitrates/resolutions). Players like ExoPlayer filter out unsupported representations based on device security level and license rules.

Example DASH Adaptation Set:

code
<Representation id="hd" width="1920" height="1080" bandwidth="4000000" codecs="avc1.640028" />
code
<Representation id="sd" width="854" height="480" bandwidth="1000000" codecs="avc1.4d401f" />

Explanation:

  • On L3 devices, only the SD representation would be selected.
  • On L1 devices, HD or 4K representations are allowed if permitted by the license.

Device-Level Validation

Developers can query the security level of a device using Android's MediaDrm API:

code
val mediaDrm = MediaDrm(WIDEVINE_UUID)
code
val securityLevel = mediaDrm.getPropertyString("securityLevel")
code
Log.d("WidevineLevel", "Security Level: $securityLevel")

Explanation:

  • MediaDrm(WIDEVINE_UUID) initializes DRM context
  • getPropertyString("securityLevel") queries device TEE