FFmpeg滤波器创建

本文详细讲解了要创建简单和复杂两种滤波器的过程,所用到的api。重点了解如何用字符串创建复杂滤波器.

1.创建简单的滤波过程

第一步:得到所需的滤波器(AVFilter),buffer和buffersink作为输入、输出的滤波器。

avfilter_get_by_name()根据名字搜索对应滤波器

c 复制代码
	const AVFilter *buffersrc = avfilter_get_by_name("buffer");
	const AVFilter *buffersink = avfilter_get_by_name("buffersink");
	const AVFilter *myfilter = avfilter_get_by_name("myfilter");

第二步:声明整个滤波过程的滤波图结构体

c 复制代码
	filter_graph = avfilter_graph_alloc();

第三步:创建滤波器实例(AVFilterContext)

c 复制代码
	AVFilterContext *in_video_filter = NULL;
	AVFilterContext *out_video_filter = NULL;
	AVFilterContext *my_video_filter = NULL;
	avfilter_graph_create_filter(&in_video_filter, buffersrc, "in", args,NULL, filter_graph);
	avfilter_graph_create_filter(&out_video_filter, buffersink, "out", NULL, NULL, filter_graph);
	avfilter_graph_create_filter(&my_video_filter, myfilter, "myfilter",NULL, NULL, filter_graph);

第四步:⽤AVFilterLink把相邻的两个滤波实例连接起来,注意函数输入里的0,表示通道,可以创建多个通道。

c 复制代码
	avfilter_link(in_video_filter, 0, my_video_filter, 0);
	avfilter_link(my_video_filter, 0, out_video_filter, 0);

第五步:最后一定要提交整个滤波图,这样才会生效

c 复制代码
	avfilter_graph_config(filter_graph, NULL);

2.创建复杂的滤波过程

复杂的滤波过程,采取前一小节创建方式效率不高,需采用字符串进行描述。

c 复制代码
	[0]trim=start_frame=10:end_frame=20[v0];\
	[0]trim=start_frame=30:end_frame=40[v1];\
	[v0][v1]concat=n=2[v2];\
	[1]hflip[v3];\
	[v2][v3]overlay=eof_action=repeat[v4];\
	[v4]drawbox=50:50:120:120:red:t=5[v5]

整体过程和前一小节类似进行创建:

第一步:声明整个滤波过程的滤波图结构体

c 复制代码
filter_graph = avfilter_graph_alloc();

第二步:把输入和过滤器命令的参数打印到filter_args里。

第一种写法:输入输出定义好

cpp 复制代码
    snprintf(filter_args, sizeof(filter_args),
	"buffer=video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d[v0];" // Parsed_buffer_0
			 "[v0]trim=start_frame=10:end_frame=20[v1];" // Parsed_trim_1
			 "[v0]trim=start_frame=30:end_frame=40[v2];" // Parsed_trim_2
			 "[v1][v2]concat=n=2[v3];"// Parsed_concat_3
			 "[v2]hflip[v4];"// Parsed_gflip_4
		 	 "[v3][v4]overlay=eof_action=repeat[v5];"// Parsed_overlay_5
			 "[v5]drawbox=50:50:120:120:red:t=5[v6];"// Parsed_drawbox_6
             "[v6]buffersink", // Parsed_buffersink_7
             width, height, format, 1, 25, 1, 1);
	)

第二种,不写输入输出

c 复制代码
snprintf(filter_args, sizeof(filter_args),
			 "[v0]trim=start_frame=10:end_frame=20[v1];" // Parsed_trim_1
			 "[v0]trim=start_frame=30:end_frame=40[v2];" // Parsed_trim_2
			 "[v1][v2]concat=n=2[v3];"// Parsed_concat_3
			 "[v2]hflip[v4];"// Parsed_gflip_4
		 	 "[v3][v4]overlay=eof_action=repeat[v5];"// Parsed_overlay_5
			 "[v5]drawbox=50:50:120:120:red:t=5[v6]"// Parsed_drawbox_6);
	)

第三步:对前面字符串进行解析,并构建滤波图。

第一种:

c 复制代码
avfilter_graph_parse2(filter_graph, graph_desc, &inputs, &outputs);

在该例子中已经写好了输入Buffer和输出buffersink,所以之后直接提交过滤器就可以。建议使用第一种

第二种没写输入输出,如下:

其中,inputs和outputs为输入、输出的接口集合。

c 复制代码
	for (cur = inputs, i = 0; cur; cur = cur->next, i++) {
		const AVFilter *buffersrc = avfilter_get_by_name("buffer");
		avfilter_graph_create_filter(&filter, buffersrc, name, args, NULL, filter_graph);
		avfilter_link(filter, 0, filter_graph, cur->pad_idx);
	}
	avfilter_inout_free(&inputs);
	for (cur = outputs, i = 0; cur; cur = cur->next, i++) {
		const AVFilter *buffersink = avfilter_get_by_name("buffersink");
		avfilter_graph_create_filter(&filter, buffersink, name, NULL, NULL, filter_graph);
		avfilter_link(filter_graph, cur->pad_idx, filter, 0);
	}
	avfilter_inout_free(&outputs);

第三步:提交整个滤波图,这样才会生效

avfilter_graph_config(filter_graph, NULL);

3.帧的传入传出

传入:向指定的buffersrc实例输⼊想要进⾏滤波的帧。

c 复制代码
av_buffersrc_add_frame(c->in_filter, pFrame);

传出:从指定的buffersink实例提取滤波完成的帧

c 复制代码
av_buffersink_get_frame(c->out_filter, pFrame);

av_buffersink_get_frame返回值⼤于0则表示提取成功。

相关推荐
luoqice2 天前
RTMP视频流的帧格式分析
网络·ffmpeg
老姚---老姚2 天前
编译支持HEVC/H.265 over RTMP / Enhanced RTMP 的 ffmpeg
ffmpeg·h.265·hevc·rtmp·enhanced
码流怪侠4 天前
FFmpeg 开发实战全解析:从入门到精通(附完整代码示例)
ffmpeg·音视频开发·视频编码
圆弧YH4 天前
FFmpeg
ffmpeg
luoqice4 天前
FLV文件格式详解
ffmpeg
happybasic5 天前
在CMD下使用FFmpeg将.wav文件转换成指定的格式~
ffmpeg
shao9185165 天前
第10章 Streaming(上):初级音频应用(1)——项目三:自建服务器的Mini-Omni实时语音聊天机器人
ffmpeg·whisper·asr·mini-omni·自建语音服务器
Leon_Chenl5 天前
【已开源】【嵌入式 Linux 音视频+ AI 实战项目】瑞芯微 Rockchip 系列 RK3588-基于深度学习的人脸门禁+ IPC 智能安防监控系统
深度学习·opencv·yolo·ffmpeg·音视频·边缘计算·人脸识别+检测
antzou6 天前
视频图片/文字水印
ffmpeg·视频水印·批量水印
AC赳赳老秦7 天前
DBA 专属方案:用 OpenClaw 实现 SQL 语句优化、慢查询分析、数据库备份巡检全自动化
服务器·前端·数据库·ffmpeg·自动化·deepseek·openclaw