传送门:MP4 文档 P15页
Mdat Box 这个 Box 是存储音视频数据的 Box,要从这个 Box 解封装出真实的媒体数据。这里只讨论 H264 的编码数据,所以这个 Box 也存的是 H264 的数据信息,具体 H264 的详细介绍参考:https://www.zzsin.com/catalog/write_avc_decoder.html
H264的基本结构是由一系列的NALU组成。原始的NALU单元组成:
Start code + NALU header + NALU Data
但是在这个 Mp4 文件下的 H246 的储存并不是以 Start 开头,所以不是以 00 00 01 / 00 00 00 01 进行切分。在这个 Box data 数据区里面 H264 具体以:NALU length + NALU header + Nalu Data ....,前面加了一个长度字段,类似 Box 格式。根据我们上面 Box 的解析,我们可以在 Avcc Box 里面提取到 SPS 和 PPS 的信息,所以这里面一般不再包含SPS PPS等数据。这里一般 NALU 类型就是 I \ B \ P 帧数据以及 SEI 用户增强信息。
Mdat Box 基本组成还是有头部和数据两部分组成,这里要注意,因为这个 Box 主要就是存放音视频的数据信息,所以通常 Box 会比较大,当4个字节不够描述当前 Box 的大小时,则会设置头部字节大小为1,用后面8字节的扩展长度字段,Box Type 还是“mdat”的 ASCII 码值。
名称 | 大小(byte) | 意义 | 说明 |
---|---|---|---|
Box length | 4 | Box 整体的大小 | 包含 Header 和 Data部分 |
Box type | 4 | ”mdat”的ASCII码,表明是 mdatbox | box 属性值,通常是固定值 |
Box Data | H264 | 音视频流编码数据 |
Box Data 下的字段,这里我们知道第一个 Chunk 是从0x80开始,已 H264 为例:
第一个 NALU
名称 | 大小(byte) | 具体值(十六进制) | 说明 |
---|---|---|---|
Nalu Length | 4 | 00 00 00 02 | 当前NALU Data整体的大小 |
Nalu Header | 1 | 09 | 0x09&0x1f=9 NALU_TYPE_AUD |
Nalu Data | 10 |
第二个 NALU
名称 | 大小(byte) | 具体值(十六进制) | 说明 |
---|---|---|---|
Nalu Length | 4 | 00 05 81 C0 | 当前NALU Data整体的大小 |
Nalu Header | 1 | 65 | 0x65&0x1f=5 NALU_TYPE_IDR I帧数据 |
Nalu Data | ... |
...
这里大概就把 MP4 包含主要和常见的 Box 进行分析了一遍和代码实现了一遍进行对 MP4 Box 解析操作,也让我们对音视频容器概念有一个比较深的认识,所以根据这些 Box 我们可以知道例如:容器解封装是为了提取什么,音视频 seek 操作的原理,把 H264 裸流进行打包成 MP4 文件 等等。
当然 Box 的总数量要达到70多个,其它都不是必须 Box,也可以参考官方文档的定义,自己也可以尝试对其他 Box 进行分析。MP4 的解封装代码比较长,看了几个开源项目都有上万行的代码量,不过只要严格按照 ISO 规范进行书写,问题不会太大。