---------------------------------------------------------------------------
author: hjjdebug
date: 上次修改时间 2022-06-10 11:24:39
description: ffmpeg 中 -c:v <codec_name> 与 -vcodec <codec_name> 的关系
---------------------------------------------------------------------------
ffmpeg 中 -c:v <codec_name> 与 -vcodec <codec_name> 的关系
跟踪代码:
ffmpeg -c:v h264_cuvid -i /opt/test/test1.ts -f null -
记住此argc 为8, argv[i] 为上面各输入项
int ffmpeg_parse_options(int argc, char **argv)
1. 在如下函数中将选项存储. 存储到opt_parse_ctx 中
OptionParseContext opt_parse_ctx;
ret = split_commandline(&opt_parse_ctx, argc, argv, options, groups, FF_ARRAY_ELEMS(groups))
{
while (optindex < argc)
{
const char *opt = argv[optindex++]; //枚举各opt
po = find_option(options, opt); //在options 表中查找?
if (po->name)
{ // normal options, 在options 表中定义的选项
add_opt(opt_parse_ctx, po, opt, arg); //opt 是命令行的选项,arg是命令行的参数. po 是找到的指针
continue;
}
/* AVOptions */
if (argv[optindex]) {
ret = opt_default(NULL, opt, argv[optindex]);
}
}
}
/* open input files */, 在此文件中使用, 选项在opt_parse_ctx.groups[GROUP_INFILE] 中
ret = open_files(&opt_parse_ctx.groups[GROUP_INFILE], "input", open_input_file);
OptionGroup *g = &l->groups[0]; //获取选项
OptionsContext octx;
init_options(&octx);
o.g = g;
ret = parse_optgroup(&octx, g); //分析选项,g 为输入,octx为输出
{
Option *o = &g->opts[i];
ret = write_option(octx, o->opt, o->key, o->val);
}
// write_option 完成后的结果
(gdb) p *octx->codec_names
$24 = {
specifier = 0x6d8ee0 "v",
u = {
str = 0x6d8f00 "h264_cuvid",
i = 7180032,
i64 = 7180032,
ui64 = 7180032,
f = 1.00613678e-38,
dbl = 3.5474071472408171e-317
}
}
以此参数来打开文件
ret = open_file(&octx, g->arg); // g->arg 是输入文件名
如果是-vcodec h264_cuvid
ret = write_option(octx, o->opt, o->key, o->val); //其write_option 将会是执行一个函数调用
{
if (po->u.func_arg) {
int ret = po->u.func_arg(octx, opt, arg);
}
此处func_arg 为定义的
static int opt_video_codec(void *optctx, const char *opt, const char *arg)
{
OptionsContext *o = optctx;
return parse_option(o, "codec:v", arg, options); //选项被改写为codec:v, arg 是h264_cuvid, :之前部分为选项.
}
int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options)
{
po = find_option(options, opt); // codec:v 与c:v 查到的选项是一致的.
ret = write_option(optctx, po, opt, arg); //这里会写到同一个位置
}
结论:
可见, -vcodec h264_cuvid 会被转写为 codec:v h264_cuvid, 然后再调用find_opton, write_option
而 -c:v h264_cuvid, 会直接查找到codec 项,写到codec ctx中.
所以说, 它们两个是一致的. 其中-vcodec 多走了一些路程.
同样 -c:a <codec_name> 与 -acodec <codec_name> 也是一样