什么是ffmpeg中的比特流过滤器?

Joe*_*Joe 16 ffmpeg filter bitstream

仔细阅读FFmpeg比特流过滤器文档后,我仍然不明白它们的真正含义.

该文件指出过滤器:

执行比特流级别修改而不执行解码

谁能进一步向我解释一下?用例会大大澄清事情.此外,有明显不同的过滤器.他们有什么不同?

Ron*_*tje 34

让我举例说明.FFmpeg视频解码器通常通过将每个呼叫的一个视频帧转换为avcodec_decode_video2来工作.因此,输入预计是比特流数据的"一个图像".让我们考虑一下从文件(磁盘的字节数组)到图像的问题.

对于"原始"(附件)H264(.h264/.bin/.264文件),单个nal单元数据(sps/pps头比特流或cabac编码的帧数据)以nal单元的顺序连接,一开始中间的代码(00 00 01 XX),其中XX是最终单位类型.(为了防止最终数据本身具有00 00 01数据,它是RBSP转义的.)因此,h264帧解析器可以简单地在起始码标记处剪切文件.他们搜索以00 00 01开始并包括00 00 01的连续数据包,直到并排除下一次出现00 00 01.然后他们解析nal单元类型和切片标头以找到每个数据包所属的帧,并返回一组nal组成一帧的单元作为h264解码器的输入.

但是.mp4文件中的H264数据是不同的.您可以想象,如果多路复用格式中已有长度标记,则00 00 01起始码可视为冗余,如mp4的情况.因此,为了每帧节省3个字节,它们会删除00 00 01前缀.他们还将PPS/SPS放在文件头中,而不是在第一帧之前添加它们,这些也会错过它们的00 00 01前缀.所以,如果我将它输入h264解码器,它需要所有nal单元的前缀,它将无法工作.该h264_mp4toannexb比特流过滤器修复了这个问题,通过识别文件头的提取部分中的pps/sps(ffmpeg称之为"extradata"),使用起始代码将各个帧数据包中的每个nal前置,并在输入之前将它们连接在一起.在h264解码器中.

您现在可能会觉得"解析器"和"比特流过滤器"之间存在非常细微的区别.这是真的.我认为官方定义是解析器接受一系列输入数据并将其拆分为帧而不丢弃任何数据或添加任何数据.解析器唯一能做的就是改变数据包边界.另一方面,允许比特流过滤器实际修改数据.我不确定这个定义是完全正确的(参见下面的vp9),但这是概念上的原因mp4toannexb是BSF,而不是解析器(因为它添加了00 00 01前缀).

其他情况下,这种"比特流调整"有助于保持解码器简单和统一,但允许我们支持在野外发生的所有文件变体:

  • mpeg4(divx)b帧解包(为了获得像IBP这样的B帧序列,它们被编码为IPB,在AVI中并且时间戳正确,人们想出了这种B帧封装的概念,其中IBP/IPB被打包在帧中I-(PB) - (),即第三个包是空的,第二个包有两个帧.这意味着在解码阶段与P帧和B帧相关联的时间戳是正确的.这也意味着你有一个数据包的两帧输入数据,这违反了ffmpeg的一帧一帧输出概念,因此我们编写了一个bsf来将数据包分成两部分 - 同时删除标记在将数据包输入解码器之前,该数据包包含两个帧,因此是BSF而不是解析器.在实践中,这解决了帧多线程的其他难题.VP9做同样的事情(称为超帧),但在解析器中拆分帧,因此解析器/ BSF拆分在理论上并不总是完美的; 也许VP9应该被称为BSF)
  • hevc mp4到annexb转换(与上面相同的故事,但对于hevc)
  • aac adts to asc conversion(这与h264/hevc annexb与mp4基本相同,但对于aac音频)

  • 注意,比特流滤波器和解析器与常规视频和音频滤波器的不同之处在于它们在编码的(通常压缩的)比特流上操作,而常规的视频和音频滤波器在未压缩的视频和音频上操作. (3认同)