原帖地址:http://blog.csdn.net/austinblog/article/details/24804455

首先从main函数看起,关键解释部分已加注释,该函数在ffmpeg.c文件中。代码如下:

  1. int main(int argc, char **argv)
  2. {
  3. int ret;
  4. int64_t ti;
  5. // 注册清理回调函数
  6. register_exit(ffmpeg_cleanup);
  7.  
  8. setvbuf(stderr,NULL,_IONBF,); /* win32 runtime needs this */
  9.  
  10. av_log_set_flags(AV_LOG_SKIP_REPEATED);
  11. parse_loglevel(argc, argv, options);
  12.  
  13. if(argc> && !strcmp(argv[], "-d")){
  14. run_as_daemon=;
  15. av_log_set_callback(log_callback_null);
  16. argc--;
  17. argv++;
  18. }
  19.  
  20. // 注册组件们
  21. avcodec_register_all();
  22. #if CONFIG_AVDEVICE
  23. avdevice_register_all();
  24. #endif
  25. avfilter_register_all();
  26. av_register_all();
  27. avformat_network_init();
  28.  
  29. show_banner(argc, argv, options);
  30.  
  31. term_init();
  32.  
  33. /* parse options and open all input/output files */
  34. // 解析参数,并且打开输入输出文件
  35. ret = ffmpeg_parse_options(argc, argv);
  36. if (ret < )
  37. exit_program();
  38.  
  39. if (nb_output_files <= && nb_input_files == ) {
  40. show_usage();
  41. av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
  42. exit_program();
  43. }
  44.  
  45. /* file converter / grab */
  46. if (nb_output_files <= ) {
  47. av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
  48. exit_program();
  49. }
  50.  
  51. // if (nb_input_files == 0) {
  52. // av_log(NULL, AV_LOG_FATAL, "At least one input file must be specified\n");
  53. // exit_program(1);
  54. // }
  55.  
  56. current_time = ti = getutime();
  57. // 音视频转换函数
  58. if (transcode() < )
  59. exit_program();
  60. ti = getutime() - ti;
  61. if (do_benchmark) {
  62. printf("bench: utime=%0.3fs\n", ti / 1000000.0);
  63. }
  64. av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n",
  65. decode_error_stat[], decode_error_stat[]);
  66. if ((decode_error_stat[] + decode_error_stat[]) * max_error_rate < decode_error_stat[])
  67. exit_program();
  68.  
  69. exit_program(received_nb_signals ? : main_return_code);
  70. return main_return_code;
  71. }

下面阅读transcode函数:

  1. static int transcode(void)
  2. {
  3. int ret, i;
  4. AVFormatContext *os;
  5. OutputStream *ost;
  6. InputStream *ist;
  7. int64_t timer_start;
  8.  
  9. // 初始化,打开所有输出流的编码器,打开所有输入流的解码器,写入所有输出文件的文件头。后面详细介绍。
  10. ret = transcode_init();
  11. if (ret < )
  12. goto fail;
  13.  
  14. if (stdin_interaction) {
  15. av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
  16. }
  17.  
  18. timer_start = av_gettime();
  19.  
  20. #if HAVE_PTHREADS
  21. if ((ret = init_input_threads()) < )
  22. goto fail;
  23. #endif
  24.  
  25. // 循环,直到收到系统信号才退出 。
  26. while (!received_sigterm) {
  27. int64_t cur_time= av_gettime();
  28.  
  29. /* if 'q' pressed, exits */
  30. if (stdin_interaction)
  31. if (check_keyboard_interaction(cur_time) < )
  32. break;
  33.  
  34. /* check if there's any stream where output is still needed */
  35. if (!need_output()) {
  36. av_log(NULL, AV_LOG_VERBOSE, "No more output streams to write to, finishing.\n");
  37. break;
  38. }
  39.  
  40. // 具体的转换工作,后面将详细介绍。
  41. ret = transcode_step();
  42. if (ret < ) {
  43. if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
  44. continue;
  45.  
  46. av_log(NULL, AV_LOG_ERROR, "Error while filtering.\n");
  47. break;
  48. }
  49.  
  50. /* dump report by using the output first video and audio streams */
  51. print_report(, timer_start, cur_time);
  52. }
  53. #if HAVE_PTHREADS
  54. free_input_threads();
  55. #endif
  56.  
  57. // 文件处理完了,把缓冲中剩余的数据写到输出文件中。
  58. /* at the end of stream, we must flush the decoder buffers */
  59. for (i = ; i < nb_input_streams; i++) {
  60. ist = input_streams[i];
  61. if (!input_files[ist->file_index]->eof_reached && ist->decoding_needed) {
  62. output_packet(ist, NULL);
  63. }
  64. }
  65. flush_encoders();
  66.  
  67. term_exit();
  68.  
  69. /* write the trailer if needed and close file */
  70. // 为输出文件写文件尾(有的不需要)。
  71. for (i = ; i < nb_output_files; i++) {
  72. os = output_files[i]->ctx;
  73. av_write_trailer(os);
  74. }
  75.  
  76. /* dump report by using the first video and audio streams */
  77. print_report(, timer_start, av_gettime());
  78.  
  79. // 关闭所有编码器。
  80. /* close each encoder */
  81. for (i = ; i < nb_output_streams; i++) {
  82. ost = output_streams[i];
  83. if (ost->encoding_needed) {
  84. av_freep(&ost->st->codec->stats_in);
  85. avcodec_close(ost->st->codec);
  86. }
  87. }
  88.  
  89. // 关闭所有解码器。
  90. /* close each decoder */
  91. for (i = ; i < nb_input_streams; i++) {
  92. ist = input_streams[i];
  93. if (ist->decoding_needed) {
  94. avcodec_close(ist->st->codec);
  95. if (ist->hwaccel_uninit)
  96. ist->hwaccel_uninit(ist->st->codec);
  97. }
  98. }
  99.  
  100. /* finished ! */
  101. ret = ;
  102.  
  103. fail:
  104. #if HAVE_PTHREADS
  105. free_input_threads();
  106. #endif
  107.  
  108. if (output_streams) {
  109. for (i = ; i < nb_output_streams; i++) {
  110. ost = output_streams[i];
  111. if (ost) {
  112. if (ost->stream_copy)
  113. av_freep(&ost->st->codec->extradata);
  114. if (ost->logfile) {
  115. fclose(ost->logfile);
  116. ost->logfile = NULL;
  117. }
  118. av_freep(&ost->st->codec->subtitle_header);
  119. av_freep(&ost->forced_kf_pts);
  120. av_freep(&ost->apad);
  121. av_dict_free(&ost->opts);
  122. av_dict_free(&ost->swr_opts);
  123. av_dict_free(&ost->resample_opts);
  124. }
  125. }
  126. }
  127. return ret;
  128. }

