FFmpeg的avfilter_register_all()用于注册所有AVFilter滤镜,包括音频、视频、音视频。但是FFmpeg4.0以后,注册函数已经被标记为过时,保留该方法是为了兼容以前版本。改为编译期自动生成AVFilter,保存在数组中。
在APIChanges文档中有说明,FFmpeg4.0的filter改动如下:
2018-04-01 - f1805d160d - lavfi 7.14.100 - avfilter.h
Deprecate use of avfilter_register(), avfilter_register_all(),
avfilter_next(). Add av_filter_iterate().
AVFilter的注册函数位于libavfilter/allfilters.c,代码如下:
#if FF_API_NEXT
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];
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
与av_register_all()一样,也是调用ff_thread_once方法执行单例线程,只初始化一次。其中,av_filter_init_next是个函数指针,主要是调用av_filter_iterate()进行迭代遍历,把所有AVFilter添加到链表。我们来看下av_filter_iterate()的实现:
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;
}
有用到filter_list数组,这个数组是编译期自动生成,位于libavfilter/filter_list.c,具体如下:
static const AVFilter * const filter_list[] = {
&ff_af_acompressor,
&ff_af_acontrast,
&ff_af_acopy,
&ff_af_acrossfade,
&ff_af_acrossover,
&ff_af_adelay,
&ff_af_aecho,
&ff_af_aemphasis,
&ff_af_afade,
&ff_af_afftdn,
&ff_af_afftfilt,
&ff_af_afir,
&ff_af_aformat,
&ff_af_agate,
&ff_af_aiir,
&ff_af_alimiter,
&ff_af_allpass,
&ff_af_aloop,
&ff_af_amerge,
&ff_af_amix,
&ff_af_anequalizer,
&ff_af_apad,
&ff_af_aphaser,
&ff_af_aresample,
&ff_af_areverse,
&ff_af_asetpts,
&ff_af_asetrate,
&ff_af_atempo,
&ff_af_atrim,
&ff_af_bandpass,
&ff_af_bandreject,
&ff_af_bass,
&ff_af_biquad,
&ff_af_channelmap,
&ff_af_channelsplit,
&ff_af_chorus,
&ff_af_compand,
&ff_af_crossfeed,
&ff_af_dcshift,
&ff_af_earwax,
&ff_af_equalizer,
&ff_af_firequalizer,
&ff_af_flanger,
&ff_af_haas,
&ff_af_highpass,
&ff_af_lowpass,
&ff_af_silencedetect,
&ff_af_silenceremove,
&ff_af_superequalizer,
&ff_af_surround,
&ff_af_treble,
&ff_af_tremolo,
&ff_af_vibrato,
&ff_af_volume,
&ff_af_volumedetect,
&ff_vf_amplify,
&ff_vf_avgblur,
&ff_vf_blackdetect,
&ff_vf_blend,
&ff_vf_colorbalance,
&ff_vf_convolution,
&ff_vf_copy,
&ff_vf_crop,
&ff_vf_deblock,
&ff_vf_delogo,
&ff_vf_deshake,
&ff_vf_drawbox,
&ff_vf_drawgraph,
&ff_vf_drawgrid,
&ff_vf_edgedetect,
&ff_vf_entropy,
&ff_vf_erosion,
&ff_vf_fade,
&ff_vf_gblur,
&ff_vf_gradfun,
&ff_vf_hflip,
&ff_vf_histogram,
&ff_vf_hstack,
&ff_vf_hue,
&ff_vf_inflate,
&ff_vf_lut,
&ff_vf_mix,
&ff_vf_normalize,
&ff_vf_overlay,
&ff_vf_palettegen,
&ff_vf_paletteuse,
&ff_vf_pseudocolor,
&ff_vf_psnr,
&ff_vf_removelogo,
&ff_vf_reverse,
&ff_vf_rotate,
&ff_vf_scale,
&ff_vf_setpts,
&ff_vf_trim,
&ff_vf_vflip,
&ff_vf_vstack,
&ff_vf_zoompan,
&ff_avf_concat,
&ff_avsrc_amovie,
&ff_avsrc_movie,
&ff_af_afifo,
&ff_vf_fifo,
&ff_asrc_abuffer,
&ff_vsrc_buffer,
&ff_asink_abuffer,
&ff_vsink_buffer,
NULL };
filter_list数组的生成来自libavfilter/allfilters.c声明的全局变量:
extern AVFilter ff_af_acompressor;
extern AVFilter ff_af_acontrast;
extern AVFilter ff_af_acopy;
extern AVFilter ff_af_acrossfade;
extern AVFilter ff_af_acrossover;
extern AVFilter ff_af_adelay;
extern AVFilter ff_af_aecho;
extern AVFilter ff_af_afade;
extern AVFilter ff_af_agate;
extern AVFilter ff_af_alimiter;
extern AVFilter ff_af_allpass;
extern AVFilter ff_af_aloop;
extern AVFilter ff_af_amerge;
extern AVFilter ff_af_amix;
extern AVFilter ff_af_apad;
extern AVFilter ff_af_aresample;
extern AVFilter ff_af_areverse;
extern AVFilter ff_af_asetpts;
extern AVFilter ff_af_asetrate;
extern AVFilter ff_af_atempo;
extern AVFilter ff_af_bandpass;
extern AVFilter ff_af_bandreject;
extern AVFilter ff_af_bass;
extern AVFilter ff_af_chorus;
extern AVFilter ff_af_equalizer;
extern AVFilter ff_af_haas;
extern AVFilter ff_af_highpass;
extern AVFilter ff_af_lowpass;
extern AVFilter ff_af_resample;
extern AVFilter ff_af_silencedetect;
extern AVFilter ff_af_silenceremove;
extern AVFilter ff_af_superequalizer;
extern AVFilter ff_af_surround;
extern AVFilter ff_af_treble;
extern AVFilter ff_af_tremolo;
extern AVFilter ff_af_volume;
extern AVFilter ff_af_volumedetect;
extern AVFilter ff_vf_ass;
extern AVFilter ff_vf_avgblur;
extern AVFilter ff_vf_blackdetect;
extern AVFilter ff_vf_blackframe;
extern AVFilter ff_vf_blend;
extern AVFilter ff_vf_boxblur;
extern AVFilter ff_vf_colorspace;
extern AVFilter ff_vf_convolution;
extern AVFilter ff_vf_copy;
extern AVFilter ff_vf_crop;
extern AVFilter ff_vf_deblock;
extern AVFilter ff_vf_delogo;
extern AVFilter ff_vf_deshake;
extern AVFilter ff_vf_drawbox;
extern AVFilter ff_vf_drawgrid;
extern AVFilter ff_vf_drawtext;
extern AVFilter ff_vf_edgedetect;
extern AVFilter ff_vf_erosion;
extern AVFilter ff_vf_fade;
extern AVFilter ff_vf_gblur;
extern AVFilter ff_vf_hflip;
extern AVFilter ff_vf_histogram;
extern AVFilter ff_vf_hstack;
extern AVFilter ff_vf_hue;
extern AVFilter ff_vf_inflate;
extern AVFilter ff_vf_limiter;
extern AVFilter ff_vf_loop;
extern AVFilter ff_vf_lut;
extern AVFilter ff_vf_mix;
extern AVFilter ff_vf_noise;
extern AVFilter ff_vf_overlay;
extern AVFilter ff_vf_palettegen;
extern AVFilter ff_vf_paletteuse;
extern AVFilter ff_vf_pseudocolor;
extern AVFilter ff_vf_psnr;
extern AVFilter ff_vf_removelogo;
extern AVFilter ff_vf_reverse;
extern AVFilter ff_vf_rotate;
extern AVFilter ff_vf_scale;
extern AVFilter ff_vf_setpts;
extern AVFilter ff_vf_smartblur;
extern AVFilter ff_vf_sobel;
extern AVFilter ff_vf_stereo3d;
extern AVFilter ff_vf_transpose;
extern AVFilter ff_vf_vflip;
extern AVFilter ff_vf_vstack;
extern AVFilter ff_vf_xfade;
extern AVFilter ff_vf_zoompan;
/* multimedia filters */
extern AVFilter ff_avf_ahistogram;
extern AVFilter ff_avf_concat;
extern AVFilter ff_avf_showfreqs;
/* multimedia sources */
extern AVFilter ff_avsrc_amovie;
extern AVFilter ff_avsrc_movie;
extern AVFilter ff_asrc_abuffer;
extern AVFilter ff_vsrc_buffer;
extern AVFilter ff_asink_abuffer;
extern AVFilter ff_vsink_buffer;
extern AVFilter ff_af_afifo;
extern AVFilter ff_vf_fifo;
总结libavfilter模块的注册函数改动:把链表改为数组,运行期注册改为编译期自动生成,开发者不用调用注册函数进行注册。