FFMPEG源码之ffmpeg.c解析

重要函数解析

  • 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;
}

下面是对每个步骤的功能的详细解释:

  1. 初始化动态加载。
    • 调用init_dynload函数,用于初始化动态加载库的相关资源,以便在需要时加载需要的库。
  2. 注册退出回调函数。
    • 调用register_exit函数,将ffmpeg_cleanup函数注册为在程序退出时被调用的回调函数。
  3. 设置stderr的缓冲模式。
    • 调用setvbuf函数,将stderr的缓冲模式设置为无缓冲模式,以确保错误信息可以立即显示在终端上。
  4. 设置日志打印选项。
    • 调用av_log_set_flags函数,设置日志打印选项。在这里设置
      AV_LOG_SKIP_REPEATED选项,表示日志会跳过重复的消息。
  5. 解析命令行参数中的日志级别选项。
    • 调用parse_loglevel函数,解析命令行参数中的日志级别选项,并将其应用到日志系统中。
  6. 注册音视频设备。
    • 调用avdevice_register_all函数,用于注册所有的音视频设备。
  7. 初始化网络模块。
    • 调用avformat_network_init函数,初始化网络模块,以便进行网络相关的操作,如打开网络流。
  8. 显示ffmpeg的banner信息。
    • 调用show_banner函数,根据命令行参数、选项和程序信息,打印ffmpeg的banner信息。
  9. 解析命令行选项并打开所有的输入/输出文件。
    • 调用ffmpeg_parse_options函数,解析命令行选项,并根据选项打开所有的输入/输出文件。
  10. 检查是否没有指定输出文件并且没有输入文件。
    • 检查nb_output_files和nb_input_files的值。
    • 若满足条件,则打印用法信息和警告,并终止程序。
  11. 检查是否至少指定一个输出文件。
    • 检查nb_output_files的值。
    • 若不满足条件,则打印致命错误信息,并终止程序。
  12. 进行文件转码或抓取。
    • 调用transcode函数,进行文件转码或抓取。
    • transcode函数返回值小于0表示出错,并通过调用exit_program函数终止程序。
  13. 如果启用了性能评测,输出性能数据。
    • 如果do_benchmark为真,计算从开始到结束的用户时间、系统时间和真实时间,并打印出来。
  14. 打印解码帧数和解码错误数。
    • 调用av_log函数,打印成功解码的帧数和解码错误数。
  15. 检查解码错误是否超过了指定的错误率。
    • 检查解码错误数是否超过了最大错误率。
    • 若满足条件,则通过调用exit_program终止程序。
  16. 根据是否接收到信号确定程序的返回码,并终止程序。
  17. 返回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;
}

函数功能:该函数用于解析命令行参数并进行相应处理,包括拆分命令行参数为内部表示形式、应用全局选项、配置终端和设置信号处理程序、打开输入文件、应用同步偏移量、创建复杂的滤波器图、打开输出文件、检查滤波器的输出。如果出现错误,会将错误信息输出到日志。


transcode()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/7922.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【运动规划算法项目实战】TABV代码解析(五):plan_manage

文章目录 前言一、FastPlannerManager.h1.1 成员变量:二、KinoReplanFSM.h2.1 成员变量2.2 方法三、plan_container.hpp3.1 成员变量:3.2 实现方法:四、backward.hpp五、fast_planner_node.cpp六、kino_replan_fsm.cpp七、planner_manager.cpp八、traj_server.cpp九、总结前言…

nlp系列(6)文本实体识别(Bi-LSTM+CRF)pytorch

模型介绍 LSTM&#xff1a;长短期记忆网络&#xff08;Long-short-term-memory&#xff09;,能够记住长句子的前后信息&#xff0c;解决了RNN的问题&#xff08;时间间隔较大时&#xff0c;网络对前面的信息会遗忘&#xff0c;从而出现梯度消失问题&#xff0c;会形成长期依赖…

Elasticsearch 一段时间后出现 SocketTimeoutException的问题

java springboot 使用ES客户端连接 一段时间闲置后&#xff0c;首次调用es命令会报SocketTimeOutException问题&#xff0c;再次调用不会报错 问题出现原因&#xff1a; Elasticsearch 客户端会根据服务器返回的HTTP报文内容&#xff0c;来决定客户端保持HTTP连接Keep-Alive…

开源项目注意事项

fork项目后&#xff0c;记得另外开启一个分支然后在新分支上进行开发&#xff0c;push到仓库后从分支往原项目提交。 否则会出现Partially verified&#xff08;导致提交pr后auto-merge失败&#xff09; 注意git提交操作 https://blog.csdn.net/sonichenn/article/details/13…

flask中的werkzeug介绍

flask中的werkzeug Werkzeug是一个Python库&#xff0c;用于开发Web应用程序。它是一个WSGI&#xff08;Web Server Gateway Interface&#xff09;工具包&#xff0c;提供了一系列实用功能来帮助开发者处理HTTP请求、响应、URLs等等。Werkzeug的设计非常灵活&#xff0c;可以…

请问学JavaScript 前要学html 和css 吗?

前言 html和css可以理解为是一个网站的骨架和皮肤&#xff0c;这两部分做好后整个网站的外观展示的完成度基本就有了个90%左右&#xff0c;所以在学习js前是需要学习html和css 的&#xff0c;这两部分不用花特别多的时间&#xff08;虽然css如果想做一些非常炫酷的效果个人认为…

