重要函数解析
- main()
- ffmpeg_parse_options()
- transcode()
main()
int main(int argc, char **argv)
{int ret;BenchmarkTimeStamps ti;/* 初始化动态加载 */init_dynload();/* 注册退出回调函数 */register_exit(ffmpeg_cleanup);/* 设置stderr的缓冲模式(win32运行时需要) */setvbuf(stderr, NULL, _IONBF, 0);/* 设置日志打印选项 */av_log_set_flags(AV_LOG_SKIP_REPEATED);parse_loglevel(argc, argv, options);#if CONFIG_AVDEVICE/* 注册音视频设备 */avdevice_register_all();
#endif/* 初始化网络模块 */avformat_network_init();/* 显示ffmpeg的banner信息 */show_banner(argc, argv, options);/* 解析命令行选项并打开所有的输入/输出文件 */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);}/* 检查是否至少指定一个输出文件 */if (nb_output_files <= 0) {av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");exit_program(1);}current_time = ti = get_benchmark_time_stamps();/* 文件转码或抓取 */if (transcode() < 0)exit_program(1);if (do_benchmark) {int64_t utime, stime, rtime;current_time = get_benchmark_time_stamps();utime = current_time.user_usec - ti.user_usec;stime = current_time.sys_usec - ti.sys_usec;rtime = current_time.real_usec - ti.real_usec;av_log(NULL, AV_LOG_INFO,"bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",utime / 1000000.0, stime / 1000000.0, rtime / 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 : main_return_code);return main_return_code;
}
下面是对每个步骤的功能的详细解释:
- 初始化动态加载。
- 调用init_dynload函数,用于初始化动态加载库的相关资源,以便在需要时加载需要的库。
- 注册退出回调函数。
- 调用register_exit函数,将ffmpeg_cleanup函数注册为在程序退出时被调用的回调函数。
- 设置stderr的缓冲模式。
- 调用setvbuf函数,将stderr的缓冲模式设置为无缓冲模式,以确保错误信息可以立即显示在终端上。
- 设置日志打印选项。
- 调用av_log_set_flags函数,设置日志打印选项。在这里设置
AV_LOG_SKIP_REPEATED选项,表示日志会跳过重复的消息。
- 调用av_log_set_flags函数,设置日志打印选项。在这里设置
- 解析命令行参数中的日志级别选项。
- 调用parse_loglevel函数,解析命令行参数中的日志级别选项,并将其应用到日志系统中。
- 注册音视频设备。
- 调用avdevice_register_all函数,用于注册所有的音视频设备。
- 初始化网络模块。
- 调用avformat_network_init函数,初始化网络模块,以便进行网络相关的操作,如打开网络流。
- 显示ffmpeg的banner信息。
- 调用show_banner函数,根据命令行参数、选项和程序信息,打印ffmpeg的banner信息。
- 解析命令行选项并打开所有的输入/输出文件。
- 调用ffmpeg_parse_options函数,解析命令行选项,并根据选项打开所有的输入/输出文件。
- 检查是否没有指定输出文件并且没有输入文件。
- 检查nb_output_files和nb_input_files的值。
- 若满足条件,则打印用法信息和警告,并终止程序。
- 检查是否至少指定一个输出文件。
- 检查nb_output_files的值。
- 若不满足条件,则打印致命错误信息,并终止程序。
- 进行文件转码或抓取。
- 调用transcode函数,进行文件转码或抓取。
- transcode函数返回值小于0表示出错,并通过调用exit_program函数终止程序。
- 如果启用了性能评测,输出性能数据。
- 如果do_benchmark为真,计算从开始到结束的用户时间、系统时间和真实时间,并打印出来。
- 打印解码帧数和解码错误数。
- 调用av_log函数,打印成功解码的帧数和解码错误数。
- 检查解码错误是否超过了指定的错误率。
- 检查解码错误数是否超过了最大错误率。
- 若满足条件,则通过调用exit_program终止程序。
- 根据是否接收到信号确定程序的返回码,并终止程序。
- 返回main_return_code作为main函数的返回值。
ffmpeg_parse_options()
// 解析命令行参数并设置选项
int ffmpeg_parse_options(int argc, char **argv)
{// 定义选项解析上下文和错误信息OptionParseContext octx;uint8_t error[128];int ret;memset(&octx, 0, sizeof(octx));/* split the commandline into an internal representation */// 将命令行参数拆分为内部表示形式ret = split_commandline(&octx, argc, argv, options, groups,FF_ARRAY_ELEMS(groups));if (ret < 0) {av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");goto fail;}/* apply global options */// 应用全局选项ret = parse_optgroup(NULL, &octx.global_opts);if (ret < 0) {av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");goto fail;}/* configure terminal and setup signal handlers */// 配置终端并设置信号处理程序term_init();/* open input files */// 打开输入文件ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);if (ret < 0) {av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");goto fail;}// 应用同步偏移量apply_sync_offsets();/* create the complex filtergraphs */// 创建复杂的滤波器图ret = init_complex_filters();if (ret < 0) {av_log(NULL, AV_LOG_FATAL, "Error initializing complex filters.\n");goto fail;}/* open output files */// 打开输出文件ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);if (ret < 0) {av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");goto fail;}// 检查滤波器的输出check_filter_outputs();fail:// 反初始化选项解析上下文uninit_parse_context(&octx);if (ret < 0) {// 如果有错误,将错误信息输出到日志av_strerror(ret, error, sizeof(error));av_log(NULL, AV_LOG_FATAL, "%s\n", error);}return ret;
}
函数功能:该函数用于解析命令行参数并进行相应处理,包括拆分命令行参数为内部表示形式、应用全局选项、配置终端和设置信号处理程序、打开输入文件、应用同步偏移量、创建复杂的滤波器图、打开输出文件、检查滤波器的输出。如果出现错误,会将错误信息输出到日志。