我创建了一个 java 程序来解析 mp4 和 ts 段。我将带有 ffmpeg 的 ts 片段混合到 mp4 中。我试图理解为什么 ffmpeg 以这种方式形成 mdat。
以下是从 TS-PES 中提取的原始 4 NALU 十六进制,按起始码排序(图 1):
00 00 00 01 |09 e0
00 00 00 01 |67 42 c0 0d 96 56 1e 33 7f e0 08 00 05 be a0 a0 a0 be 00 00 07 d0 00 00 ea 61 28
00 00 00 01 |68 da 8f 20
00 00 00 01 |65 88 80 40 20 7f 3e 21 11 c2 18 78 b0 00 40 81 0e 04 1a 24 05 48 09 84 67 36 61 14 33 8f eb 05 d6 a5 e4 1e 34 d1 f8 65 08 8c 00 f0 00 ...
根据我的解析器(图 2),这些看起来像合法的NALU:
fzb:false nri:0x0 nut:9 [[DATA]] : 09 E0
fzb:false nri:0x3 nut:7 seq_parameter_set_rbsp [[DATA]] : 67 42 C0 0D 96 56 1E 33 7F E0 08 00 05 BE A0 A0 A0 BE 00 00 07 D0 00 00 EA 61 28
fzb:false nri:0x3 nut:8 pic_parameter_set_rbsp [[DATA]] : 68 DA 8F 20
fzb:false nri:0x3 nut:5 slice_layer_without_partitioning_rbsp() fmis:0 st:7(I_2) ppsi:0x0 [[DATA]] : 65 88 80 40 20 7F 3E 21 11 C2 18 78 B0 00 40 81 0E 04 1A 24 05 48 09 84 67 36 61 14 33 8F EB 05 D6 A5 E4 1E 34 D1 F8 65 08 8C 00 F0 00
然后,由 SampleTableBox 分块的我的复用 mp4 mdat 包含这个十六进制数据,按看起来像畸形NALU 的排序(图 3):
00 00 00 02 |09 e0
00 00 00 1b |67 42 c0 0d 96 56 1e 33 7f e0 08 00 05 be a0 a0 a0 be 00 00 07 d0 00 00 ea 61 28
00 00 00 04 |68 da 8f 20
00 00 1e ac |65 88 80 40 20 7f 3e 21 11 c2 18 78 b0 00 40 81 0e 04 1a 24 05 48 09 84 67 36 61 14 33 8f eb 05 d6 a5 e4 1e 34 d1 f8 65 08 8c 00 f0 00
请注意 ITU-T H264 7.4.1 中上述数据的简写参考:
fbz = forbidden_zero_bit
nri = nal_ref_idc
nut = nal_unit_type
fmis = first_mb_in_slice
st = slice_type
ppsi = pic_parameter_set_id
另请注意,有效载荷是相同的。
我认为 mp4 是正确的,因为它在任何播放器中都能正常工作。但我不确定 mdat muxing 对 NALU 起始代码做了什么。我对此有点陌生,很难弄清楚为什么会这样。
它们看起来不像 NALU,因为起始代码不以 01 结尾。
有人建议它们是 AvcC (ISO/IEC 14996-15 5.2.4.1.1),但每个数据集中的第一个字节以 00 开头,如 NALU,并且不会通过 configurationVersion 测试(第一个字节 01)。
我想知道在这种情况下如何指定 mdat。如果有人能指出我正确的方向或无可辩驳的著作,那将不胜感激。谢谢!