2015-08-15 31 views
6

经过仔细阅读FFmpeg Bitstream Filters Documentation,我仍然不明白他们真的是什么。什么是ffmpeg中的比特流筛选器?

该文件指出,过滤器:

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

谁能进一步解释说,给我吗?用例会大大地澄清事物。此外,有明显不同的过滤器。他们有什么不同?

+0

我没有downvote,但它可能是同一个人,投票结束本网站脱离主题(不编程相关)的问题。 – mark4o

回答

19

让我来举例说明。 FFmpeg视频解码器通常通过将每个呼叫的一个视频帧转换为avcodec_decode_video2来工作。因此预计输入是比特流数据的“一个图像”。让我们考虑从文件(磁盘字节数组)到图像的第二个问题。对于“原始”(附录b)H264(.h264/.bin/.264文件),单独的最终单元数据(sps/pps头部比特流或cabac编码的帧数据)被串联在一个nal单元序列中,中间有一个起始码(00 00 01 XX),其中XX是最终设备类型。 (为了防止nal数据本身拥有00 00 01数据,它是RBSP转义的。)所以一个h264 frame parser可以简单地在开始代码标记处剪切文件。他们搜索以00 00 01开始并且包括00 00 01的连续分组,直到并且排除00 00 01的下一个分组。然后,他们解析最终单元类型和切片报头以找到每个分组属于哪个帧,并且返回一组nal作为h264 decoder的输入组成一帧的单元。

但.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 frame unpacking(得到乙 - 像IBP这样的编码为IPB的帧序列,在AVI中获得时间戳,人们提出了这种B帧包装的概念,其中IBP/IPB在帧中打包为I-(PB)-(),即第三个包是空的,第二个包是空的有两个帧,这意味着在解码阶段与P和B帧相关的时间戳是正确的。这也意味着对于一个数据包你有两帧输入数据,这违反了ffmpeg的一帧一帧输出概念,所以我们写了一个bsf将数据包分成两部分 - 连同删除标记说数据包包含两个帧,因此BSF而不是解析器 - 在输入到解码器之前。实际上,这解决了帧多线程的其他难题。 VP9做同样的事情(称为超帧),但拆分了parser中的帧,所以解析器/ BSF拆分在理论上并不总是完美的;也许VP9的应该叫BSF)
  • HEVC MP4到annexb如上述的转换(同一个故事,但对于HEVC)
  • AAC adts to asc转换(这基本上是一样的H264/HEVC annexb与MP4,但对AAC音频)
+1

请注意,比特流过滤器和解析器与普通视频和音频过滤器不同,因为它们在编码(通常为压缩)比特流上运行,而常规视频和音频过滤器则在未压缩视频和音频上运行。 – mark4o

+0

与mark4o的说法类似,请注意,在运行ffmpeg而未执行流拷贝(即实际转码视频)时,将在重新编码之后应用比特流筛选器。 – bhh1988