您的位置:首页 > 其它

ffmpeg源码简析(二)av_register_all(),avcodec_register_all()

2017-04-24 16:00 676 查看

av_register_all()

该函数在所有基于ffmpeg的应用程序中几乎都是第一个被调用的。只有调用了该函数,才能使用复用器,编码器等。

av_register_all()调用了avcodec_register_all()。avcodec_register_all()注册了和编解码器有关的组件:硬件加速器,解码器,编码器,Parser,Bitstream Filter。av_register_all()除了调用avcodec_register_all()之外,还注册了复用器,解复用器,协议处理器。

下面附上复用器,解复用器,协议处理器的代码。

注册复用器的函数是av_register_output_format()。

void av_register_output_format(AVOutputFormat *format)
{
AVOutputFormat **p;
p = &first_oformat;
while (*p != NULL) p = &(*p)->next;
*p = format;
format->next = NULL;
}


注册解复用器的函数是av_register_input_format()。

//遍历链表并把当前的Input Format加到链表的尾部。
void av_register_input_format(AVInputFormat *format)
{
AVInputFormat **p;
p = &first_iformat;
while (*p != NULL) p = &(*p)->next;
*p = format;
format->next = NULL;
}


注册协议处理器的函数是ffurl_register_protocol()。

int ffurl_register_protocol(URLProtocol *protocol)
{
URLProtocol **p;
p = &first_protocol;
while (*p)
p = &(*p)->next;
*p             = protocol;
protocol->next = NULL;
return 0;
}


下面贴出它的源代码(allformats.c)

#include "avformat.h"
#include "rtp.h"
#include "rdt.h"
#include "url.h"
//定义的宏?宏的速度会快一点?注册AVOutputFormat
//define中,#用来把参数转换成字符串,##则用来连接前后两个参数,把它们变成一个字符串。
#define REGISTER_MUXER(X,x) { \
extern AVOutputFormat ff_##x##_muxer; \
if(CONFIG_##X##_MUXER) av_register_output_format(&ff_##x##_muxer); }
//注册AVInputFormat
#define REGISTER_DEMUXER(X,x) { \
extern AVInputFormat ff_##x##_demuxer; \
if(CONFIG_##X##_DEMUXER) av_register_input_format(&ff_##x##_demuxer); }
//注册函数av_register_input_format

//两个一起注册!
#define REGISTER_MUXDEMUX(X,x)  REGISTER_MUXER(X,x); REGISTER_DEMUXER(X,x)
//注册URLProtocol
//extern URLProtocol ff_##x##_protocol;
//在librtmp中,对应的就是ff_rtmp_protocol
//这样就把librtmp整合起来了
//由此可见URLProtocol的名字是固定的
#define REGISTER_PROTOCOL(X,x) { \
extern URLProtocol ff_##x##_protocol; \
if(CONFIG_##X##_PROTOCOL) ffurl_register_protocol(&ff_##x##_protocol, sizeof(ff_##x##_protocol)); }
//注册函数ffurl_register_protocol
void av_register_all(void)
{
static int initialized;

if (initialized)
return;
initialized = 1;
//注册所有的codec
avcodec_register_all();
//注册所有的MUXER(复用器和解复用器)
/* (de)muxers */
REGISTER_MUXER    (A64, a64);
REGISTER_DEMUXER  (AAC, aac);
REGISTER_MUXDEMUX (AC3, ac3);
REGISTER_DEMUXER  (ACT, act);
REGISTER_DEMUXER  (ADF, adf);


avcodec_register_all()

avcodec_register_all()注册了和编解码器有关的组件:硬件加速器,解码器,编码器,Parser,Bitstream Filter

avcodec_register()的源代码:

//注册所有的AVCodec  遍历链表并把当前的AVCodec加到链表的尾部。
void avcodec_register(AVCodec *codec)
{
AVCodec **p;
//初始化
avcodec_init();
//从第一个开始
p = &first_avcodec;
while (*p != NULL) p = &(*p)->next;
*p = codec;
codec->next = NULL;

if (codec->init_static_data)
codec->init_static_data(codec);
}


下面附上硬件加速器,编码器/解码器,parser,Bitstream Filter的注册代码。

硬件加速器注册函数是av_register_hwaccel()。

void av_register_hwaccel(AVHWAccel *hwaccel)
{
AVHWAccel **p = last_hwaccel;
hwaccel->next = NULL;
while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel))
p = &(*p)->next;
last_hwaccel = &hwaccel->next;
}


编解码器注册函数是avcodec_register()。

av_cold void avcodec_register(AVCodec *codec)
{
AVCodec **p;
avcodec_init();
p = last_avcodec;
codec->next = NULL;

while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec))
p = &(*p)->next;
last_avcodec = &codec->next;

if (codec->init_static_data)
codec->init_static_data(codec);
}


parser注册函数是av_register_codec_parser()。

void av_register_codec_parser(AVCodecParser *parser)
{
do {
parser->next = av_first_parser;
} while (parser->next != avpriv_atomic_ptr_cas((void * volatile *)&av_first_parser, parser->next, parser));
}


Bitstream Filter注册函数是av_register_bitstream_filter()。

void av_register_bitstream_filter(AVBitStreamFilter *bsf)
{
do {
bsf->next = first_bitstream_filter;
} while(bsf->next != avpriv_atomic_ptr_cas((void * volatile *)&first_bitstream_filter, bsf->next, bsf));
}


后两个函数中的avpriv_atomic_ptr_cas()定义如下。

void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
{
if (*ptr == oldval) {
*ptr = newval;
return oldval;
}
return *ptr;
}


图结:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: