AVInputFormat结构体
AVInputFormat 每种码流输入格式(例如h264,FLV, MKV, MP4, AVI)对应一个结构体,用来保存视音频的解码参数,目前以h264码流格式为例,描述结构体成员:
name:封装格式名称简写(short_name)[h264]
long_name:码流输入格式的长名称[raw H.264 video]
extensions:码流输入格式的扩展名[h26l,h264,264,avc]
raw_codec_id:码流输入格式ID[28]
read_packet:avformat-57.dll!0x000007fee101ca90 (加载符号以获取其他信息)
read_header:avformat-57.dll!0x000007fee101cb70 (加载符号以获取其他信息)
关键函数:int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
read_packet函数读取一个AVPacket,然后放在pkt,这个函数在进行分帧
av_read_frame函数的里面会被调用到,调用相应的解码器获取一帧的完整数据
问题:各种码流输入格式是什么时候被加载的?
回答:当第一次调用av_register_all的时候就会注册复用器,其中就包含了各种码流的输入格式的处理函数
查看调用关系
av_register_all
register_all
REGISTER_MUXDEMUX(H264, h264);
#define REGISTER_MUXDEMUX(X, x) REGISTER_MUXER(X, x); REGISTER_DEMUXER(X, x)
#define REGISTER_MUXER(X, x) \
{ \
extern AVOutputFormat ff_##x##_muxer; \
if (CONFIG_##X##_MUXER) \
av_register_output_format(&ff_##x##_muxer); \
}
#define REGISTER_DEMUXER(X, x) \
{ \
extern AVInputFormat ff_##x##_demuxer; \
if (CONFIG_##X##_DEMUXER) \
av_register_input_format(&ff_##x##_demuxer); \
}
看看注册码流输入格式的函数
void av_register_input_format(AVInputFormat *format)
{
AVInputFormat **p = last_iformat;
// Note, format could be added after the first 2 checks but that implies that *p is no longer NULL
while(p != &format->next && !format->next && avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
p = &(*p)->next;
if (!format->next)
last_iformat = &format->next;
}
其中关键的全局变量是
static AVInputFormat *first_iformat = NULL;
static AVInputFormat **last_iformat = &first_iformat;
保存了所有码流格式
AVInputFormat *av_iformat_next(const AVInputFormat *f)
{
if (f)
return f->next;
else
return first_iformat;
}
AVInputFormat *av_find_input_format(const char *short_name)
{
AVInputFormat *fmt = NULL;
while ((fmt = av_iformat_next(fmt)))//获取解码器的链表指针,
if (av_match_name(short_name, fmt->name))//根据输入的码流格式简写,轮询链表查找解码器
return fmt;
return NULL;
}
在avformat_open_input函数优化篇就直接指定码流的输入格式,从而减少了探测码流格式的时间
参考
http://blog.csdn.net/leixiaohua1020/article/details/12677129
AVInputFormat 每种码流输入格式(例如h264,FLV, MKV, MP4, AVI)对应一个结构体,用来保存视音频的解码参数,目前以h264码流格式为例,描述结构体成员:
name:封装格式名称简写(short_name)[h264]
long_name:码流输入格式的长名称[raw H.264 video]
extensions:码流输入格式的扩展名[h26l,h264,264,avc]
raw_codec_id:码流输入格式ID[28]
read_packet:avformat-57.dll!0x000007fee101ca90 (加载符号以获取其他信息)
read_header:avformat-57.dll!0x000007fee101cb70 (加载符号以获取其他信息)
关键函数:int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
read_packet函数读取一个AVPacket,然后放在pkt,这个函数在进行分帧
av_read_frame函数的里面会被调用到,调用相应的解码器获取一帧的完整数据
问题:各种码流输入格式是什么时候被加载的?
回答:当第一次调用av_register_all的时候就会注册复用器,其中就包含了各种码流的输入格式的处理函数
查看调用关系
av_register_all
register_all
REGISTER_MUXDEMUX(H264, h264);
#define REGISTER_MUXDEMUX(X, x) REGISTER_MUXER(X, x); REGISTER_DEMUXER(X, x)
#define REGISTER_MUXER(X, x) \
{ \
extern AVOutputFormat ff_##x##_muxer; \
if (CONFIG_##X##_MUXER) \
av_register_output_format(&ff_##x##_muxer); \
}
#define REGISTER_DEMUXER(X, x) \
{ \
extern AVInputFormat ff_##x##_demuxer; \
if (CONFIG_##X##_DEMUXER) \
av_register_input_format(&ff_##x##_demuxer); \
}
看看注册码流输入格式的函数
void av_register_input_format(AVInputFormat *format)
{
AVInputFormat **p = last_iformat;
// Note, format could be added after the first 2 checks but that implies that *p is no longer NULL
while(p != &format->next && !format->next && avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
p = &(*p)->next;
if (!format->next)
last_iformat = &format->next;
}
其中关键的全局变量是
static AVInputFormat *first_iformat = NULL;
static AVInputFormat **last_iformat = &first_iformat;
保存了所有码流格式
AVInputFormat *av_iformat_next(const AVInputFormat *f)
{
if (f)
return f->next;
else
return first_iformat;
}
AVInputFormat *av_find_input_format(const char *short_name)
{
AVInputFormat *fmt = NULL;
while ((fmt = av_iformat_next(fmt)))//获取解码器的链表指针,
if (av_match_name(short_name, fmt->name))//根据输入的码流格式简写,轮询链表查找解码器
return fmt;
return NULL;
}
在avformat_open_input函数优化篇就直接指定码流的输入格式,从而减少了探测码流格式的时间
参考
http://blog.csdn.net/leixiaohua1020/article/details/12677129
http://blog.csdn.net/neustar1/article/details/38231937
本文转自fengyuzaitu 51CTO博客,原文链接:http://blog.51cto.com/fengyuzaitu/1983060,如需转载请自行联系原作者