ffmpeg源码分析二:main函数和transcode函数 (转2)
原帖地址:http://blog.csdn.net/austinblog/article/details/24804455
首先从main函数看起,关键解释部分已加注释,该函数在ffmpeg.c文件中。代码如下:
int main(int argc, char **argv)
{
int ret;
int64_t ti;
// 注册清理回调函数
register_exit(ffmpeg_cleanup); setvbuf(stderr,NULL,_IONBF,); /* win32 runtime needs this */ av_log_set_flags(AV_LOG_SKIP_REPEATED);
parse_loglevel(argc, argv, options); if(argc> && !strcmp(argv[], "-d")){
run_as_daemon=;
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 < )
exit_program(); if (nb_output_files <= && nb_input_files == ) {
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();
} /* file converter / grab */
if (nb_output_files <= ) {
av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
exit_program();
} // 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() < )
exit_program();
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[], decode_error_stat[]);
if ((decode_error_stat[] + decode_error_stat[]) * max_error_rate < decode_error_stat[])
exit_program(); exit_program(received_nb_signals ? : main_return_code);
return main_return_code;
}
下面阅读transcode函数:
static int transcode(void)
{
int ret, i;
AVFormatContext *os;
OutputStream *ost;
InputStream *ist;
int64_t timer_start; // 初始化,打开所有输出流的编码器,打开所有输入流的解码器,写入所有输出文件的文件头。后面详细介绍。
ret = transcode_init();
if (ret < )
goto fail; if (stdin_interaction) {
av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
} timer_start = av_gettime(); #if HAVE_PTHREADS
if ((ret = init_input_threads()) < )
goto fail;
#endif // 循环,直到收到系统信号才退出 。
while (!received_sigterm) {
int64_t cur_time= av_gettime(); /* if 'q' pressed, exits */
if (stdin_interaction)
if (check_keyboard_interaction(cur_time) < )
break; /* check if there's any stream where output is still needed */
if (!need_output()) {
av_log(NULL, AV_LOG_VERBOSE, "No more output streams to write to, finishing.\n");
break;
} // 具体的转换工作,后面将详细介绍。
ret = transcode_step();
if (ret < ) {
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
continue; av_log(NULL, AV_LOG_ERROR, "Error while filtering.\n");
break;
} /* dump report by using the output first video and audio streams */
print_report(, timer_start, cur_time);
}
#if HAVE_PTHREADS
free_input_threads();
#endif // 文件处理完了,把缓冲中剩余的数据写到输出文件中。
/* at the end of stream, we must flush the decoder buffers */
for (i = ; i < nb_input_streams; i++) {
ist = input_streams[i];
if (!input_files[ist->file_index]->eof_reached && ist->decoding_needed) {
output_packet(ist, NULL);
}
}
flush_encoders(); term_exit(); /* write the trailer if needed and close file */
// 为输出文件写文件尾(有的不需要)。
for (i = ; i < nb_output_files; i++) {
os = output_files[i]->ctx;
av_write_trailer(os);
} /* dump report by using the first video and audio streams */
print_report(, timer_start, av_gettime()); // 关闭所有编码器。
/* close each encoder */
for (i = ; i < nb_output_streams; i++) {
ost = output_streams[i];
if (ost->encoding_needed) {
av_freep(&ost->st->codec->stats_in);
avcodec_close(ost->st->codec);
}
} // 关闭所有解码器。
/* close each decoder */
for (i = ; i < nb_input_streams; i++) {
ist = input_streams[i];
if (ist->decoding_needed) {
avcodec_close(ist->st->codec);
if (ist->hwaccel_uninit)
ist->hwaccel_uninit(ist->st->codec);
}
} /* finished ! */
ret = ; fail:
#if HAVE_PTHREADS
free_input_threads();
#endif if (output_streams) {
for (i = ; i < nb_output_streams; i++) {
ost = output_streams[i];
if (ost) {
if (ost->stream_copy)
av_freep(&ost->st->codec->extradata);
if (ost->logfile) {
fclose(ost->logfile);
ost->logfile = NULL;
}
av_freep(&ost->st->codec->subtitle_header);
av_freep(&ost->forced_kf_pts);
av_freep(&ost->apad);
av_dict_free(&ost->opts);
av_dict_free(&ost->swr_opts);
av_dict_free(&ost->resample_opts);
}
}
}
return ret;
}
ffmpeg源码分析二:main函数和transcode函数 (转2)的更多相关文章
- 最新版ffmpeg源码分析
最新版ffmpeg源码分析一:框架 (ffmpeg v0.9) 框架 最新版的ffmpeg中发现了一个新的东西:avconv,而且ffmpeg.c与avconv.c一个模样,一研究才发现是libav下 ...
- Vue源码分析(二) : Vue实例挂载
Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...
- 多线程之美8一 AbstractQueuedSynchronizer源码分析<二>
目录 AQS的源码分析 该篇主要分析AQS的ConditionObject,是AQS的内部类,实现等待通知机制. 1.条件队列 条件队列与AQS中的同步队列有所不同,结构图如下: 两者区别: 1.链表 ...
- Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题
4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...
- 框架-springmvc源码分析(二)
框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...
- Tomcat源码分析二:先看看Tomcat的整体架构
Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Conn ...
- 十、Spring之BeanFactory源码分析(二)
Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...
- external-attacher源码分析(1)-main方法与启动参数分析
更多 ceph-csi 其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 摘要 ceph-csi分析-external-attacher源码分析.external- ...
- SequoiaDB 系列之五 :源码分析之main函数
好久好久没有写博客了,因为一直要做各种事,工作上的,生活上的,这一下就是半年. 时光如梭. 这两天回头看了看写的博客,感觉都是贻笑大方. 但是还是想坚持把SequoiaDB系列写完. 初步的打算已经确 ...
随机推荐
- vc 实现一个 http Server
实现 http 的协议解析 以及封装 , 对应不同的访问地址, 调用绑定的处理程序 , #include "stdafx.h" #include "lyocomm\web ...
- WPF 绘制对齐像素的清晰显示的线条
此前有小伙伴询问我为何他 1 像素的线条显示发虚,然后我告诉他是“像素对齐”的问题,然而他设置了各种对齐像素的属性依旧没有作用.于是我对此进行了一系列试验,对 WPF 像素对齐的各种方法进行了一次总结 ...
- C#飞行棋游戏
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 用oradebug short_stack及strace -p分析oracle进程是否dead或出现故障
1,可以采用oradebug或者strace -p跟踪后台或前台进程是否dead或hang住2,如果进程出现故障,必会在对应的TRC文件写入最新信息,基于此可以获取非常重要的信息进一步分析与诊断 ...
- linux的mysql
mysql https://www.cnblogs.com/cnblogsfans/archive/2009/09/21/1570942.html https://blog.csdn.net/Smal ...
- 进程间通信IPC之--无名管道(pipe)和有名管道(fifo)(转)
进程间通信IPC之--无名管道(pipe)和有名管道(fifo) 2012-01-17 22:41:20 分类: C/C++ 每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中 ...
- 军哥 LNMP 常见问题
安装memcached出错: Install memcached...Notice: memcached-1.4.25.tar.gz not found!!!download now...--2016 ...
- vue的动画组件(transition)
当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理: 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名. v-enter: 定 ...
- cocos2d
http://www.jetbrains.com/webstorm/download/index.html 运行又有下面错误 Fatal signal 11 (SIGSEGV) at 0x000000 ...
- RK3288 USB触摸屏无法使用,需要添加PID和VID
RK3288 Android5.1 现象:USB 接口触摸屏插到板子上,触摸屏无法使用,有可能出现更奇葩的,同一套代码,有的板子可以用,有的板子不能用. 1.打开串口调试,插上触摸屏,读取触摸屏的 ...