FFmpeg滤波器创建

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

1.创建简单的滤波过程

第一步:得到所需的滤波器(AVFilter),buffer和buffersink作为输入、输出的滤波器。
avfilter_get_by_name()根据名字搜索对应滤波器

	const AVFilter *buffersrc = avfilter_get_by_name("buffer");
	const AVFilter *buffersink = avfilter_get_by_name("buffersink");
	const AVFilter *myfilter = avfilter_get_by_name("myfilter");

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

	filter_graph = avfilter_graph_alloc();

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

	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,表示通道,可以创建多个通道。

	avfilter_link(in_video_filter, 0, my_video_filter, 0);
	avfilter_link(my_video_filter, 0, out_video_filter, 0);

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

	avfilter_graph_config(filter_graph, NULL);

2.创建复杂的滤波过程

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

	[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]

整体过程和前一小节类似进行创建:
第一步:声明整个滤波过程的滤波图结构体

filter_graph = avfilter_graph_alloc();

第二步:把输入和过滤器命令的参数打印到filter_args里。
第一种写法:输入输出定义好

    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);
	)

第二种,不写输入输出

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);
	)

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

avfilter_graph_parse2(filter_graph, graph_desc, &inputs, &outputs);

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

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

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

	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实例输⼊想要进⾏滤波的帧。

av_buffersrc_add_frame(c->in_filter, pFrame);

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

av_buffersink_get_frame(c->out_filter, pFrame);

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

相关推荐

  1. FFmpeg滤波器创建

    2024-03-24 15:04:02       18 阅读
  2. <span style='color:red;'>ffmpeg</span>

    ffmpeg

    2024-03-24 15:04:02      14 阅读
  3. FFmpeg

    2024-03-24 15:04:02       11 阅读
  4. ffmpeg

    2024-03-24 15:04:02       11 阅读
  5. 滤波器opencv

    2024-03-24 15:04:02       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-24 15:04:02       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-24 15:04:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-24 15:04:02       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-24 15:04:02       20 阅读

热门阅读

  1. Uniapp manifest

    2024-03-24 15:04:02       17 阅读
  2. 搜索旋转排序数组

    2024-03-24 15:04:02       23 阅读
  3. 课时73:流程控制_for循环_综合案例

    2024-03-24 15:04:02       17 阅读
  4. 【Linux】调试器-gdb的安装与使用

    2024-03-24 15:04:02       17 阅读
  5. dom元素+CSS实现阶梯动画效果

    2024-03-24 15:04:02       19 阅读
  6. Linux安装iptables 防火墙

    2024-03-24 15:04:02       20 阅读
  7. 前端安全之XSS与CSRF

    2024-03-24 15:04:02       15 阅读
  8. Median of an Array(贪心策略,编程技巧)

    2024-03-24 15:04:02       20 阅读
  9. Mysql

    Mysql

    2024-03-24 15:04:02      16 阅读
  10. arm linux应用程序crash分析一般方法

    2024-03-24 15:04:02       18 阅读
  11. Vue2 CSS小知识点

    2024-03-24 15:04:02       19 阅读
  12. 【力扣】268.丢失的数字

    2024-03-24 15:04:02       19 阅读