音视频处理FFMPeg开发实战(10) -- 利用滤镜功能缩放视频

利用滤镜有关函数,对视频高宽进行缩放, 简便省事,省了不少细节上的处理。

回顾一下滤镜的使用方法。

创建FILTER的一般流程:

1、初始化滤镜对象:

(1)调用avfilter_graph_alloc()函数创建一个Filter对象
(2)调用函数avfilter_graph_parse_ptr()把描述信息加到Filter对象上。
(3)调用avfilter_graph_config()函数检查配置有效性、配置滤镜的连接和格式。


	AVFilter *buffersrc = avfilter_get_by_name("buffer");
	AVFilter *buffersink = avfilter_get_by_name("buffersink");
	g_outputs = avfilter_inout_alloc();
	g_inputs = avfilter_inout_alloc();
	string  filters_descr = "scale=640:480";
	enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P };


	g_filter_graph = avfilter_graph_alloc();
	if (!g_outputs || !g_inputs || !g_filter_graph) {
		ret = AVERROR(ENOMEM);
		goto end_filter;
	}

	sprintf_s(args, sizeof(args),
		"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
		codecContext->width, codecContext->height, codecContext->pix_fmt,
		codecContext->time_base.num, codecContext->time_base.den,
		codecContext->sample_aspect_ratio.num, codecContext->sample_aspect_ratio.den);

	ret = avfilter_graph_create_filter(&g_buffersrcContext, buffersrc, "video_input",//"video_input",
		args, NULL, g_filter_graph);
	if (ret < 0) {
		goto end_filter;
	}

	ret = avfilter_graph_create_filter(&g_buffersinkContext, buffersink, "video_output",// "video_output",
		NULL, NULL, g_filter_graph);
	if (ret < 0) {
		goto end_filter;
	}

	ret = av_opt_set_int_list(g_buffersinkContext, "pix_fmts", pix_fmts,
		AV_PIX_FMT_YUV420P, AV_OPT_SEARCH_CHILDREN);
	if (ret < 0) {
		goto end_filter;
	}


	g_outputs->name = av_strdup("in");
	g_outputs->filter_ctx = g_buffersrcContext;
	g_outputs->pad_idx = 0;
	g_outputs->next = NULL;

	g_inputs->name = av_strdup("out");
	g_inputs->filter_ctx = g_buffersinkContext;
	g_inputs->pad_idx = 0;
	g_inputs->next = NULL;

	if ((ret = avfilter_graph_parse_ptr(g_filter_graph, filters_descr.c_str(),
		&g_inputs, &g_outputs, NULL)) < 0)
		goto end_filter;

	if ((ret = avfilter_graph_config(g_filter_graph, NULL)) < 0)
		goto end_filter;
	return ret;

end_filter:
	avfilter_inout_free(&g_inputs);
	avfilter_inout_free(&g_outputs);
	g_inputs = nullptr;
	g_outputs = nullptr;

2、在解码后的数据帧上添加滤镜:

(1)使用av_buffersrc_add_frame_flags()把解码的帧数据传给Filter。
(2)使用av_buffersink_get_frame()从Filter中把处理好的数据取出。

if (av_buffersrc_add_frame_flags(g_buffersrcContext, pSrcVideoFrame, AV_BUFFERSRC_FLAG_PUSH) >= 0)
{
	ret = av_buffersink_get_frame_flags(g_buffersinkContext, filterFrame, AV_BUFFERSINK_FLAG_NO_REQUEST);
	if (ret >= 0)
	{
	}
}

3、工程项目源代码下载:

在Debug – x86 编译通过。
附带完整的开发环境(库,头文件,DLL)

下载源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值