1、执行congfigure时:从allfilters.c获取滤镜名,并将其写入filter_list.c
configure
find_filters_extern(){
file=$source_path/$1
sed -n 's/^extern AVFilter ff_[avfsinkrc]\{2,5\}_\([[:alnum:]_]\{1,\}\);/\1_filter/p' $file
}
#从allfilters.c获取滤镜名
FILTER_LIST=$(find_filters_extern libavfilter/allfilters.c)
#生成filter_list.c文件,将滤镜名写入文件中
print_enabled_components libavfilter/filter_list.c AVFilter filter_list $FILTER_LIST
allfilters.c
extern AVFilter ff_af_abench;
extern AVFilter ff_af_acompressor;
extern AVFilter ff_af_acontrast;
extern AVFilter ff_af_acopy;
extern AVFilter ff_af_acue;
extern AVFilter ff_af_acrossfade;
extern AVFilter ff_af_acrossover;
extern AVFilter ff_af_acrusher;
extern AVFilter ff_af_adeclick;
extern AVFilter ff_af_adeclip;
extern AVFilter ff_af_adelay;
extern AVFilter ff_af_adenorm;
extern AVFilter ff_af_aderivative;
extern AVFilter ff_af_aecho;
extern AVFilter ff_af_aemphasis;
extern AVFilter ff_af_aeval;
。
。
。
filter_list.c
static const AVFilter * const filter_list[] = {
&ff_af_abench,
&ff_af_acompressor,
&ff_af_acontrast,
&ff_af_acopy,
&ff_af_acue,
&ff_af_acrossfade,
&ff_af_acrossover,
&ff_af_acrusher,
&ff_af_adeclick,
&ff_af_adeclip,
&ff_af_adelay,
&ff_af_adenorm,
&ff_af_aderivative,
&ff_af_aecho,
&ff_af_aemphasis,
&ff_af_aeval,
&ff_af_aexciter,
&ff_af_afade,
&ff_af_afftdn,
&ff_af_afftfilt,
&ff_af_afir,
。
。
。
2、之后的注册或是查找,都是从filter_list中查询
allfilters.c
const AVFilter *av_filter_iterate(void **opaque)
{
uintptr_t i = (uintptr_t)*opaque;
const AVFilter *f = filter_list[i];
if (f)
*opaque = (void*)(i + 1);
return f;
}
const AVFilter *avfilter_get_by_name(const char *name)
{
const AVFilter *f = NULL;
void *opaque = 0;
if (!name)
return NULL;
while ((f = av_filter_iterate(&opaque)))
if (!strcmp(f->name, name))
return f;
return NULL;
}
#if FF_API_NEXT
FF_DISABLE_DEPRECATION_WARNINGS
static AVOnce av_filter_next_init = AV_ONCE_INIT;
static void av_filter_init_next(void)
{
AVFilter *prev = NULL, *p;
void *i = 0;
while ((p = (AVFilter*)av_filter_iterate(&i))) {
if (prev)
prev->next = p;
prev = p;
}
}
void avfilter_register_all(void)
{
ff_thread_once(&av_filter_next_init, av_filter_init_next);
}
int avfilter_register(AVFilter *filter)
{
ff_thread_once(&av_filter_next_init, av_filter_init_next);
return 0;
}
const AVFilter *avfilter_next(const AVFilter *prev)
{
ff_thread_once(&av_filter_next_init, av_filter_init_next);
return prev ? prev->next : filter_list[0];
}
3、allfilter.c里的滤镜结构体都是extern声明的,实际定义的地方在滤镜本身对应的c文件里,比如ff_vsrc_buffer的定义是在buffersrc.c里
AVFilter ff_vsrc_buffer = {
.name = "buffer",
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
.priv_size = sizeof(BufferSourceContext),
.query_formats = query_formats,
.init = init_video,
.uninit = uninit,
.inputs = NULL,
.outputs = avfilter_vsrc_buffer_outputs,
.priv_class = &buffer_class,
};