FFmpeg滤镜相关的重要结构体
核心结构体概览
FFmpeg滤镜系统由多个关键结构体组成,构成了完整的滤镜处理框架。以下是滤镜系统中最重要的结构体及其相互关系:
AVFilterGraph ┬─ AVFilterContext ┬─ AVFilter│ ├─ AVFilterLink│ └─ AVFilterPad└─ AVFilterInOut
详细结构体分析
1. AVFilterGraph(滤镜图容器)
功能:管理整个滤镜图的所有组件和状态
重要成员:
typedef struct AVFilterGraph {const AVClass *av_class; // 类信息,用于日志和配置AVFilterContext **filters; // 所有滤镜实例数组unsigned nb_filters; // 滤镜数量AVFilterLink **sink_links; // 所有输出链接int sink_links_count; // 输出链接数量char *graph_str; // 滤镜图描述字符串// ...其他成员
} AVFilterGraph;
2. AVFilter(滤镜定义)
功能:描述滤镜的类型、功能和操作接口
重要成员:
typedef struct AVFilter {const char *name; // 滤镜名称(唯一标识)const char *description; // 滤镜描述const AVFilterPad *inputs; // 输入端口定义const AVFilterPad *outputs; // 输出端口定义int (*init)(AVFilterContext *ctx); // 初始化函数int (*uninit)(AVFilterContext *ctx);// 反初始化函数int (*query_formats)(AVFilterContext *ctx); // 格式协商函数// ...其他成员
} AVFilter;
3. AVFilterContext(滤镜实例)
功能:表示滤镜图中的一个具体滤镜实例
重要成员:
typedef 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; // 滤镜私有数据// ...其他成员
} AVFilterContext;
4. AVFilterLink(滤镜连接)
功能:表示两个滤镜之间的连接关系和数据通道
重要成员:
typedef struct AVFilterLink {AVFilterContext *src; // 源滤镜AVFilterContext *dst; // 目标滤镜AVFilterPad *srcpad; // 源端口AVFilterPad *dstpad; // 目标端口enum AVMediaType type; // 媒体类型(视频/音频)/* 协商后的格式参数 */int w, h; // 视频宽高int sample_rate; // 音频采样率AVSampleFormat format; // 音频格式AVPixelFormat format; // 视频格式int64_t current_pts; // 当前时间戳AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h);AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples);// ...其他成员
} AVFilterLink;
5. AVFilterPad(滤镜端口)
功能:定义滤镜的输入/输出端口特性
重要成员:
typedef struct AVFilterPad {const char *name; // 端口名称enum AVMediaType type; // 媒体类型// 重要回调函数int (*config_props)(AVFilterLink *link); // 配置属性int (*filter_frame)(AVFilterLink *link, AVFrame *frame); // 帧处理int (*request_frame)(AVFilterLink *link); // 请求帧// ...其他成员
} AVFilterPad;
6. AVFilterInOut(滤镜输入输出端点)
功能:用于构建滤镜图时的临时连接描述
重要成员:
typedef struct AVFilterInOut {char *name; // 流标识名称AVFilterContext *filter_ctx; // 关联的滤镜int pad_idx; // 端口索引struct AVFilterInOut *next; // 链表指针
} AVFilterInOut;
结构体关系图解
[AVFilterGraph] 管理多个|├── [AVFilterContext] 实例1 ──基于─→ [AVFilter] (模板)│ ├── input_pads: [AVFilterPad]数组│ ├── output_pads: [AVFilterPad]数组│ ├── inputs: [AVFilterLink]数组 (连接到上游)│ └── outputs: [AVFilterLink]数组 (连接到下游)│├── [AVFilterContext] 实例2│ ├── ...│└── [AVFilterInOut]链表 (临时构建用)
关键API函数
-
滤镜图管理:
avfilter_graph_alloc()
- 创建滤镜图avfilter_graph_free()
- 释放滤镜图avfilter_graph_parse_ptr()
- 解析滤镜描述字符串
-
滤镜实例管理:
avfilter_graph_create_filter()
- 创建滤镜实例avfilter_link()
- 连接两个滤镜
-
数据处理:
av_buffersrc_add_frame()
- 向滤镜图输入数据av_buffersink_get_frame()
- 从滤镜图获取输出
实际应用示例
创建滤镜图的基本流程
AVFilterGraph *graph = avfilter_graph_alloc();// 创建buffer源滤镜(输入)
AVFilterContext *src_ctx;
avfilter_graph_create_filter(&src_ctx, avfilter_get_by_name("buffer"),"in", args, NULL, graph);// 创建buffer汇滤镜(输出)
AVFilterContext *sink_ctx;
avfilter_graph_create_filter(&sink_ctx,avfilter_get_by_name("buffersink"),"out", NULL, NULL, graph);// 创建处理滤镜(如scale)
AVFilterContext *scale_ctx;
avfilter_graph_create_filter(&scale_ctx,avfilter_get_by_name("scale"),"scale", "640:480", NULL, graph);// 连接滤镜
avfilter_link(src_ctx, 0, scale_ctx, 0);
avfilter_link(scale_ctx, 0, sink_ctx, 0);// 配置完成
avfilter_graph_config(graph, NULL);
自定义滤镜开发模板
typedef struct {const AVClass *class;// 自定义参数int param1;float param2;// ...其他私有数据
} MyFilterContext;static int filter_frame(AVFilterLink *inlink, AVFrame *frame) {MyFilterContext *ctx = inlink->dst->priv;// 处理帧数据process_frame(frame, ctx->param1, ctx->param2);// 传递给下一个滤镜return ff_filter_frame(inlink->dst->outputs[0], frame);
}static const AVFilterPad myfilter_inputs[] = {{.name = "default",.type = AVMEDIA_TYPE_VIDEO,.filter_frame = filter_frame,},{ NULL }
};AVFilter ff_vf_myfilter = {.name = "myfilter",.description = "My custom filter",.priv_size = sizeof(MyFilterContext),.inputs = myfilter_inputs,.outputs = NULL, // 动态分配.priv_class = &myfilter_class,
};