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则表示提取成功。

相关推荐
海天鹰2 小时前
ffmpeg区域颜色覆盖
ffmpeg
@Crazy Snail15 小时前
C# Winform--ffmpeg图片合成视频以及参数设置
开发语言·ffmpeg·c#
runing_an_min15 小时前
ffmpeg 视频滤镜:高斯模糊-gblur
ffmpeg·音视频·高斯模糊·gblur
disgare15 小时前
FFmpegFrameRecorder 切分视频文件时结束条件设置不当导致切分后的文件过短问题
ffmpeg
Tech Synapse15 小时前
Java中使用FFmpeg拉取RTSP流
java·开发语言·ffmpeg
oushaojun216 小时前
ubuntu中使用ffmpeg和nginx推http hls视频流
nginx·ubuntu·ffmpeg·hls
cuijiecheng20182 天前
FFmpeg源码:ffio_read_indirect函数分析
ffmpeg
黑客KKKing3 天前
网络安全-企业环境渗透2-wordpress任意文件读&&FFmpeg任意文件读
安全·web安全·ffmpeg
oushaojun23 天前
win10中使用ffmpeg和MediaMTX 推流rtsp视频
ffmpeg·rtsp·mediamtx
lxkj_20244 天前
使用线程局部存储解决ffmpeg中多实例调用下自定义日志回调问题
ffmpeg