FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。
提供了模板接口,可以方便调用自己的方法快速实现滤镜,并提供了丰富的现成例子。
详细说明在https://github.com/FFmpeg/FFmpeg/blob/master/doc/writing_filters.txt
调用说明首先说明一下,FFmpeg对图像滤镜以 vf_ 为前缀,音频特效以 af_ 为前缀。 在libavfilter\allfilters.c 文件内,声明了所有滤镜/特效的配置。通过avfilter_get_by_name(const char *name) 函数可以拿到对应的滤镜配置。
然后通过下面的函数构建、初始化:
int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
const char *name, const char *args, void *opaque,
AVFilterGraph *graph_ctx)
所有滤镜/特效都要申明在libavfilter/avfilter.h
调用流程在文档中已经做了详细介绍。这里以 cropdetect 功能为例。
cropdetect 可以检测图像四周黑边,然后返回边框参数,方便后续进行裁剪。滤镜实现文件是libavfilter\vf_cropdetect.c
static const AVFilterPad avfilter_vf_cropdetect_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
.filter_frame = filter_frame,
},
};
static const AVFilterPad avfilter_vf_cropdetect_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO
},
};
const AVFilter ff_vf_cropdetect = {
.name = "cropdetect",
.description = NULL_IF_CONFIG_SMALL("Auto-detect crop size."),
.priv_size = sizeof(CropDetectContext),
.priv_class = &cropdetect_class,
.init = init,
FILTER_INPUTS(avfilter_vf_cropdetect_inputs),
FILTER_OUTPUTS(avfilter_vf_cropdetect_outputs),
FILTER_PIXFMTS_ARRAY(pix_fmts),
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
};
init()根据文档,首先会调用init() 函数。这里会完成最终的初始化, buffer 申请和预计算等工作。注意,这时 local context 已经得到了用户的初始化配置,但是并不知道输入的数据类型,所以这个函数通常用来清洗数据。
uninit()释放所有的申请的 buffer。 cropdetect并没有实现。
通常这个函数跟在init() 函数后面,用于格式协商。通常在这里指定输入输出的像素格式(灰度/rgb32/yuv4:2:0)。所有的像素格式定义在libavutil/pixfmt.h 。 cropdetect并没有实现。
filter_frame()这个是等待开始的回调函数,在这里处理收到的图像帧。通过下面函数获取输入链接
static int filter_frame(AVFilterLink *inlink, AVFrame *in) { ... }
可以获取滤镜文本:
AVFilterContext *ctx = inlink->dst;
获取内部状态上下文:
FoobarContext *foobar = ctx->priv;
图像处理后发往的输出链接:
AVFilterLink *outlink = ctx->outputs[0];
|