FFmpeg在libavfilter模块提供简单与复杂的音视频滤镜,所有滤波器由AVFilterGraph滤波器图表连接起来。简单滤镜为一对一输出,复杂滤镜为多对一输出。重要的结构体包括:AVFilterGraph、AVFilterLink、AVFilterContext、AVFilter。支持在滤波器图表指定位置插入AVFilter滤波器,然后由AVFilterLink把滤波器连接起来。
1、AVFilterGraph
AVFilterGraph为滤波器图表结构体,保存滤波器上下文、滤波器数量、线程类型、线程数量、回调函数等,代码位于libavfilter/avfilter.h头文件中:
typedef struct AVFilterGraph {
const AVClass *av_class;
// 滤波器上下文
AVFilterContext **filters;
// 滤波器数量
unsigned nb_filters;
char *scale_sws_opts;
int thread_type;
int nb_threads;
AVFilterGraphInternal *internal;
void *opaque;
// 用户设置的回调函数
avfilter_execute_func *execute;
char *aresample_swr_opts;
AVFilterLink **sink_links;
int sink_links_count;
unsigned disable_auto_convert;
} AVFilterGraph;
2、AVFilterLink
AVFilterLink为滤波器的连接器,负责把两个滤波器连接起来,内部包含指向源滤波器和目标滤波器的指针。需要注意的是,应用程序不能直接访问AVFilterLink,使用buffersrc和buffersink的API代替。代码同样位于avfilter.h头文件中:
struct AVFilterLink {
// 源滤波器上下文
AVFilterContext *src;
AVFilterPad *srcpad;
// 目标滤波器上下文
AVFilterContext *dst;
AVFilterPad *dstpad;
// 媒体类型
enum AVMediaType type;
// 视频参数
int w;
int h;
AVRational sample_aspect_ratio;
// 音频参数
uint64_t channel_layout;
int sample_rate;
int format;
// pts的时间基
AVRational time_base;
AVFilterFormatsConfig incfg;
AVFilterFormatsConfig outcfg;
// 连接器的初始化状态
enum {
AVLINK_UNINIT = 0, // 没初始化
AVLINK_STARTINIT, // 已初始化,没完成
AVLINK_INIT // 已完成初始化
} init_state;
struct AVFilterGraph *graph;
// 当前pts时间戳
int64_t current_pts;
int64_t current_pts_us;
int age_index;
AVRational frame_rate;
AVFrame *partial_buf;
int partial_buf_size;
int min_samples;
int max_samples;
int channels;
int64_t frame_count_in, frame_count_out;
void *frame_pool;
int frame_wanted_out;
AVBufferRef *hw_frames_ctx;
#ifndef FF_INTERNAL_FIELDS
// 内部数据结构(保留)
char reserved[0xF000];
#else /* FF_INTERNAL_FIELDS */
// 滤波器的帧队列
FFFrameQueue fifo;
frame_blocked_in;
int status_in;
int64_t status_in_pts;
int status_out;
#endif /* FF_INTERNAL_FIELDS */
};
3、AVFilterContext
AVFilterContext为滤波器上下文的结构体,包含滤波器实例、名字、输入Pad和Link、输出Pad和Link,还有ready字段表示滤波器准备就绪且带有优先级。具体代码如下:
struct AVFilterContext {
const AVClass *av_class;
// 滤波器实例
const AVFilter *filter;
// 滤波器名字
char *name;
AVFilterPad *input_pads;
AVFilterLink **inputs;
unsigned nb_inputs;
AVFilterPad *output_pads;
AVFilterLink **outputs;
unsigned nb_outputs;
void *priv;
struct AVFilterGraph *graph;
int thread_type;
AVFilterInternal *internal;
struct AVFilterCommand *command_queue;
char *enable_str;
void *enable;
double *var_values;
int is_disabled;
AVBufferRef *hw_device_ctx;
int nb_threads;
// 滤波器准备就绪,带优先级
unsigned ready;
int extra_hw_frames;
};
4、AVFilter
AVFilter为滤波器的结构体,包含滤波器名字与描述、输入输出的AVFilterPad、滤波器操作的函数指针。具体代码如下:
typedef struct AVFilter {
// 滤波器名字
const char *name;
// 滤波器描述
const char *description;
const AVFilterPad *inputs;
const AVFilterPad *outputs;
const AVClass *priv_class;
int flags;
int priv_size;
int flags_internal;
// 预初始化函数指针
int (*preinit)(AVFilterContext *ctx);
// 初始化函数指针
int (*init)(AVFilterContext *ctx);
// 带字典参数的初始化函数指针
int (*init_dict)(AVFilterContext *ctx, AVDictionary **options);
// 反初始化函数指针
void (*uninit)(AVFilterContext *ctx);
// 查询滤波器支持的输入输出格式
int (*query_formats)(AVFilterContext *);
// 处理命令函数指针
int (*process_command)(AVFilterContext *, const char *cmd,
const char *arg, char *res,