FFmpeg滤镜API用法与实例解析 (6)

调用avfilter_graph_parse_ptr()后,滤镜图如下所示:

3.1.3. 建立滤镜连接

调用avfilter_graph_config()将上一步得到的滤镜图进行配置,建立滤镜间的连接,此步完成后即生了一个可用的滤镜图,如下图所示:

3.2 使用滤镜处理原始帧

配置好滤镜后,可在音视频处理过程中使用滤镜。使用滤镜比配置滤镜简单很多,主要调用如下两个API函数:

调用av_buffersrc_add_frame_flags()将音视频帧发送给滤镜

调用av_buffersink_get_frame()取得经滤镜处理后的音视频帧

4. 滤镜API应用实例分析

滤镜接收原始音视频帧,经过各种效果的滤镜处理后输出的仍然是原始音视频帧。在滤镜API应用实例中,核心内容是“滤镜配置”和“滤镜使用”两个部分,滤镜接收什么样的输入源不重要,对滤镜的输出做什么处理也不重要。不同的输入源,及不同的输出处理方式仅仅是为了加深对滤镜API使用的理解,以及方便观察滤镜的处理效果。

滤镜的输入可以是解码器的输出、原始YUV文件及测试图。本文三个示例只针对视频滤镜:
示例1:编码器的输出作为滤镜的输入,滤镜的输出简单处理,无法观察滤镜效果。
示例2:编码器的输出作为滤镜的输入,滤镜的输出可以播放,可直观观察滤镜效果。
示例3:测试图作为滤镜的输入(而测试图本身也是由特殊滤镜生成),滤镜的输出可以播放,可直接观察滤镜效果。

4.1 示例1:官方例程

https://github.com/FFmpeg/FFmpeg/blob/n4.1/doc/examples/filtering_video.c
官方例程实现的功能是:打开一个视频文件,解码后经过滤镜处理,然后以简单灰度模式在命令窗口中播放视频帧。

例程中使用的滤镜选项是scale=78:24,transpose=cclock,表示先用scale滤镜将视频帧缩放到78x24像素,再用transpose滤镜将视频帧逆时针旋转90度。

简述一下例程的步骤:

打开视频文件,调用open_input_file()实现

初始化滤镜,调用init_filters()实现

解码得到视频帧,调用avcodec_send_packet()和avcodec_receive_frame()获得解码后的原始视频帧

将视频帧发给滤镜,调用av_buffersrc_add_frame_flags()实现

从滤镜输出端取视频帧,调用av_buffersink_get_frame()实现

播放视频帧,调用display_frame()实现

例程核心是滤镜相关的代码,因此视频帧播放部分做了简化处理。

4.2 示例2:可播放版本

官方例程主要演示滤镜API的使用方法,代码量较少,简化了视频播放部分,这样使得滤镜的处理效果无法直观观察。示例2针对此问题,在官方代码基础上增加了正常的视频播放效果。

4.2.1 代码

在https://github.com/leichn/exercises/blob/master/source/ffmpeg/ffmpeg_vfilter/目录下有如下几个文件,说明如下:

vfilter_filesrc.c 用于示例2:输入源为视频文件,经滤镜处理后播放 vfilter_testsrc.c 用于示例3:输入源为测试图,经滤镜处理后播放 video_filter.c 滤镜处理功能 video_play.c 视频播放功能 Makefile

video_filter.c封装了滤镜处理相关代码,详参本文第3节。
video_play.c实现了视频播放功能,本例无需过多关注,实现原理可参考如下两篇文章:
“FFmpeg简易播放器的实现-视频播放”
“ffplay源码分析5-图像格式转换”
vfilter_filesrc.c是示例2的主程序,实现了打开视频文件,解码,滤镜处理,播放的主流程

4.2.2 编译

进入代码目录,在命令行运行make vf_file命令,将生成vf_file可执行文件

4.2.3 测试

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzpdg.html