DASH MP4 cenc 笔记

术语:

  • Initialization Segment 通常指 moov box,不包含 moof box
  • Movie Fragment 一般指 moof box
  • tenc Track Encryption box
  • sgpd sample group description box
  • sbgp Sample To Group Box
  • senc sample encryption box
  • saio auxiliary information offset box
  • saiz auxiliary information size box
  • pssh protection system specific header box

cenc 定义于 ISO BMFF的ISO/IEC 23001-7。其包括:

  • 对于NAL结构的Video和其他媒体使用AES-128 CTR 模式的Common ENCryption(CENC)方案
  • 单个 Representation 的multi-DRM 系统的解密支持
  • Key Rotation(隔断时间更换 media keys)
  • MPD 中对默认 KID 属性和 pssh 元素的XML语法支持

DRM组成:

  1. MPD中的 ContentProtection描述符,其包含了表示使用了通用加密或特殊DRM的URI
  2. tenc box(位于Initialization Segment,通常指的是位于 moov box 的 trak box 中)描述了加密参数和default_KID。位于 sgpd box 的 default_KID 会覆盖 tenc 中的 default_KID,同样,关于 "not encrypted" 的参数也会被覆盖。当样本可用于解密时,样本组描述中KID引用的密钥必须可用,其可能位于 moof box中的 pssh box。default_KID 也可能出现在 MPD中。
  3. senc box 可能存储了 IV(initialization vectors) 和 subsample 的加密范围。对于一个加密track而言,其位于 traf box(track fragment box)中。访问这些存储的参数需要借助于 sziosaiz box。(参考ISO14496-12 #8.7.8)
  4. pssh用于批准对于以"Protection System Specific"形式的DRM获取的数据或者keys。pssh 可能存在于moov 或者 moof box。其也可能以cenc:pssh的形式出现在 MPD 中,这种形式支持 faster parsing,earlier access,identification of duplicate license requests,和不修改内容的前提下的附加DRMs。在moov中的pssh形式并不是推荐的,因为在Web浏览器中为每个Representation和比特率切换 Initialization Segment 时,它们都会触发license requests。
  5. Key rotation 主要用于更改连续实时内容的密钥。其实现需要以下条件:
    • sbgpseig类型的sgpd用于声明应用于每个sample的 KID,和隔断时间对于 KIDs的改变,即 Key rotation。 当Segment中的sample可用于解密时,样本组引用的KID必须具有与这些KID对应的密钥. Segments 种的 sample group 引用的Keys位于 moof种的 pssh box 中。版本 1"pssh"框可用于列出存储的 KID 值,以便在文件分段时删除重复box。
    • 对于不同用户,Movie Fragment 中存储的 pssh采用一致的DRM格式,以使得 Movie Fragment 可以被不同用户共享。用户特定信息必须"带外"(out of band)传递,如与default_KID关联的"root"许可证中,该许可证可以针对每个 DRM 客户端进行个性化设置,并控制对存储在 Media Segments 中的共享"pssh"信息的访问,例如,使用特定于用户的 DRM 根许可证提供的"root key"加密存储在Segment"pssh"box中的密钥。cenc指定"pssh"以启用moov/moof的密钥存储;但它不排除满足 KID 索引和可用性要求的其他密钥交付方法。

ISO BMFF Support for Common Encryption and DRM

cenc 具有以下结构关系:
• moov/pssh (zero or one per system ID)
• moov/trak/mdia/minf/stbl/stsd/sinf/schm (one, if encrypted)
• moov/trak/mdia/minf/stbl/stsd/sinf/schi/tenc (one, if encrypted)
• moof/traf/saiz (one, if encrypted)
• moof/traf/saio (one, if encrypted)
• moof/traf/senc (one, if encrypted)

Key Rotation 具有以下结构关系:
• moof/traf/sbgp (one per sample group)
• moof/traf/sgpd ‘seig’ (sample group entry) (one per sample group)
• moof/pssh (zero or one per system ID)

senc 与 saio/saio 的关系

senc结构如下:

aligned(8) class SampleEncryptionBox extends FullBox(‘senc’, version=0, flags)
{
  unsigned int(32) sample_count;
  {
    unsigned int(Per_Sample_IV_Size*8) InitializationVector;
    if (flags & 0x000002)
    {
    unsigned int(16) subsample_count;
      {
        unsigned int(16) BytesOfClearData;
        unsigned int(32) BytesOfProtectedData;
      } [ subsample_count ]
    }
  }[ sample_count ]
}

sample auxiliary information 的一个可选存储位置是senc box (Sample Encryption Box)。senc 包含 sample auxiliary information,和对于每个 sample 的 IV信息,和 partial sample 加密video的 clear 以及 protected 数据的字节范围(即 “Subsample encryption”)。当track 的sample 或者 track fragment 为加密的时候是有用的。在 traf box(track fragment box) 中存储 senc box,使得在 moof(movie fragment) 中可以访问所有包含 sample 的必要 sample auxiliary information,以使每个 track fragment 可以独立解密。

saiz 的结构如下:

aligned(8) class SampleAuxiliaryInformationSizesBox extends FullBox(‘saiz’, version = 0, flags)
{
  if (flags & 1) {
    unsigned int(32) aux_info_type; // 声明辅助信息类型,对于 cenc加密,此处是 cenc
    unsigned int(32) aux_info_type_parameter; // 与前者关联的参数,由aux_info_type决定
  }
  unsigned int(8) default_sample_info_size; // 辅助信息 默认大小
  unsigned int(32) sample_count;  // 有多少sample 辅助信息
  if (default_sample_info_size == 0) {
    unsigned int(8) sample_info_size[ sample_count ];
  }
}

saio 的结构如下:

aligned(8) class SampleAuxiliaryInformationOffsetsBox extends FullBox(‘saio’, version, flags)
{
  if (flags & 1) {
    unsigned int(32) aux_info_type; // 声明辅助信息类型,对于 cenc加密,此处是 cenc
    unsigned int(32) aux_info_type_parameter; // 与前者关联的参数,由aux_info_type决定
  }
  unsigned int(32) entry_count; // 一般为1
  if ( version == 0 ) {
    unsigned int(32) offset[ entry_count ]; // 若 saio/saiz 在 stbl 中,此值是绝对的; 在 traf 中,该值是相对的(tfhd box 的flag, 如果该 flag == 0x020000(default-base-is-moof)则表示该相对偏移量是相对于 moof box的开始位置)
  }
  else {
    unsigned int(64) offset[ entry_count ];
  }
}

对于 saio/saiz 与 senc 同时存在与 traf的情况,saio 指向的辅助信息始终是 senc 中的第一个 IV, 因为 辅助信息是连续的,所以辅助信息的大小通常为 saiz.default_sample_info_size * saiz.sample_count. 并且有 senc.sample_count == saiz.sample_count;

总结 Common encryption sample auxiliary information

受保护 track 中的每个受保护 sample 都应具有与其关联的IV(Initialization Vector)。 IV 和 SubSample 加密信息都可以由等于 sheme 的 aux_info_type 和 等于0 的aux_info_type_parameter的 sample 辅助信息提供。比如:如果track 使用 cenc scheme 加密,那么 ux_info_type == cenc,aux_info_type_parameter == 0;所以这些可选字段应该忽略。对于 cenc 类型的 sample 辅助信息,其具有一下形式:

aligned(8) class CencSampleAuxiliaryDataFormat
{
  unsigned int(Per_Sample_IV_Size*8) InitializationVector;
  if (sample_info_size > Per_Sample_IV_Size )
  {
    unsigned int(16) subsample_count;
    {
      unsigned int(16) BytesOfClearData;
      unsigned int(32) BytesOfProtectedData;
    } [subsample_count ]
  }
}

这个结构就是senc的子结构
如果 SubSample Encrytion 的方案未被使用(即 sample auxiliary information 的size == Per_Sample_IV_Size),此时整个 sample 都是加密的。这种情况下,所有的auxiliary information 都具有相同的size,因此 saiz 中的 default_sample_info_size == Per_Sample_IV_Size(IV)。
如果 Per_Sample_IV_Size 也为0,(因为使用了 constant IVs),那么sample auxiliary information 应该为 0 且被忽略。
注意:即使使用了 Subsample encryption, sample auxiliary information 的 size 对于所有 sample 而言,仍然可能都相同(如果所有的sample 都含有相同数目的subsample),而且,default_sample_info_size 也可能被使用。

posted @ 2020-04-08 10:42  花园小花匠  阅读(2378)  评论(0编辑  收藏  举报