为什么我不能使手动修改的 MPEG-4 扩展框(块)大小起作用?
Why can't I get a manually modified MPEG-4 extended box (chunk) size to work?
概览
作为编写 MPEG-4 (MP4) 文件解析器的项目的一部分,我需要了解如何在 MP4 文件中处理扩展框(或块)大小。当我尝试手动模拟具有扩展框大小的 MP4 文件时,媒体播放器报告该文件无效。
技术信息
一个 MP4 文件由一系列 objects 组成,称为 'boxes'。所有数据都包含在框中,文件中没有其他数据。
这是第 4.2 节的屏幕截图:Object 结构,它描述了方框 header 及其大小和类型字段:
大多数 MP4 框 header 包含两个字段:32 位压缩框大小和 32 位框类型。紧凑的盒子尺寸支持高达 4 GB 的盒子数据。有时 MP4 盒可能有比这更多的数据(例如,一个大视频文件)。在这种情况下,紧凑盒大小设置为 1,并且紧跟在盒类型之后添加八 (8) 个八位字节。这个 64 位数字被称为 'extended box size',并支持最大 2^64 的框大小。
为了更好地理解扩展框大小,我拿了一个简单的 MP4 文件,想修改 moov/trak/mdia
框以使用扩展框大小,而不是紧凑大小。
这是 MP4 文件在修改之前的样子。三个框 header 以红色突出显示:
我的计划如下:
- 修改
moov/trak/mdia
框
- 在
moov/trak/mdia
中,紧跟框类型 ('mdia') 插入八 (8) 个八位字节。这最终将成为我们扩展的盒子尺寸。
- 将紧凑框大小复制到 newly-inserted 扩展框大小,将大小增加 8 以补偿新插入的八位字节。大小按big-endian顺序插入。
- 将紧凑大小设置为 1。
- 修改
moov/trak
框
- 将 8 添加到现有的紧凑框大小(以补偿添加到
mdia
的八个八位字节)。
- 修改
moov
框
- 将 8 添加到现有的压缩框大小(同样,以补偿
mdia
中的八个八位字节)
这是 MP4 文件现在的样子,修改后的八位字节为红色:
我们做了什么?
我们已经告诉 MP4 parser/player 从扩展字段而不是紧凑大小字段中获取 moov/trak/mdia
框大小,并将所有 parent 框增加八个(8 ) 以补偿 mdia
框中的 newly-inserted 扩展框大小。
有什么问题?
当我尝试播放修改后的 MP4 文件时,我收到来自不同媒体播放器的错误消息:
为什么媒体播放器将修改后的文件视为无效 MP4?
- 我是否需要更改任何其他字段?
- 扩展框大小是否必须大于2^32?
- 是否只有特定的框类型支持扩展框大小(例如,媒体数据)?
感谢@Alan Birtles 指出块偏移量也需要修改。实际上,stco
(示例 table 块偏移量?)框包含 绝对 文件偏移到 mdat
框中的数据块(而不是 relative 框内的偏移量)。这个可以看规范文档:
块偏移量需要增加我们在 mdat
框之前添加到文件中的八位字节数。在我们的例子中,这是插入 mdia
框中的八 (8) 个八位字节扩展框大小。
剩下的就是手动更改在两个 stco
框(视频和音频轨道)中找到的块偏移量,为每个块偏移量添加八 (8) 个。这是 stco
个方块,然后将 8 添加到它们的块偏移量:
现在文件通过了两个ffmpeg and ffprobe 工具的有效性测试。有趣的是,虽然 VLC 成功播放修改后的文件,但其他媒体播放器(例如 Windows Media Player、MS Photos、MS Movies & TV、MS MovieMaker)报告文件已损坏。目前尚不清楚为什么他们无法播放该文件。未经证实的可能性包括:
- 不支持
mdat
以外的任何框的扩展框尺寸
- 如果扩展框大小小于 2^32 则犹豫不决
总而言之,如果将任何字段添加到框(例如,扩展框大小),stco
块偏移量需要增加每个 [=10] 之前插入 MP4 文件中的八位字节数=] 框.
概览
作为编写 MPEG-4 (MP4) 文件解析器的项目的一部分,我需要了解如何在 MP4 文件中处理扩展框(或块)大小。当我尝试手动模拟具有扩展框大小的 MP4 文件时,媒体播放器报告该文件无效。
技术信息
一个 MP4 文件由一系列 objects 组成,称为 'boxes'。所有数据都包含在框中,文件中没有其他数据。
这是第 4.2 节的屏幕截图:Object 结构,它描述了方框 header 及其大小和类型字段:
大多数 MP4 框 header 包含两个字段:32 位压缩框大小和 32 位框类型。紧凑的盒子尺寸支持高达 4 GB 的盒子数据。有时 MP4 盒可能有比这更多的数据(例如,一个大视频文件)。在这种情况下,紧凑盒大小设置为 1,并且紧跟在盒类型之后添加八 (8) 个八位字节。这个 64 位数字被称为 'extended box size',并支持最大 2^64 的框大小。
为了更好地理解扩展框大小,我拿了一个简单的 MP4 文件,想修改 moov/trak/mdia
框以使用扩展框大小,而不是紧凑大小。
这是 MP4 文件在修改之前的样子。三个框 header 以红色突出显示:
我的计划如下:
- 修改
moov/trak/mdia
框- 在
moov/trak/mdia
中,紧跟框类型 ('mdia') 插入八 (8) 个八位字节。这最终将成为我们扩展的盒子尺寸。 - 将紧凑框大小复制到 newly-inserted 扩展框大小,将大小增加 8 以补偿新插入的八位字节。大小按big-endian顺序插入。
- 将紧凑大小设置为 1。
- 在
- 修改
moov/trak
框- 将 8 添加到现有的紧凑框大小(以补偿添加到
mdia
的八个八位字节)。
- 将 8 添加到现有的紧凑框大小(以补偿添加到
- 修改
moov
框- 将 8 添加到现有的压缩框大小(同样,以补偿
mdia
中的八个八位字节)
- 将 8 添加到现有的压缩框大小(同样,以补偿
这是 MP4 文件现在的样子,修改后的八位字节为红色:
我们做了什么?
我们已经告诉 MP4 parser/player 从扩展字段而不是紧凑大小字段中获取 moov/trak/mdia
框大小,并将所有 parent 框增加八个(8 ) 以补偿 mdia
框中的 newly-inserted 扩展框大小。
有什么问题?
当我尝试播放修改后的 MP4 文件时,我收到来自不同媒体播放器的错误消息:
为什么媒体播放器将修改后的文件视为无效 MP4?
- 我是否需要更改任何其他字段?
- 扩展框大小是否必须大于2^32?
- 是否只有特定的框类型支持扩展框大小(例如,媒体数据)?
感谢@Alan Birtles 指出块偏移量也需要修改。实际上,stco
(示例 table 块偏移量?)框包含 绝对 文件偏移到 mdat
框中的数据块(而不是 relative 框内的偏移量)。这个可以看规范文档:
块偏移量需要增加我们在 mdat
框之前添加到文件中的八位字节数。在我们的例子中,这是插入 mdia
框中的八 (8) 个八位字节扩展框大小。
剩下的就是手动更改在两个 stco
框(视频和音频轨道)中找到的块偏移量,为每个块偏移量添加八 (8) 个。这是 stco
个方块,然后将 8 添加到它们的块偏移量:
现在文件通过了两个ffmpeg and ffprobe 工具的有效性测试。有趣的是,虽然 VLC 成功播放修改后的文件,但其他媒体播放器(例如 Windows Media Player、MS Photos、MS Movies & TV、MS MovieMaker)报告文件已损坏。目前尚不清楚为什么他们无法播放该文件。未经证实的可能性包括:
- 不支持
mdat
以外的任何框的扩展框尺寸
- 如果扩展框大小小于 2^32 则犹豫不决
总而言之,如果将任何字段添加到框(例如,扩展框大小),stco
块偏移量需要增加每个 [=10] 之前插入 MP4 文件中的八位字节数=] 框.