在仔细阅读FFmpeg Bitstream Filters Documentation之后,我仍然不明白它们的真正用途。
该文件指出过滤器:
执行比特流级别修改而不执行解码
谁能进一步向我解释一下?一个用例将极大地澄清事情。此外,还有明显不同的过滤器。它们有何不同?
在仔细阅读FFmpeg Bitstream Filters Documentation之后,我仍然不明白它们的真正用途。
该文件指出过滤器:
执行比特流级别修改而不执行解码
谁能进一步向我解释一下?一个用例将极大地澄清事情。此外,还有明显不同的过滤器。它们有何不同?
让我举例说明。FFmpeg 视频解码器通常通过每次调用将一个视频帧转换为 avcodec_decode_video2 来工作。因此,输入预计是“一个图像”的比特流数据。让我们考虑一下从文件(磁盘字节数组)到图像的问题。
对于“原始”(附件b)H264(.h264/.bin/.264 文件),单个最终单元数据(sps/pps 标头比特流或 cabac 编码的帧数据)以最终单元序列连接,并以开头代码 (00 00 01 XX) 介于两者之间,其中 XX 是最终单元类型。(为了防止最终数据本身有 00 00 01 数据,它被 RBSP 转义。)所以一个h264 帧解析器可以简单地在开始代码标记处剪切文件。他们搜索从 00 00 01 开始(包括 00 00 01)的连续数据包,直到并排除下一个 00 00 01 出现。然后他们解析 nal 单元类型和 slice header 以找到每个数据包属于哪个帧,并返回一组 nal组成一帧的单元作为h264 解码器的输入。
但是,.mp4 文件中的 H264 数据是不同的。您可以想象,如果多路复用格式中已经有长度标记,那么 00 00 01 开始代码可以被认为是多余的,就像 mp4 的情况一样。因此,为了每帧节省 3 个字节,他们删除了 00 00 01 前缀。他们还将 PPS/SPS 放在文件头中,而不是在第一帧之前添加它,而且这些也错过了它们的 00 00 01 前缀。所以,如果我将这个输入到 h264 解码器中,它需要所有 nal 单元的前缀,它就行不通了。h264_mp4toannexb _比特流过滤器通过识别文件头的提取部分中的 pps/sps 来解决这个问题(ffmpeg 称之为“额外数据”),在每个帧数据包中添加起始码,并在输入之前将它们连接在一起在 h264 解码器中。
您现在可能会觉得“解析器”和“比特流过滤器”之间存在非常细微的区别。这是真实的。我认为官方的定义是解析器获取一系列输入数据并将其拆分为帧而不丢弃任何数据或添加任何数据。解析器唯一要做的就是改变数据包边界。另一方面,允许比特流过滤器实际修改数据。我不确定这个定义是否完全正确(参见下面的 vp9),但这是 mp4toannexb 是 BSF 而不是解析器的概念原因(因为它添加了 00 00 01 前缀)。
这种“比特流调整”有助于保持解码器简单和统一的其他情况,但允许我们支持碰巧存在于野外的所有文件变体: