我正在做一个为网络视频生成缩略图的实验。我打算通过模拟解码器的工作原理,从二进制流中提取出I帧,并将原始视频的PPS和SPS信息相加,形成H264原始信息,然后交给ffmpeg生成图像。我几乎解决了很多问题,甚至写了一个demo来实现我的功能,但是我找不到任何关于多个NALU组成一帧时哪里有标识符的信息(严格来说是有一点,但是可以'解决不了我的问题,我稍后再谈)。
您可以使用以下命令来生成我提到的视频类型:
ffmpeg -i input.mp4 -c:v libx264 -x264-params slices=8 output.mp4
这将生成每帧 8 个切片的视频。由于我稍后会使用这个文件,因此我还将使用以下命令生成 H264 原始信息文件:
ffmpeg -i output.mp4 -vcodec copy -an output.h264
当我放入分析程序中时,可以看到多个IDR NALU连接在一起,其中非第一个IDR NALU的Slice Header中的first_mb_in_slice不为0:
但是当我回到MP4中的mdat并查看NALU时,所有first_mb_in_slice都变成0:
0x9a= 1001 1010,根据指数哥伦布编码,first_mb_in_slice == 0( ueg(1B) == 0 ), slice_type == P帧(ueg(00110B) == 5),但在H264中使用相同的算法raw 文件,结果与程序给出的结果相同。
是否有其他地方有此信息的标识符?假设我随机得到一个NALU,我能知道这个视频是否被切片,或者我的操作错误吗?
PS:只放入一个NALU到解码器中是可行的,但只能解析1/8的图像
如果需要参考,我写的演示程序地址是:https://github.com/gaowanliang/web-video-thumbnailer
好问题!
H.264 有两种格式。我们称它们为 mp4 和附件 B。
在附件 B 中,您的视频帧是访问单元 (AU)。
在磁盘或线路上,它看起来像这样:
|Access Unit Delimiter| |PPS| |SPS| |Slice (1)| |Slice (2)| ... |Slice (n)| |Access Unit Delimiter|
您必须解析切片标头以确定 I、P 或 B 帧。 您必须对切片进行计数,直到到达下一个访问单元分隔符或流末尾。
在附件 B 中,各种 NAL 单元(访问单元定界符、PPS 和切片)由定界符“0x00 0x00 0x00 0x01”分隔
在 MP4 中,NAL 单位是带有其大小的前缀。 因此读取大小,读取NAL单元的类型(例如切片),解析切片头以确定I,P或B,转到下一个NAL单元。 在 MP4 中,容器会告诉您访问单元有多大 - 因此您不必寻找访问单元分隔符。
在这两种情况下(附件 B 或 MP4),您都可以简单地计算一个访问单元中的切片数量。