FFMPEG中avfilter模块 调用流程
FFMPEG中avfilter模块 调用流程
- FFMPEG中avfilter模块 调用流程
- 前言
- 一、avfilter的调用流程图
- 二、filter的初始化
- 三、两个特殊的filter
- 四、初始化filter的基本过程
- 五、使用filter步骤
- 六、滤镜处理
- 总结
前言
视频拼接
一、avfilter的调用流程图

二、filter的初始化

./ffmpeg -buffer_size 1024000 -i udp://@224.1.1.3:20000 -i udp://@224.1.1.3:20000 -filter_complex "[0:v]crop=900:900:10:10,scale=1920:1080[v0];[1:v]crop=900:900:10:10,scale=1920:1080[v1];[v0][v1]hstack=2[out]" -pkt_size 1316 -map [out] -f mpegts udp://@239.255.255.250:54546
AVFilterLink对应是描述符(scare:90:90)
三、两个特殊的filter
- 1.buffer filter (处理前中的数据放到这里)
- 2 buffersink filter (滤镜处理完成后放到这里)
四、初始化filter的基本过程
- 1、 创建 graph, avfilter_graph_alloc()
- 2、buffer filter 和buffersink filter
- 3、 分析filter描述符,并构造AVFilterGraph
- 4、使构建好的AVFilterGraph生效
init_filter函数实现
/*
* 初始化过滤器
*/
static int32_t init_filters(const char * filter_desc)
{int32_t ret = 0;const AVFilter * buffersrc = ::avfilter_get_by_name("buffer");const AVFilter* buffersink = ::avfilter_get_by_name("buffersink");AVFilterInOut * inputs = ::avfilter_inout_alloc();AVFilterInOut* outputs = ::avfilter_inout_alloc();if (!inputs){printf("alloc inputs failed !!!\n");return -1;}if (!outputs){printf("alloc outputs failed !!!\n");return -1;}char args[1024] = { 0 };AVRational time_base = g_fmt_ctx_ptr->streams[g_video_stream_index]->time_base;// video_size=wxh:pix_fmt=xx:time_base=xxx/xxxx:pixel_aspect=xxx/xxsnprintf(args, 1024, "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",g_codec_ctx_ptr->width, g_codec_ctx_ptr->height, g_codec_ctx_ptr->pix_fmt, time_base.num, time_base.den, g_codec_ctx_ptr->sample_aspect_ratio.num, g_codec_ctx_ptr->sample_aspect_ratio.den);//g_graph = ::avfilter_graph_alloc();if (!g_graph){printf("alloc graph failed !!!\n");return -1;}//解析描述符 filter_desc // "[0:v]crop=900:900:10:10,scale=1920:1080[v0];[1:v]crop=900:900:10:10,scale=1920:1080[v1];[v0][v1]hstack=2[out]"// [a][b]overlay=xxxx[out]// 输入 buffer filter 创建// 构造input 和output// args : 查看参数 命令 : ./ffmpeg -h filter=bufferret = ::avfilter_graph_create_filter(&g_buffer_ctx, buffersrc, "in", args, NULL/*buffer 用户数据*/, g_graph);if (ret < 0){printf("in -->avfilter graph create filter failed !!!");return ret;}// args 参数查看: ./ffmpeg -h filter=buffersink//buffersink AVOptions ://pix_fmts <binary> ..FV.......set the supported pixel formatsenum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };// 输出buffer sink filter 创建ret = ::avfilter_graph_create_filter(&g_buffersink_ctx, buffersink, "out", NULL, NULL/*buffer 用户数据*/, g_graph);if (ret < 0){printf("buffer sink filter graph create filter failed !!!");return -1;}ret = av_opt_set_int_list((void *)g_buffersink_ctx, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);//比较奇怪// create outinputs->name = av_strdup("out");inputs->filter_ctx = g_buffer_ctx;inputs->pad_idx = 0;inputs->next = NULL;// outpus 构造// create inoutputs->name = av_strdup("in");outputs->filter_ctx = g_buffersink_ctx;outputs->pad_idx = 0;outputs->next = NULL;//最重要步骤//// create filter and add graph for filter desciption ret = ::avfilter_graph_parse_ptr(g_graph, filter_desc, &inputs, &outputs, NULL );//graph 生效ret = ::avfilter_graph_config(g_graph, NULL);if (ret < 0){printf("filter graph config failed !!!\n");return ret;}::avfilter_inout_free(&inputs);::avfilter_inout_free(&outputs);inputs = NULL;outputs = NULL;return 0;
}
五、使用filter步骤
- 1、 获得解码后得原始数据 PCM/YUV
- 2、 将数据添加到buffer filter中
- 3、从buffersink 中读取处理好得数据
- 4、当所有数据处理完成后, 释放资源
六、滤镜处理
/***
*解码器视频帧 滤镜处理
*/
static int filter_video(AVFrame* frame, AVFrame*filter_frame)
{// 向filter buffer中添加视频帧int32_t ret = ::av_buffersrc_add_frame(g_buffer_ctx, frame);if (ret < 0){printf("filter buffersrc add frame failed (%s)!!!\n", make_error_string(ret));return ret;}//获取buffersink 处理完成后得数据while (true){ret = ::av_buffersink_get_frame(g_buffersink_ctx, filter_frame);if (ret < 0){//有可能buuffersink还没有处理好数据 需要继续获取得啦 ~~~~if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){// 需要释放资源啦 ~~~~// av_frame_unref(filter_frame);break;}return ret;}// 直接写入文件中区do_frame(filter_frame);av_frame_unref(filter_frame);}av_frame_unref(filter_frame);
}
效果图
总结
filter的demo地址:https://github.com/chensongpoixs/cmp4_box_avi_flv/tree/master/filter