A protected track keeps its codec description under a different sample entry type and says
how it is protected in a sinf box. The boxes here describe the scheme; the
samples themselves stay encrypted, and nothing in the file gives the key. These layouts
(ISO/IEC 14496-12 for the structure and ISO/IEC 23001-7, Common Encryption, for
tenc, pssh, senc and the seig sample
group) come from memory; neither standard could be read, and no file made by FFmpeg on the
test machine was encrypted, so none of these layouts has been checked against a real file.
The viewer reads them, labels every field, and has only been run on hand-checked
layouts.
Protected sample entries
The entry type becomes encv (video), enca (audio),
enct (text), encm (metadata), encs (systems),
encf (font), encu (subtitles), encp (haptics) or
enc3 (volumetric). The rest of the entry is that of the original type, and
it gains a sinf child. Restricted schemes (stereo or omnidirectional video) use
resv and resa with an rinf box built the same way.
sinf, frma, schm, schi
| Box | Fields |
|---|---|
sinf | Container: frma, schm and schi. |
frma | data_format (4): the entry type the track had before protection (avc1, mp4a …). |
schm | Full box; flag 1: scheme_uri present. scheme_type (4), scheme_version (4), scheme_uri (zero-ended, when flagged). Common Encryption schemes: cenc AES-CTR, cens AES-CTR with sub-sample pattern, cbc1 AES-CBC, cbcs AES-CBC with sub-sample pattern; the version is 0x00010000. Others in the registry: cva1, cva2, cvar (sample variants), sve1, odkm (OMA DRM), cpcm (DVB CPCM), aSEI, stvi, erpv and the other OMAF schemes. |
schi | Container for what the scheme needs: for Common Encryption, tenc. |
tenc: track encryption
| Size | Name | Meaning |
|---|---|---|
| 1 | reserved | Zero. |
| 1 | reserved (version 0), or default_crypt_byte_block (4 bits) and default_skip_byte_block (4 bits) from version 1 | The pattern of cens and cbcs: blocks of 16 bytes encrypted, then blocks left clear. |
| 1 | default_isProtected | 1 when the samples are encrypted. |
| 1 | default_Per_Sample_IV_Size | 0, 8 or 16 bytes. 0 with isProtected 1 means one constant IV. |
| 16 | default_KID | The key identifier. |
| 1 + n | default_constant_IV_size, default_constant_IV | Only when isProtected is 1 and the per-sample IV size is 0. |
pssh: protection system specific header
In moov or moof. A full box: SystemID (16 bytes), for version 1
KID_count (4) and that many 16-byte key IDs, DataSize (4) and the data, which only the DRM
system understands. System IDs the viewer names: Widevine
edef8ba9-79d6-4ace-a3c8-27dcd51d21ed, PlayReady
9a04f079-9840-4286-ab92-e65be0885f95, FairPlay Streaming
94ce86fb-07ff-4f43-adb8-93d2fa968ca2, the W3C common system
1077efec-c0b2-4d02-ace3-3c1e52e2fb4b, Marlin
5e629af5-38da-4063-8977-97ffbd9902d4, Adobe Primetime
f239e769-efa3-4850-9c16-a903c6932efb. The data of each is not decoded.
senc, saiz, saio and seig
| Box | Fields |
|---|---|
senc | Full box; flags: 1 overrides the track defaults, 2 sub-sample encryption. sample_count (4); each sample: InitializationVector (the IV size from tenc), and with flag 2 subsample_count (2) and, for each, BytesOfClearData (2) and BytesOfProtectedData (4). In a traf or in stbl. |
saiz | Full box; flag 1: aux_info_type (4) and aux_info_type_parameter (4). default_sample_info_size (1), sample_count (4), and a size byte for each sample when the default is 0. |
saio | Full box; flag 1: aux_info_type and its parameter as in saiz. entry_count (4), then offsets (4, or 8 in version 1). |
sgpd seig | The sample group of encryption parameters: for each entry, reserved (1), crypt_byte_block and skip_byte_block (4 bits each), isProtected (1), Per_Sample_IV_Size (1), KID (16), and constant_IV_size (1) with the constant IV when isProtected is 1 and the IV size is 0. |
What a viewer cannot read
Encrypted samples cannot be played or decoded without the key, which is never in the
file. The sizes, positions and sub-sample ranges are all visible, and the viewer shows
them. The data inside pssh is private to the DRM system.