大概框架:首先创建filter,通过avfilter_link,将各个创建好的filter按⾃⼰想要的次序链接到⼀起,然后avfilter_graph_config之后,就可以正常使⽤。⽐较常⽤的滤镜有:scale、trim、overlay、rotate、movie、yadif。scale 滤镜⽤于缩放,trim 滤镜⽤于帧级剪切,overlay 滤镜⽤于视频叠加,rotate 滤镜实现旋转,movie 滤镜可以加载第三⽅的视频,yadif 滤镜可以去隔⾏。
一、主要结构体和API介绍
AVFilterGraph-对filters系统的整体管理
重点
struct AVFilterGraph{
AVFilterContext **filters;
unsigned nb_filters;
}
AVFilter-定义filter本身的能⼒
const char *name;
const AVFilterPad *inputs;
const AVFilterPad *outputs;
AVFilterContext-filter实例,管理filter与外部的联系
// filter实例,管理filter与外部的联系
重点
struct AVFilterContext
{
const AVFilter *filter;
char *name;
AVFilterPad *input_pads;
AVFilterLink **inputs;
unsigned nb_inputs
AVFilterPad *output_pads;
AVFilterLink **outputs;
unsigned nb_outputs;
struct AVFilterGraph *graph; // 从属于哪个AVFilterGraph
}
AVFilterLink-定义两个filters之间的联接
struct AVFilterLink
{
AVFilterContext *src;
AVFilterPad *srcpad;
AVFilterContext *dst;
AVFilterPad *dstpad;
struct AVFilterGraph *graph;
}
AVFilterPad-定义filter的输⼊/输出接⼝
// 定义filter的输⼊/输出接⼝
重点
struct AVFilterPad
{
const char *name;
AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h);
AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples);
int (*filter_frame)(AVFilterLink *link, AVFrame *frame);
int (*request_frame)(AVFilterLink *link);
}
在AVFilter模块中定义了AVFilter结构,每个AVFilter都是具有独⽴功能的节点,如scale filter的作⽤就是进⾏图像尺⼨变换,overlay filter的作⽤就是进⾏图像的叠加。
这⾥需要重点提的是两个特别的filter,⼀个是buffer,⼀个是buffersink,滤波器buffer代表filter graph中的源头,原始数据就往这个filter节点输⼊的;⽽滤波器buffersink代表filter graph中的输出节点,处理完成的数据从这个filter节点输出。
二、 函数使⽤
// 获取FFmpeg中定义的filter,调⽤该⽅法前需要先调⽤avfilter_register_all();进⾏滤波器注册
AVFilter avfilter_get_by_name(const char name);
// 往源滤波器buffer中输⼊待处理的数据
int av_buffersrc_add_frame(AVFilterContext ctx, AVFrame frame);
// 从⽬的滤波器buffersink中获取处理完的数据
int av_buffersink_get_frame(AVFilterContext ctx, AVFrame frame);
// 创建⼀个滤波器图filter graph
AVFilterGraph *avfilter_graph_alloc(void);
// 创建⼀个滤波器实例AVFilterContext,并添加到AVFilterGraph中
int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
const char name, const char args, void *opaque,
AVFilterGraph *graph_ctx);
// 连接两个滤波器节点
int avfilter_link(AVFilterContext *src, unsigned srcpad,
AVFilterContext *dst, unsigned dstpad);
三、AVFilter主体框架流程
基本结构
我们把⼀整个滤波的流程称为滤波过程。下⾯是⼀个滤波过程的结构
图中简要指示出了滤波所⽤到的各个结构体,各个结构体有如下作⽤:
在利⽤AVFilter进⾏⾳视频数据处理前先将在进⾏的处理流程绘制出来,现在以FFmpeg filter官⽅⽂档中的⼀个例⼦为例进⾏说明。
这个例⼦的处理流程如上所示,⾸先使⽤split滤波器将input流分成两路流(main和tmp),然后分别对两路流进⾏处理。对于tmp流,先经过crop滤波器进⾏裁剪处理,再经过flip滤波器进⾏垂直⽅向上的翻转操作,输出的结果命名为flip流。再将main流和flip流输⼊到overlay滤波器进⾏合成操作。上图的input就是上⾯提过的buffer源滤波器,output就是上⾯的提过的buffersink滤波器。上图中每个节点都是⼀个AVFilterContext,每个连线就是AVFliterLink。所有这些信息都统一由AVFilterGraph来管理。
流程可视化就是将视频下半部分翻转
原视频
处理后