![](/img/trans.png)
[英]h264 inside AVI, MP4 and “Raw” h264 streams. Different format of NAL units (or ffmpeg bug)
[英]Decode a single (H264) packet dumped by ffmpeg from a mp4 file
我使用 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 个字节是数据包本身的大小,我尝试在将缓冲区传递给数据包之前跳过这些字节,但也失败了。
我是跳过了某个步骤还是做错了什么? 我正在尝试做的甚至可能吗? (请说是:)
建议H.264是国际电信联盟,T elecommunications标准化部门(ITU-T)定义的视频编解码标准。 它是免费提供的,可以从他们的网站上下载。
该标准定义了一种字节流格式,其最低抽象级别是 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 位或字节。
MPEG-4 是由国际标准组织 (ISO) 和国际电工委员会 (IEC) 的一个联合小组制定的音频-视频编码和存储标准的多个“部分”系列,称为运动图像专家组 (MPEG)。 只有 MPEG-4 系列的几个部分是相关的:
.mp4
文件扩展名和格式。 这部分非常昂贵( 88 瑞士法郎)并且不向公众开放。.mp4
容器的基础。不幸的是,第 15 部分也是定义 NALU 框架的新方案的部分。 该方案提出将所有 SPS/PPS NALU 提取到一个称为AVCC 的“带外”结构中,并且还将 NALU 前面的起始代码前缀剥离并替换为一个(几乎总是)表示大小的 4 字节数字,以字节为单位,以下 NALU。
该方案流行于快速随机搜索视频数据,通过将所有视频解码器配置数据(SPS/PPS)收集在一个标准化的地方,一开始就可以配置视频解码器,然后不用担心意外的惊喜就像视频帧大小的动态变化(附件 B 允许)。
幸运的是,网上有关于 AVCC 结构的提示,在 AVCC 和 Annex B 之间转换的代码也是如此。
您似乎需要 AVCC -> Annex B 转换。 这可以通过 FFmpeg 的比特流过滤器h264_mp4toannexb
来完成:
ffmpeg -i INPUT.mp4 -codec copy -bsf:v h264_mp4toannexb OUTPUT.ts
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.