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;