ffmpeg源码分析二:main函数和transcode函数 (转2)的更多相关文章

  1. 最新版ffmpeg源码分析

    最新版ffmpeg源码分析一:框架 (ffmpeg v0.9) 框架 最新版的ffmpeg中发现了一个新的东西:avconv,而且ffmpeg.c与avconv.c一个模样,一研究才发现是libav下 ...

  2. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  3. 多线程之美8一 AbstractQueuedSynchronizer源码分析<二>

    目录 AQS的源码分析 该篇主要分析AQS的ConditionObject,是AQS的内部类,实现等待通知机制. 1.条件队列 条件队列与AQS中的同步队列有所不同,结构图如下: 两者区别: 1.链表 ...

  4. Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题

    4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...

  5. 框架-springmvc源码分析(二)

    框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...

  6. Tomcat源码分析二:先看看Tomcat的整体架构

    Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Conn ...

  7. 十、Spring之BeanFactory源码分析(二)

    Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...

  8. external-attacher源码分析(1)-main方法与启动参数分析

    更多 ceph-csi 其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 摘要 ceph-csi分析-external-attacher源码分析.external- ...

  9. SequoiaDB 系列之五 :源码分析之main函数

    好久好久没有写博客了,因为一直要做各种事,工作上的,生活上的,这一下就是半年. 时光如梭. 这两天回头看了看写的博客,感觉都是贻笑大方. 但是还是想坚持把SequoiaDB系列写完. 初步的打算已经确 ...

随机推荐

  1. 神器如 dnSpy,无需源码也能修改 .NET 程序

    dnSpy 是 0xd4d 开发的 .NET 程序调试神器. 说它是神器真的毫不为过!它能在完全没有源码的情况下即时调试程序,甚至还能修改程序!本文讲向大家介绍如何使用 dnSpy 修改 .NET 程 ...

  2. Web API的发布问题

    配置“ISAPI 和 CGI 限制”的4.0版本设置为允许,要不然出现“由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面.”的错误. “An error has ...

  3. [LOJ6261]一个人的高三楼

    loj description 给你一个长度为\(n\)的数列\(a_i\),求它的\(k\)次前缀和模\(998244353\).(就是做\(k\)次前缀和后的数列) \(n\le10^5,k\le ...

  4. 解决js代码中加入alert()就成功执行,不加就不对的问题!

    问题: jquery中的$(document).ready(function(){})中调用两个方法(1)利用ajax请求去后台查图书类别的方法(2)当页面上利用图书类别去查询图书返回页面,让图书类别 ...

  5. 基于spring的异常一站式解决方案

    https://segmentfault.com/a/1190000006749441#articleHeader4 https://lrwinx.github.io/2016/04/28/%E5%A ...

  6. js的delegate回调例子

    暂时没发现有具体的实际用处,先记录下 <!DOCTYPE html> <html> <head lang="en"> <meta char ...

  7. Oracle拆分字符串函数与执行调用

    本函数可以将“目标字符串”以“指定字符串”进行拆分,并通过表结构返回结果.代码如下: ); CREATE OR REPLACE FUNCTION splitstr(p_string IN VARCHA ...

  8. linux tcp server demo

    #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <ne ...

  9. Java报错 -- The public type c must be defined in its own file

    出现The public type c must be defined in its own file这个问题,是由于定义的JAVA类同文件名不一致 你的文件里很可能有两个 public 的类,而Ja ...

  10. mysql 下字符集知识汇总

    Do not issue the query set names with Connector/J, as the driver will not detect that the character ...