整体结构流程
核心逻辑
通过读源码发现核心的处理逻辑是av_guess_format函数,这里就根据核心逻辑来阅读,其余的基本是是在做判断和赋值
av_guess_format阅读分析
步骤1(先看头文件)
/**
* Return the output format in the list of registered output formats
* which best matches the provided parameters, or return NULL if
* there is no match.
*
* @param short_name if non-NULL checks if short_name matches with the
* names of the registered formats
* @param filename if non-NULL checks if filename terminates with the
* extensions of the registered formats
* @param mime_type if non-NULL checks if mime_type matches with the
* MIME type of the registered formats
*/
const AVOutputFormat *av_guess_format(const char *short_name,const char *filename,const char *mime_type);
说明
1.根据注释信息,此函数返回AVOutputFormat的指针,通过注册的 ”output formats“列表进行匹配,没有匹配上就返回NULL
2.思考:这里说的"注册列表"指的是啥?(下面做解释)
步骤2(看函数定义)
const AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
const char *mime_type)
{
const AVOutputFormat *fmt = NULL;
const AVOutputFormat *fmt_found = NULL;
void *i = 0;
int score_max, score;
/* specific test for image sequences */
#if CONFIG_IMAGE2_MUXER
if (!short_name && filename &&
av_filename_number_test(filename) &&
ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {
return av_guess_format("image2", NULL, NULL);
}
#endif
/* Find the proper file type. */
score_max = 0;
while ((fmt = av_muxer_iterate(&i))) {
score = 0;
if (fmt->name && short_name && av_match_name(short_name, fmt->name))
score += 100;
if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
score += 10;
if (filename && fmt->extensions &&
av_match_ext(filename, fmt->extensions)) {
score += 5;
}
if (score > score_max) {
score_max = score;
fmt_found = fmt;
}
}
return fmt_found;
}
从此函数中可以发现干活的核心处理函数是 “av_muxer_iterate”;从这个我们就可以大概猜测,此函数做了两件事情:
- 取出”注册列表“中的AVOutputFormat的指针.
- 对参数进行的值进行递增.
查看av_muxer_iterate函数定义
const AVOutputFormat *av_muxer_iterate(void **opaque)
{
static const uintptr_t size = sizeof(muxer_list)/sizeof(muxer_list[0]) - 1;
uintptr_t i = (uintptr_t)*opaque;
const AVOutputFormat *f = NULL;
uintptr_t tmp;
if (i < size) {
f = muxer_list[i];
} else if (tmp = atomic_load_explicit(&outdev_list_intptr, memory_order_relaxed)) {
const AVOutputFormat *const *outdev_list = (const AVOutputFormat *const *)tmp;
f = outdev_list[i - size];
}
if (f)
*opaque = (void*)(i + 1);
return f;
}
原来注册列表就是一个数组,里面存放的就是解析和封装不同”format“的指针,这是想看muxer_list里面是些什么?但是源码文件里面这个却没有找到就很奇怪,先埋个坑,后面找到什么原因在纪录。反正基础逻辑就是"注册列表"就是一个数组,至于这个数组什么时候出现,我猜测是在链接的时候指向的。