ffmpeg 源码学习
-- 之ffmpeg命令行参数解析
大家通过git在安装好cygwin之后,下载源码到(cygwin)home目录,通过./configure ...... ,可以添加一堆参数选项,执行可以生成config.mk等编译使用的文件,通过命令对工程编译进行配置可以达到一些裁剪功能,去掉不需要的部分。然后make之后会生成fserver.exe ,ffmpeg.exe , ffprobe.exe , ffplayer.exe几个可以供用户使用的工具。
ffmpeg是一个命令行工具,主要将一个多媒体文件不同格式之间进行转换;ffserver是一个多媒体流服务器,主要用于实时广播;ffplay是一个小型的每天播放器,基于SDL和ffmpeg库生成;最后ffprobe是一个简单的流分析仪。
另外这些工具都支持哪些命令参数,怎么使用,这个网上搜索很方便。但是要整体搜集的话,有很好的方法。如:ffserver -help 就可以全部打印出来
$ ffserver.exe -h
ffserver version N-57325-gf94124c Copyright (c) 2000-2013 the FFmpeg developers
built on Oct 23 2013 02:17:58 with gcc 3.4.4 (GCC) (cygming special, gdc 0.12, using dmd 0.125)
configuration:
libavutil 52. 47.101 / 52. 47.101
libavcodec 55. 37.102 / 55. 37.102
libavformat 55. 19.103 / 55. 19.103
libavdevice 55. 4.100 / 55. 4.100
libavfilter 3. 89.100 / 3. 89.100
libswscale 2. 5.101 / 2. 5.101
libswresample 0. 17.104 / 0. 17.104
usage: ffserver [options]
Hyper fast multi format Audio/Video streaming server
Main options:
-L show license
-h topic show help
-? topic show help
-help topic show help
--help topic show help
-version show version
-formats show available formats
-codecs show available codecs
-decoders show available decoders
-encoders show available encoders
-bsfs show available bit stream filters
-protocols show available protocols
-filters show available filters
-pix_fmts show available pixel formats
-layouts show standard channel layouts
-sample_fmts show available audio sample formats
-loglevel loglevel set logging level
-v loglevel set logging level
-report generate a report
-max_alloc bytes set maximum size of a single allocated block
-cpuflags flags force specific cpu flags
-n enable no-launch mode
-d enable debug mode
-f configfile use configfile instead of /etc/ffserver.conf
想ffmpeg就可以支持的选项特别多,可以ffmpeg -help > ffmpeg_option.txt重定向到一个文件里,然后可以自己慢慢研究。
顺便说明一下,该组织提供几个供开发者使用的静态库:
1.libavformat用于各种音视频格式的封装和解析,获取解码需要的信息以生成上下文结构读取音视频帧的功能;
2.libavcodec用于各种类型声音/图像的编解码;
3.libavutil公共模块提供一些公共工具函数;
4.libswscale用于视频场景比例缩放,色彩映射转换等等;
5.libpostproc用于后期效果处理
ffmpeg的命令参数如下:
1.获取视频的信息
ffmpeg -i video.avi
2.将图片序列合成视频
ffmpeg -f image2 -i image%d.jpg video.mpg
上面的命令会把当前目录下的图片(名字如:image1.jpg. image2.jpg. 等...)合并成video.mpg
3.将视频分解成图片序列
ffmpeg -i video.mpg image%d.jpg
上面的命令会生成image1.jpg. image2.jpg. ...
支持的图片格式有:PGM. PPM. PAM. PGMYUV. JPEG. GIF. PNG. TIFF. SGI
详细可以参考官网: http://ffmpeg.org/ffmpeg.html
这里就详细了解一下我们在使用ffmpeg工具时,传入的参数是如何透传下去的。
ffmpeg的命令行语法规则:
ffmpeg [ global_options
] {[ input_file_options
] -i ‘ input_file
’} ... {[ output_file_options
] ‘ output_file
’} ...
在ffmpeg.c 文件中,我们可以从main()中,
int main(int argc, char **argv)
{
int ret;
int64_t ti;
register_exit(ffmpeg_cleanup);
setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
av_log_set_flags(AV_LOG_SKIP_REPEATED);
parse_loglevel(argc, argv, options);
if(argc>1 && !strcmp(argv[1], "-d")){
run_as_daemon=1;
av_log_set_callback(log_callback_null);
argc--;
argv++;
}
avcodec_register_all();
#if CONFIG_AVDEVICE
avdevice_register_all();
#endif
avfilter_register_all();
av_register_all();
avformat_network_init();
show_banner(argc, argv, options);
term_init();
/* parse options and open all input/output files */
ret = ffmpeg_parse_options(argc, argv);
if (ret < 0)
exit_program(1);
if (nb_output_files <= 0 && nb_input_files == 0) {
show_usage();
av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
exit_program(1);
}
/* file converter / grab */
if (nb_output_files <= 0) {
av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
exit_program(1);
}
// if (nb_input_files == 0) {
// av_log(NULL, AV_LOG_FATAL, "At least one input file must be specified\n");
// exit_program(1);
// }
current_time = ti = getutime();
if (transcode() < 0)
exit_program(1);
ti = getutime() - ti;
if (do_benchmark) {
printf("bench: utime=%0.3fs\n", ti / 1000000.0);
}
av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n",
decode_error_stat[0], decode_error_stat[1]);
if ((decode_error_stat[0] + decode_error_stat[1]) * max_error_rate < decode_error_stat[1])
exit_program(69);
exit_program(received_nb_signals ? 255 : 0);
return 0;
}
可以看到,主要做了三件事:(1)注册各类(de)muxer , (de)codec , portocol 等;(2)ffmpeg_parse_options解析解析输入的参数项并打开输入输出文件;(3)transcode()函数开始文件格式转换
本篇主要看ffmpeg_parse_options,其在ffmpeg_opt.c文件中定义
(1)从命令参数参数里面分成三个部分,全局选项
参数 , 输入文件及其选项,输出文件及其选项;
(2)ffmpeg_parse_options也主要按照参数的语法规则来,逐步操作;
(3)分解命令行参数split_commandline
(4)解析全局的参数parse_optgroup
(5)open_files打开输入,输出文件;
(6)ffmpeg_opt.c文件中全局变量options包含所有命令及其关联的操作符,详看OptionDef结构体
关于ffmpeg和其他模块的关系,下次整理。