open_input_file函数是被open_files函数调用,在调用之前open_files函数将解析得到的输入相关参数存入到 OptionsContext o中,以ffmpeg -f v4l2 -i /dev/video0 test.mp4为例,其实就是-f v4l2 -i /dev/video0,
其中 -f v4l2通过parse_optgroup函数来解析,这里主要还是跟options中对f参数的定义相关的,会去根据这些定义来进行相关的操作(write_option函数),write_option部分代码,这里我们其实就是获取了一个v4l2转存了一下,需要注意的就是-f 定义中的 { .off = OFFSET(format) },其实就是格式了,这个会在后面的时候会用到
if (po->flags & OPT_STRING) { //
char *str;
str = av_strdup(arg);
av_freep(dst);
if (!str)
return AVERROR(ENOMEM);
*(char **)dst = str;
} else if (po->flags & OPT_BOOL || po->flags & OPT_INT) {
*(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
} else if (po->flags & OPT_INT64) {
*(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
} else if (po->flags & OPT_TIME) {
*(int64_t *)dst = parse_time_or_die(opt, arg, 1);
} else if (po->flags & OPT_FLOAT) {
*(float *)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
} else if (po->flags & OPT_DOUBLE) {
*(double *)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
} else if (po->u.func_arg) {
int ret = po->u.func_arg(optctx, opt, arg);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR,
"Failed to set value '%s' for option '%s': %s\n",
arg, opt, av_err2str(ret));
return ret;
}
}
if (po->flags & OPT_EXIT)
exit_program(0);
然后调用了真正的open_input_file函数 传入两个参数一个是上面的 o就是转存的数据,另一个就是g->arg 就是filename 这里就是/dev/video0,open_input_file函数相对复杂,定义在ffmpeg_opt.c中。open_input_file函数中有很多if判断,看起来就很迷糊,都是针对一些具体的参数用的,这里我是参考了别人的文章简单看了一下
//输入参数o里面存放着文件的对应参数,filename表示文件名
static int open_input_file(OptionsContext *o, const char *filename)
{
InputFile *f;//存放此文件的所有信息,之后会放到input_files中
AVFormatContext *ic;//每个文件对应一个这样的结构体
AVInputFormat *file_iformat = NULL;
int err, i, ret;
int64_t timestamp;
AVDictionary **opts;
AVDictionary *unused_opts = NULL;
AVDictionaryEntry *e = NULL;
int orig_nb_streams; // number of streams before avformat_find_stream_info
char * video_codec_name = NULL;
char * audio_codec_name = NULL;
char *subtitle_codec_name = NULL;
char * data_codec_name = NULL;
int scan_all_pmts_set = 0;
/*在options[]中对应“f”,指定输入文件的格式“-f”*/
if (o->format) {
if (!(file_iformat = av_find_input_format(o->format))) {
av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
exit_program(1);
}
}
//如果是管道输入文件名为“-”
if (!strcmp(filename, "-"))
filename = "pipe

本文深入分析ffmpeg中的open_input_file函数,该函数在open_files调用后,接收OptionsContext o和filename作为参数。首先,通过av_find_input_format查找输入格式,接着avformat_alloc_context分配上下文,并配置相关参数。然后,调用avformat_open_input打开输入,最后进行avformat_find_stream_info以获取流信息。整个过程涉及ffmpeg的内部机制和关键步骤。
最低0.47元/天 解锁文章
1666

被折叠的 条评论
为什么被折叠?



