你真的懂 MP4 格式吗? (2)

Time-to-Sample Box,定义每个 Sample 时长。Time To Sample 的 table entry 布局如下:

stts table entry 布局

Sample count:sample 个数

Sample duration:sample 持续时间

持续时间相同的连续的 Sample 可以放到一个 entry 里面,以达到节省空间的目的。

下图示例中,第 1 个 Sample 时间为 33362 微秒,第 2-11 个 Sample 时间为 33363 微秒:

stts 内容

stss

Sync Sample Box,同步 Sample 表,存放关键帧列表,关键帧是为了支持随机访问。
stss 的 table entry 布局如下:

stss table entry 布局

下图示例中,该视频 track 只有一个关键帧即第 1 帧:

stss 内容

stsc

Sample-To-Chunk Box,Sample-Chunk 映射表。上文提到 MP4 通常把 Sample 封装到 Chunk 中,一个 Chunk 可能会包含一个或者几个 Sample。Sample-To-Chunk Atom 的 table entry 布局如下图所示:

stsc table entry 布局

First chunk:使用该表项的第一个 chunk 序号。

Samples per chunk:使用该表项的 chunk 中包含有几个 sample。

Sample description ID:使用该表项的 chunk 参考的 stsd 表项序号。

下图示例中,可以看到该视频 track 一共有两个 stsc 表项,Chunk 序列 1-108,每个 Chunk 包含一个 sample,Chunk 序列 109 开始,每个 Chunk 包含两个 Sample。

stsc 内容

stsz

Sample Size Box,指定了每个 Sample 的 size。Sample Size Atom 包含两 Sample 总数和一张包含了每个 Sample Size 的表。

Sample Size 表的 entry 布局如下图:

stsz table entry 布局

下图示例中,该视频流一共有 110 个 Sample,第 1 个 Sample 大小为 42072 字节,第 2 个 Sample 大小为 7354 个字节。

stsz 内容

stco

Chunk Offset Box,指定了每个 Chunk 在文件中的位置,这个表是确定每个 Sample 在文件中位置的关键。该表包含了 Chunk 个数和一个包含每个 Chunk 在文件中偏移位置的表。每个表项的内存布局如下:

stco table entry 布局

需要注意,这里 stco 只是指定的每个 Chunk 在文件中的偏移位置,并没有给出每个 Sample 在文件中的偏移。想要获得每个 Sample 的偏移位置,需要结合 Sample Size box 和 Sample-To-Chunk 计算后取得。

下图示例中,该视频流第 1 个 Chunk 在文件中的偏移为 4750,第 1 个 Chunk 在文件中的偏移为 47007。

stco 内容

如何计算 Sample 偏移位置

上文提到通过 stco 并不能直接获取某个 Sample 的偏移位置,下面举例说明如何获取某一个 pts 对应的 Sample 在文件中的位置。大体需要以下步骤:

将 pts 转换到媒体对应的时间坐标系。

根据 stts 计算某个 pts 对应的 Sample 序号。

根据 stsc 计算 Sample 序号存放在哪个 Chunk 中。

根据 stco 获取对应 Chunk 在文件中的偏移位置。

根据 stsz 获取 Sample 在 Chunk 内的偏移位置并加上第 4 步获取的偏移,计算出 Sample 在文件中的偏移。

例如,想要获取 3.64 秒视频 Sample 数据在文件中的位置:

根据 time scale 参数,将 3.64 秒转换为视频时间轴对应的 3640000。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwjfp.html