ffmpeg中滤镜有两种,一种是处理滤镜,一种是源滤镜
1 处理滤镜是有输入的,有输出的如 vf_unsharp
2 源滤镜 没有输入,只有输出 如src_movie.c
一 先看下如何添加一个处理滤镜
AVFilter ff_vf_roiblur = {
.name = "roiblur",
.description = NULL_IF_CONFIG_SMALL("Apply Roi Blur filter."),
.priv_size = sizeof(RoiBlurContext),
.priv_class = &roiblur_class,
.uninit = uninit,
.query_formats = query_formats,
.inputs = roiblur_inputs,
.outputs = roiblur_outputs,
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
};
static const AVFilterPad roiblur_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
.config_props = config_input,
},
{ NULL }
};
static const AVFilterPad roiblur_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
},
{ NULL }
};
先定义滤镜名字,这里的ff_vf_roiblur 即是滤镜名字,最终需要手动添加到allfilters.c文件中,然后执行./configure ,这样就能自动生成对应的Makefile
其中的关键函数
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
RoiBlurContext *s = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
int plane;
AVFrame *out = av_frame_alloc();
out->width = in->width;
out->height = in->height;
out->format = in->format;
av_frame_get_buffer(out,32);
av_frame_copy_props(out,in);
if(is_roi_valid(s->x0,s->y0,s->w0,s->h0) == 1)
{
blur_roi_area(out,s->x0,s->y0,s->w0,s->h0);
}
if(is_roi_valid(s->x1,s->y1,s->w1,s->h1) == 1)
{
blur_roi_area(out,s->x1,s->y1,s->w1,s->h1);
}
if(is_roi_valid(s->x2,s->y2,s->w2,s->h2) == 1)
{
blur_roi_area(out,s->x2,s->y2,s->w2,s->h2);
}
if(is_roi_valid(s->x3,s->y3,s->w3,s->h3) == 1)
{
blur_roi_area(out,s->x3,s->y3,s->w3,s->h3);
}
if(in)
{
av_frame_free(&in);
in = NULL;
}
return ff_filter_frame(outlink, out);//将滤镜处理后的AVFrame 流向下一个滤镜
}
最终滤镜文件保存在libavfilter 目录下,文件名和滤镜名要对应,vf_roiblur.c
allfilters.c中的修改:
extern AVFilter ff_vf_roiblur;