如何在ffmpeg中添加自定义滤镜

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;

 

 

你可能感兴趣的:(音视频)