ffmpeg 中 -f <format> 字段的意义
----------------------------------------
author: hjjdebug
date: 2022年 10月 23日 星期日
----------------------------------------
我见到过的-f force format
-f mpegts
-f decklink
-f x11grab
-f alsa
-f hls
当然还有很多...
这里有三个常见问题,
1. 这些format 到底是什么意思? 答: 是文件格式的意思.
2. 我怎么知道有多少种formats? 答: ffmpeg -formats 可以列出所有的formats, 它就是muxer,demuxer支持的格式总和.
3. 这些参数能省略吗? 答: 能.
对于输入,如果不指定-f, ffmpeg 会根据输入数据(来自于输入文件,或输入设备或其它协议)来判断数据的封装格式.
对于输出,如果不指定-f, ffmpeg 也可以通过输出文件名进行推导.
如果指定了-f 选项, 则-f 后跟的参数会被存储到
struct OptionsContext
{
...
const char *format;
...
}
以输入为例,该format 字符串, 打开文件的时候如果其不为空,会被用来查找对应的格式.
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);
}
}
查找对应格式之法: 也是判定格式字符串是否合法之法为枚举.
AVInputFormat *av_find_input_format(const char *short_name)
{
const AVInputFormat *fmt = NULL;
void *i = 0;
while ((fmt = av_demuxer_iterate(&i))) // 在所有的demuxer中枚举
if (av_match_name(short_name, fmt->name)) // 匹配上名字就可以了.
return (AVInputFormat*)fmt;
return NULL;
}
正确的format会返回一个file_iformat,这是一个AVInputFormat 结构,该指针会被传递给avformat_open_input,
输入文件格式file_iformat 会在avformat_open_input 时进一步判断,当发现还没有确定,会进行探测.
如果没有 -f 项, 则 avformat_open_input 的 file_iformat=0
err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
如果输入文件格式为空,需要探测文件格式
if(!format_opts)
file_iformat = av_probe_input_format2(&pd, 0, &score))
探测之法为枚举:
while ((fmt1 = av_demuxer_iterate(&i))) { // 在所有的demuxer 中枚举
score = 0;
if (fmt1->read_probe) { // 根据数据进行探测, 这需要下一层具体的fmt 根据实际数据判断
score = fmt1->read_probe(&lpd);
if (score)
av_log(NULL, AV_LOG_TRACE, "Probing %s score:%d size:%d\n", fmt1->name, score, lpd.buf_size);
}
}
这里保留下最高的得分即为探测到的格式.
所以,不管是判定格式字符串是否合法,还是根据数据自动查找格式,用到的方法都是枚举!