一、av_register_all()
av_register_all()的申明在文件libavformat\avformat.h中,如下所示
/**
* Initialize libavformat and register all the muxers, demuxers and
* protocols. If you do not call this function, then you can select
* exactly which formats you want to support.
*
* @see av_register_input_format()
* @see av_register_output_format()
*/
attribute_deprecated
void av_register_all(void);
从定义中可以看出av_register_all()过时了,取而代之的是av_register_input_format()、av_register_output_format()这两个函数,不过查看申明也可发现,这两个函数也过时了,我们先看依稀。av_register_all()注册所有的demuxer,muxer,outdev,indev设备。其定义在文件libavformat\allformats.c中,如下所示:
void av_register_all(void)
{
ff_thread_once(&av_format_next_init, av_format_init_next);
}
void av_register_input_format(AVInputFormat *format)
{
ff_thread_once(&av_format_next_init, av_format_init_next);
}
void av_register_output_format(AVOutputFormat *format)
{
ff_thread_once(&av_format_next_init, av_format_init_next);
}
av_register_all()、av_register_input_format()、av_register_output_format()这三个函数调用了一个只运行一次的线程,线程的执行函数是av_format_init_next(),其定义在文件libavcodec\allcodecs.c中,如下所示:
static void av_format_init_next(void)
{
AVOutputFormat *prevout = NULL, *out;
AVInputFormat *previn = NULL, *in;
ff_mutex_lock(&avpriv_register_devices_mutex);
for (int i = 0; (out = (AVOutputFormat*)muxer_list[i]); i++) {
if (prevout)
prevout->next = out;
prevout = out;
}
if (outdev_list) {
for (int i = 0; (out = (AVOutputFormat*)outdev_list[i]); i++) {
if (prevout)
prevout->next = out;
prevout = out;
}
}
for (int i = 0; (in = (AVInputFormat*)demuxer_list[i]); i++) {
if (previn)
previn->next = in;
previn = in;
}
if (indev_list) {
for (int i = 0; (in = (AVInputFormat*)indev_list[i]); i++) {
if (previn)
previn->next = in;
previn = in;
}
}
ff_mutex_unlock(&avpriv_register_devices_mutex);
}
在av_format_init_next()函数中,他涉及到四个变量muxer_list、outdev_list、demuxer_list和indev_list,这四个变量是makefile文件自动生成的,正常是没有的,需要我们编译一下ffmpeg才会出现。其定义如下所示:
libavformat\muxer_list.c
static const AVOutputFormat * const muxer_list[] = {
......
&ff_flv_muxer,
&ff_framecrc_muxer,
&ff_framehash_muxer,
&ff_framemd5_muxer,
&ff_g722_muxer,
&ff_g723_1_muxer,
&ff_g726_muxer,
&ff_g726le_muxer,
&ff_gif_muxer,
&ff_gsm_muxer,
&ff_gxf_muxer,
&ff_h261_muxer,
&ff_h263_muxer,
&ff_h264_muxer,
.....
NULL };
libavformat\demuxer_list.c
static const AVInputFormat * const demuxer_list[] = {
&ff_aa_demuxer,
&ff_aac_demuxer,
&ff_ac3_demuxer,
.......
NULL };
libavdevice\indev_list.c
static const AVInputFormat * const indev_list[] = {
&ff_fbdev_demuxer,
&ff_lavfi_demuxer,
&ff_oss_demuxer,
&ff_v4l2_demuxer,
NULL };
libavdevice\outdev_list.c
static const AVOutputFormat * const outdev_list[] = {
&ff_fbdev_muxer,
&ff_oss_muxer,
&ff_v4l2_muxer,
NULL };
这四个变量都是已经定义了的全局变量,不需要在用其他函数进行注册,所以有关这些变量的注册也就不需要了。
二、avcodec_register_all()
avcodec_register_all()功能和av_register_all函数相似,注册编码器,其申明在文件libavcodec\avcodec.h中,如下所示。
/**
* Register all the codecs, parsers and bitstream filters which were enabled at
* configuration time. If you do not call this function you can select exactly
* which formats you want to support, by using the individual registration
* functions.
*
* @see avcodec_register
* @see av_register_codec_parser
* @see av_register_bitstream_filter
*/
attribute_deprecated
void avcodec_register_all(void);
看申明也是过时了,猜测和上面的情况差不多。
void avcodec_register_all(void)
{
ff_thread_once(&av_codec_next_init, av_codec_init_next);
}
static void av_codec_init_next(void)
{
AVCodec *prev = NULL, *p;
void *i = 0;
while ((p = (AVCodec*)av_codec_iterate(&i))) {
if (prev)
prev->next = p;
prev = p;
}
}
const AVCodec *av_codec_iterate(void **opaque)
{
uintptr_t i = (uintptr_t)*opaque;
const AVCodec *c = codec_list[i];
ff_thread_once(&av_codec_static_init, av_codec_init_static);
if (c)
*opaque = (void*)(i + 1);
return c;
}
codec_list全局变量也是make自动生成的,生成文件libavcodec\codec_list.c。也就不需要进行codec注册了。
static const AVCodec * const codec_list[] = {
.....
&ff_mpeg4_encoder,
......
&ff_mpeg4_decoder,
.....
NULL };