buk*_*jot 6 c video specifications ffmpeg h.264
TL; DR:我想从AVI/MP4文件读取原始的h264流,甚至是破坏/不完整的.
几乎所有关于h264的文档都告诉我它包含NAL数据包.好的.几乎每个地方都告诉我,数据包应该以像00 00 01或者签名开头00 00 00 01.例如,https://stackoverflow.com/a/18638298/8167678,/sf/answers/1233787621/
H.264的格式是它由NAL单元组成,每个NAL单元的起始前缀为三个字节,值为0x00,0x00,0x01,每个单元的类型不同,具体取决于这些后面的第4个字节的值. 3个起始字节.一个NAL单元不是视频中的一个帧,每个帧由许多NAL单元组成.
好的.
我下载了random_youtube_video.mp4并从中删除了一帧:
ffmpeg -ss 10 -i random_youtube_video.mp4 -frames 1 -c copy pic.avi
得到了:
红色部分 - 这是AVI容器的一部分,其他 - 实际数据.正如你所看到的,我在这里00 00 24 A9而不是00 00 00 01
这个AVI文件播放完美
如您所见,这里完全相同的字节. 这个MP4文件播放完美
我试图删除原始数据:
ffmpeg -i pic.avi -c copy pic.h264

此文件无法在VLC中播放,甚至生成此文件的ffmpeg也无法解析它:

MP4Box 告诉我:
Cannot find H264 start code
Error importing pic.h264: BitStream Not Compliant
Run Code Online (Sandbox Code Playgroud)
当没有任何作用时,很难学习h264的内部结构.
所以,我有疑问:
更新:
这似乎是ffmpeg中的bug:
当我进行双重转换时:
ffmpeg -ss 10 -i random_youtube_video.mp4 -frames 1 -c copy pic.mp4
ffmpeg pic.mp4 -c copy pic.h264
Run Code Online (Sandbox Code Playgroud)
但是当我直接转换文件时:
ffmpeg -ss 10 -i random_youtube_video.mp4 -frames 1 -c copy pic.h264

我有NAL签名和一个额外的NAL单位.其他字节相同(选中).
这是错误吗?
UPDATE
不是,这不是bug,U必须使用选项-bsf h264_mp4toannexb将流保存为"附件B"格式(带前缀)
"我想从AVI文件中读取原始的h264流,甚至是破坏/不完整的."
"几乎每个地方都告诉我,数据包应该以签名开头:
00 00 01或者00 00 00 01""......正如你所看到的,我在这里
00 00 24 A9而不是00 00 00 01"
您的H264采用AVCC格式,这意味着它使用数据大小(而不是数据起始码).只有附件B才会将您提到的签名作为起始代码.
你寻找帧,而不是通过寻找起始码,而是你只是跳过帧大小来达到(请求的)帧的最终正确偏移...
AVI处理:
读取大小(四个)字节(32位整数,Little Endian).
提取下一个字节,直到大小金额.
这是您的H.264帧(采用AVCC格式),解码字节以查看图像.
转换成附件-B,尝试更换的H.264第一个4个字节帧的字节用00 00 00 01.
考虑一下你显示的AVI字节(见第一张图片):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 4C 49 53 54 BA 24 00 00 6D 6F 76 69 ....LISTº$..movi
30 30 64 63 AD 24 00 00 00 00 24 A9 65 88 84 27 00dc.$....$©eˆ„'
C7 11 FE B3 C7 83 08 00 08 2A 7B 6E 59 B5 71 E1 Ç.þ³Çƒ...*{nYµqá
E3 9C 0E 73 E7 10 50 00 18 E9 25 F7 AA 7D 9C 30 ãœ.sç.P..é%÷ª}œ0
E6 2F 0F 20 00 3A 64 AA CA 5E 4F CA FF AE 20 04 æ/. .:dªÊ^OÊÿ® .
07 81 40 00 48 00 0A 28 71 21 84 48 06 18 90 0C ..@.H..(q!„H....
31 14 57 9E 7A CD 63 A0 E0 9B 96 69 C5 18 AE F2 1.WžzÍc à›–iÅ.®ò
E6 07 02 29 01 20 10 70 A1 0F 8C BC 73 F0 78 FA æ..). .p¡.Œ¼sðxú
9E 1D E1 C2 BF 8C 62 CE CE AC 14 5A A4 E1 45 44 ž.ῌbÎά.Z¤áED
38 38 85 DB 12 57 3E F6 E0 FB AE 03 04 21 62 8D 88…Û.W>öàû®..!b.
F6 F1 1E 37 1C A2 FF 75 1C F1 02 66 0C 92 07 06 öñ.7.¢ÿu.ñ.f.’..
15 7C 90 15 6F 7D FC BD 13 1E 2B 0C 14 3C 0C 00 .|..o}ü½..+..<..
B0 EA 6F 53 B4 98 D7 80 7A 68 3E 34 69 20 D2 FA °êoS´˜×€zh>4i Òú
F0 91 FC 75 C6 00 01 18 C0 00 3B 9A C5 E2 7D BF ð‘üuÆ...À.;šÅâ}¿
Run Code Online (Sandbox Code Playgroud)
一些解释:
忽略前导多个00字节.
4C 49 53 54 D6 3C 00 00 6D 6F 76 69包括30 30 64 63= AVI"List"标题.
AD 24 00 00== decimal 9389是AVI自己的H264项目大小(在Little Endian中读取).
请注意,AVI字节包括...
-记项目的总规模(AD 24 00 00...或反向小端:00 00 24 AD)
-其次是项目数据(00 00 24 A9 65 88 84 27 ... etc ... C5 E2 7D BF).
这个大小既是AVI本身的四个字节大小,也是项目自身字节的长度.或者干脆:
00 00 24 A9
AVI中的H.264视频帧字节:
接下来是项目数据,即H.264 视频帧.通过格式凑巧/字节布局,它也适用于4个字节的条目数据的大小(因为你H264是AVCC格式,如果它是附件-B,那么你会看到,而不是启动代码的字节大小字节这里).与AVI不同,此大小以Little Endian格式编写.
00 00 00 01=此视频帧的字节大小(而不是起始码:) 65 88 84 27 C7 11 FE B3 C7.
X= H.264 关键帧(始终从X5开始,其中X5值基于其他设置).
请记住四个大小的字节(甚至是起始代码),如果后跟...
65= keyframe(IDR),示例字节X1.41= P或B帧,示例字节X6.X7= SEI(补充增强信息).X8= SPS(序列参数集).00 00 00 X9= PPS(图片参数集).00 00 01=访问单元分隔符.如果在AVI文件中搜索完全相同的字节,则可以找到H.264.请参见第三张图片,这些是您的H.264字节(它们被剪切并粘贴到AVI容器中).
有时框架被切成不同的NAL单元.因此,如果您提取关键帧并且它仅显示1/2或1/3而不是完整图像,则只需抓住下一个或两个NAL并重新尝试解码.
| 归档时间: |
|
| 查看次数: |
4718 次 |
| 最近记录: |