日期:2016.10.18
作者:isshe
github:github.com/isshe
邮箱:[email protected]
接下来打算学习一下编解码,不过好像很难的样子, 希望能看懂。
void av_register_all(void)
{
static int initialized;
if (initialized)
return;
//注册编解码器
avcodec_register_all();
/* (de)muxers */
//注册复用器
REGISTER_MUXER (A64, a64);
//注册解复用器
REGISTER_DEMUXER (AA, aa);
//两个同时注册
REGISTER_MUXDEMUX(AC3, ac3);
#define REGISTER_MUXER(X, x) \
{ \
extern AVOutputFormat ff_##x##_muxer; \
if (CONFIG_##X##_MUXER) \
av_register_output_format(&ff_##x##_muxer); \
}
//head of registered output format linked list
static AVOutputFormat *first_oformat = NULL;
static AVOutputFormat **last_oformat = &first_oformat;
void av_register_output_format(AVOutputFormat *format)
{
AVOutputFormat **p = last_oformat;
// Note, format could be added after the first 2 checks but that implies that *p is no longer NULL
//检查链表中有无指定的format,没有就加入。
//在前面两个条件成立后才把format连接到p链表中。
while(p != &format->next && !format->next && avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
p = &(*p)->next;
if (!format->next)
last_oformat = &format->next;
}
void avcodec_register_all(void)
{
static int initialized;
if (initialized)
return;
initialized = 1;
//硬件加速器
/* hardware accelerators */
REGISTER_HWACCEL(H263_CUVID, h263_cuvid);
//注意以下函数适用于视频和音频
//注册编码器
REGISTER_ENCODER(A64MULTI, a64multi);
//注册解码器
REGISTER_DECODER(AASC, aasc);
//两个同时注册
REGISTER_ENCDEC (ALIAS_PIX, alias_pix);
//注册分析器???不懂
REGISTER_PARSER(AAC, aac);
#define REGISTER_HWACCEL(X, x) \
{ \
extern AVHWAccel ff_##x##_hwaccel; \
if (CONFIG_##X##_HWACCEL) \
av_register_hwaccel(&ff_##x##_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;
}
#define REGISTER_ENCODER(X, x) \
{ \
extern AVCodec ff_##x##_encoder; \
if (CONFIG_##X##_ENCODER) \
avcodec_register(&ff_##x##_encoder); \
}
AVCodec ff_aac_encoder = {
.name = "aac",
.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
.type = AVMEDIA_TYPE_AUDIO,
.id = AV_CODEC_ID_AAC,
.priv_data_size = sizeof(AACEncContext),
.init = aac_encode_init, //初始化
.encode2 = aac_encode_frame, //编码函数
.close = aac_encode_end, //
.defaults = aac_encode_defaults,
.supported_samplerates = mpeg4audio_sample_rates,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
.priv_class = &aacenc_class,
};
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);
}
#define REGISTER_PARSER(X, x) \
{ \
extern AVCodecParser ff_##x##_parser; \
if (CONFIG_##X##_PARSER) \
av_register_codec_parser(&ff_##x##_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));
}