我用ffmpeg从mp4内的h264视频中转储代表单个帧的数据包
ffmpeg -i video.mp4 -c copy -vframes 1 -map 0:v:0 -f data frame.bin
frame.bin
中的数据似乎很好,并且似乎由与mdat
中的第一个块/数据包(我不确定正确的术语)完全相同的字节组成原子。
现在我要解码该帧。由于我知道用于创建该数据包的编解码器(h264),因此我认为我可以简单地准备一个编解码器上下文,将所有数据加载到一个数据包中,并使用传统的avcodec_send_packet(codecContext, packet)
和avcodec_receive_frame()
组合。
很遗憾,对avcodec_send_packet
的呼叫失败,并且我收到以下错误消息
(-1094995529) Invalid data found when processing input
由于数据包数据的前4个字节是数据包本身的大小,因此我尝试在将缓冲区传递给数据包之前跳过这些字节,但这也失败了。
我跳过某些步骤还是做错了什么?我尝试做的事情甚至可能吗? (请说是:)
答案 0 :(得分:1)
推荐H.264是由国际电信联盟 T 电信标准化部门(ITU- T )定义的视频编解码器标准。 免费和can be downloaded from their website可用。
该标准定义了一种字节流格式,其最低抽象级别为NALU(网络层抽象单元)。
可以存在32种类型的NALU,尽管大约11种是保留或未使用的。有些带有视频切片数据,有些则没有。 在本讨论的后面部分,两种NALU类型将很重要:SPS(序列参数集)和PPS(图片参数集)。两者都需要对视频片段进行解码,并提供有关流的重要信息,例如流的大小和原始数据的解释。
H.264没有定义如何传输和构建这些NALU。但是,它的确在标准自己的附件B中描述了一种可能的方案。由于缺乏更好的名称,该方案通常称为附件B 。
该方案包括在NALU的前面加上易于同步的起始代码,这些代码在NALU中不能出现:3字节或4字节模式00 00 01
或00 00 00 01
。然后是NALU的其余部分。此方案在硬件和/或流媒体情况中很流行,因为它可以轻松获取位锁定和字节对齐,定期“带内”发送SPS / PPS,从而允许在任意点调谐到流中以开始解码,并且具有有趣的性质,即可以在NALU之间有效地发送任意数量的0位或字节。
.mp4
文件扩展名和格式。这部分非常昂贵( 88瑞士法郎),并且不向公众提供。
MPEG-4第15部分,定义了如何将NALU结构的视频数据(例如第10 / H.264视频)存储在第12部分ISO BMFF中。这部分价格非常昂贵( 198瑞士法郎),并且不向公众提供,但是第14、12和10部分是常用{ {1}}容器,其中包含H.264编码的视频。
不幸的是,第15部分还是定义了NALU的新框架的部分。该方案建议将所有SPS / PPS NALU提取到称为“ AVCC ”的“带外”结构中,并用(几乎总是)剥离并替换NALU前面的起始代码前缀。 4个字节的数字,表示以下NALU的大小(以字节为单位)。
此方案在通过视频数据进行快速和随机查找时很流行,并且通过将所有视频解码器配置数据(SPS / PPS)收集在一个标准化的位置,可以在开始时配置一次视频解码器,此后便不必担心有关视频帧大小的动态变化(附件B允许的变化)的意外惊喜。
幸运的是,关于AVCC结构的提示在线存在,并且在AVCC和附件B之间进行翻译的代码也是如此。
您似乎需要AVCC->附件B转换。可以使用FFmpeg的位流过滤器h264_mp4toannexb
:
.mp4