1、命令行解析
1.1 命令行例子
-
命令行包括三个部分:输入参数,输出参数,和全局选项。
-
-i /home/ron/music/avm.mp4是输入参数,a.mp4是输出参数。输入/输出参数可以有专属的选项,这些选项应该紧挨着放在输入输出参数前面。如-vf “split main...main”就是输出参数a.mp4的选项。
-
全局选项的位置不需要限定,因为选项是以选项名字查找的。
-
可以有多组输入参数和多组输出参数。
1.2 解析命令行
split_commandline()负责解析命令行。
int split_commandline(OptionParseContext *octx, int argc, char *argv[], const OptionDef *options, const OptionGroupDef *groups, int nb_groups);
解析的结果保存在OptionParseContext中。解析时需要参考OptionDef和OptionGroupDef。OptonDef[]是支持ffmpeg的选项列表,OptionGroupDef[]是支持的组列表,包括输入类和输出类,前者以-i开头,加上设备名。后者只有文件名。
下面的类图显示了涉及的类:
-
OptionGroup保存一个输入(或输出)和它的选项列表。Option表示一个选项。
-
OptionParseContext中包括多个OptionGroup。全局选项保存在global_opts中。所有输入设备的选项保存在一个OptionGroupList实例中,所有输出设备的选项保存在另一个实例中。两者合起来组成数组groups.
1.3 split_commandline()
split_commandline()在一个循环中解析命令行,主要涉及如下函数。
函数 | 功能 |
---|---|
find_option() | 查询支持的option列表,检查当前元素是否一个option |
add_option() | 将option加入一个临时组。(因为option先于group出现,还不知道应该加入到哪个组。) |
match_group_separator() | 查询支持的group列表,检查当前元素是否是一个Group |
finish_group() | 设置临时组的参数,并用它填充OptionParseContext.groups(现在知道应该加入哪个组了) |
1.4 parse_optgroup()
parse_optgroup()负责将OptionGroup转换成OptionsContext。
int parse_optgroup(void *optctx, OptionGroup *g);
-
OptionGroup保存的选项值是字符串,而OptionsContext保存的值是由OptionDef定义的实际类型。parse_optgroup()的第一个参数optctx实际上是OptonsContext。
下面的类图显示了涉及的类:
-
SpecifierOpt保存实际类型的选项。OptionsContext有若干个SpecifierOpt数组的成员。每个specfier数组保存一类选项。如filters保存”filter”选项。但filter可以是”filter:v”,属于video,也可以是“filter:a”,属于audio。SpecifierOpt.s