vue中重新获取数据导致页面加长,要求在页面更新之后浏览器滚动条滚动到之前浏览记录的位置。以及获取当前页面中是哪个元素产生滚动条的方法。

目前的页面样式为&#xff1a; 代码是&#xff1a; <section id"detailSection"><el-tableref"multipleTable":data"logDetailList"style"width: 650px;margin:20px auto;"id"dialogDetail":show-header"fals…

App测试流程及测试点

1 APP测试基本流程 1.1流程图 1.2测试周期 测试周期可按项目的开发周期来确定测试时间&#xff0c;一般测试时间为两三周&#xff08;即15个工作日&#xff09;&#xff0c;根据项目情况以及版本质量可适当缩短或延长测试时间。正式测试前先向主管确认项目排期。 1.3测试资源…

启动es容器错误

说明&#xff1a;启动es容器&#xff0c;刚启动就停止&#xff0c;查看日志&#xff0c;出现以下错误信息&#xff08;java.lang.IllegalArgumentException: Plugin [analysis-ik] was built for Elasticsearch version 8.8.2 but version 7.12.1 is running&#xff09; 解决&…

【2023】HashMap详细源码分析解读

前言 在弄清楚HashMap之前先介绍一下使用到的数据结构&#xff0c;在jdk1.8之后HashMap中为了优化效率加入了红黑树这种数据结构。 树 在计算机科学中&#xff0c;树&#xff08;英语&#xff1a;tree&#xff09;是一种抽象数据类型&#xff08;ADT&#xff09;或是实作这种…

【洛谷】P4414 [COCI2006-2007#2] ABC

[COCI2006-2007#2] ABC 题面翻译 【题目描述】 三个整数分别为 A , B , C A,B,C A,B,C。这三个数字不会按照这样的顺序给你&#xff0c;但它们始终满足条件&#xff1a; A < B < C A < B < C A<B<C。为了看起来更加简洁明了&#xff0c;我们希望你可以按…

MySQL学习笔记 ------ 分组查询

#进阶5&#xff1a;分组查询 /* 语法&#xff1a; select 分组函数&#xff0c;列&#xff08;要求出现在group by的后面&#xff09; from 表 【where 筛选条件】 group by 分组的列表 【order by 排序的字段】; 注意&#xff1a;查询列表必须特殊&#xff0c;要求是分组函…

ChatGPT在智能电子设备中的应用如何?

ChatGPT在智能电子设备中有着广泛的应用潜力&#xff0c;可以为电子设备提供更智能、更个性化的用户体验&#xff0c;并为用户提供更多便利和高效的功能和服务。智能电子设备是指通过集成计算机、传感器、网络和人工智能等技术&#xff0c;实现智能化的功能和交互的设备。ChatG…

【C#】Lock关键字

一、概述 Lock关键字&#xff0c;确保当一个线程位于代码的临界区时&#xff0c;另一个线程不进入临界区。如果其他线程试图进入锁定的代码&#xff0c;则它将一直等待&#xff08;即被阻止&#xff09;&#xff0c;直到该对象被释放。 Lock关键字属于语法糖&#xff0c;其本…

数据结构【栈和队列】

第三章 栈与队列 一、栈 1.定义&#xff1a;只允许一端进行插入和删除的线性表&#xff0c;结构与手枪的弹夹差不多&#xff0c;可以作为实现递归函数&#xff08;调用和返回都是后进先出&#xff09;调用的一种数据结构&#xff1b; 栈顶&#xff1a;允许插入删除的那端&…

网络知识点之-BGP协议

边界网关协议&#xff08;BGP&#xff09;是运行于 TCP 上的一种自治系统的路由协议。 BGP 是唯一一个用来处理像因特网大小的网络的协议&#xff0c;也是唯一能够妥善处理好不相关路由域间的多路连接的协议。 BGP 构建在 EGP 的经验之上。 BGP 系统的主要功能是和其他的 BGP 系…

How to Use your mac to Read a Word and Repeat it more times

Using the say Command on a Mac 在 Mac 上使用 say 命令 The say command is a fun and useful feature on Mac computers that allows you to convert text to speech using the command line. With this command, you can make your Mac speak anything you type after it…

特征选择策略:为检测乳腺癌生物标志物寻找新出口

内容一览&#xff1a;microRNA&#xff08;小分子核糖核酸&#xff09;是一类短小的单链非编码 RNA 转录体。这些分子在多种恶性肿瘤中呈现失控性生长&#xff0c;因此近年来被诸多研究确定为确诊癌症的可靠的生物标志物 (biomarker)。在多种病理分析中&#xff0c;差异表达分析…

vue3下的uniapp跨域踩坑

uniapp vue3 H5跨域踩坑 开发移动端H5的时候由于后端接口没有做跨域处理&#xff0c;因此需要做下服务器代理&#xff0c;于是百度搜索了uniapp下h5的跨域配置 在manifest下的h5配置proxy&#xff0c;大概是这样: "h5": {"devServer": {"https"…

安全—01day

文章目录 1. 编码1.1 ASCLL编码1.2 URL编码1.3 Unicode编码1.4 HTML编码1.5 Base64编码 2. form表单2.1 php接收form表单2.2 python接收form表单 1. 编码 1.1 ASCLL编码 ASCII 是基于拉丁字母的一套电脑编码系统&#xff0c;主要用于显示现代英语和其他西欧语言。它是最通用的…