avcodec_register_all 提供注册codec
parsers
filters
的功能。
avcodec_register_all 框架
avcodec_register_all
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void avcodec_register_all ( void )
{
static int initialized ;
if ( initialized )
return ;
initialized = 1 ;
/* hardwar accelerators */
REGISTER_HWACCEL ( H264_MMAL , h264_mmal );
......
/* video codecs */
REGISTER_DECODER ( HEVC , hevc );
......
REGISTER_ENCDEC ( MPEG4 , mpeg4 );
......
/* audio codecs */
REGISTER_ENCDEC ( AAC , aac );
......
/* parsers */
REGISTER_PARSER ( HEVC , hevc );
/* bitstream filters */
REGISTER_BSF ( HEVC_MP4TOANNEXB , hevc_mp4toannexb );
}
调用关系
从avcodec_register_all
的框架和调用关系图可以看出,该函数主要注册硬件加速器、codec、parsers、比特流过滤器等。
源码分析
注册一次
initialized_once
1
2
3
4
5
static int initialized ;
if ( initialized )
return ;
initialized = 1 ;
该段代码可以看出,当调用过该函数一次后,再次调用时,该函数直接返回。
注意,这种方法在 FFMEPG 源码中非常常见。
注册硬件加速器
REGISTER_HWACCEL
1
2
3
4
5
6
#define REGISTER_HWACCEL(X, x) \
{ \
extern AVHWAccel ff_##x##_hwaccel; \
if (CONFIG_##X##_HWACCEL) \
av_register_hwaccel(&ff_##x##_hwaccel); \
}
以H264
为例,REGISTER_HWACCEL(H264_MMAL, h264_mmal)
展开如下:
1
2
3
extern AVHWAccel ff_h264_mmal_hwaccel;
if(CONFIG_H264_MMAL_HWACCEL)
av_register_hwaccel(&ff_h264_mmal_hwaccel);
av_register_hwaccel(&ff_h264_mmal_hwaccel)
展开如下:
av_register_hwaccel
1
2
3
4
5
6
7
8
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 ;
}
注册codec
REGISTER_DECODER
1
2
3
4
5
6
#define REGISTER_DECODER(X, x) \
{ \
extern AVCodec ff_##x##_decoder; \
if (CONFIG_##X##_DECODER) \
avcodec_register(&ff_##x##_decoder); \
}
以HEVC
为例,REGISTER_DECODER(HEVC, hevc)
展开如下:
1
2
3
extern AVCodec ff_hevc_decoder;
if(CONFIG_HEVC_DECODER)
avcodec_register(&ff_hevc_decoder);
avcodec_register(&ff_hevc_decoder)
展开如下:
avcodec_register
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 );
}
ff_hevc_decoder 定义如下:
ff_hevc_decoder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
AVCodec ff_hevc_decoder = {
. name = "hevc" ,
. long_name = NULL_IF_CONFIG_SMALL ( "HEVC (High Efficiency Video Coding)" ),
. type = AVMEDIA_TYPE_VIDEO ,
. id = AV_CODEC_ID_HEVC ,
. priv_data_size = sizeof ( HEVCContext ),
. priv_class = & hevc_decoder_class ,
. init = hevc_decode_init ,
. close = hevc_decode_free ,
. decode = hevc_decode_frame ,
. flush = hevc_decode_flush ,
. update_thread_context = hevc_update_thread_context ,
. init_thread_copy = hevc_init_thread_copy ,
. capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS ,
. profiles = NULL_IF_CONFIG_SMALL ( profiles ),
};
注册parser
REGISTER_PARSER
1
2
3
4
5
6
#define REGISTER_PARSER(X, x) \
{ \
extern AVCodecParser ff_##x##_parser; \
if (CONFIG_##X##_PARSER) \
av_register_codec_parser(&ff_##x##_parser); \
}
以HEVC
为例,REGISTER_PARSER(HEVC, hevc)
展开如下:
1
2
3
extern AVCoderParser ff_hevc_parser;
if(CONFIG_HEVC_PARSER)
av_register_codec_parser(&ff_hevc_parser);
av_register_codec_parser(&ff_hevc_parser)
展开如下:
av_register_codec_parser
1
2
3
4
5
6
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 ));
}
ff_hevc_parser 定义如下:
ff_hevc_parser
1
2
3
4
5
6
7
AVCodecParser ff_hevc_parser = {
. codec_ids = { AV_CODEC_ID_HEVC },
. priv_data_size = sizeof ( HEVCParserContext ),
. parser_parse = hevc_parse ,
. parser_close = hevc_parser_close ,
. split = hevc_split ,
};
注册bitstream filters
REGISTER_BSF
1
2
3
4
5
6
#define REGISTER_BSF(X, x) \
{ \
extern AVBitStreamFilter ff_##x##_bsf; \
if (CONFIG_##X##_BSF) \
av_register_bitstream_filter(&ff_##x##_bsf); \
}
以HEVC
为例,REGISTER_BSF(HEVC_MP4TOANNEXB, hevc_mp4toannexb)
展开如下:
1
2
3
extern AVBitStreamFilter ff_hevc_mp4toannexb_bsf;
if(CONFIG_HEVC_MP4TOANNEXB_BSF)
av_register_bitstream_filter(&ff_hevc_mp4toannexb_bsf);
av_register_bitstream_filter(&&ff_hevc_mp4toannexb_bsf)
展开如下:
av_register_bitstream_filter
1
2
3
4
5
6
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 ));
}
ff_hevc_mp4toannexb_bsf 定义如下:
ff_hevc_mp4toannexb_bsf
1
2
3
4
5
6
AVBitStreamFilter ff_hevc_mp4toannexb_bsf = {
"hevc_mp4toannexb" ,
sizeof ( HEVCBSFContext ),
hevc_mp4toannexb_filter ,
hevc_mp4toannexb_close ,
};