最新版ffmpeg源码分析二:transcode()函数
还是先看一下主函数吧:(省略了很多无关大雅的代码)
int main(int argc, char **argv)
{
OptionsContext o = { 0 };
int64_t ti;
//与命令行分析有关的结构的初始化,下面不再罗嗦
reset_options(&o, 0);
//设置日志级别
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
#if CONFIG_AVFILTER
avfilter_register_all();
#endif
av_register_all();
//初始化网络,windows下需要
avformat_network_init();
show_banner();
term_init();
//分析命令行输入的参数们
parse_options(&o, argc, argv, options, opt_output_file);
//文件的转换就在此函数中发生
if (transcode(output_files, nb_output_files, input_files, nb_input_files)< 0)
exit_program(1);
exit_program(0);
return 0;
}
int main(int argc, char **argv)
{
OptionsContext o = { 0 };
int64_t ti;
//与命令行分析有关的结构的初始化,下面不再罗嗦
reset_options(&o, 0);
//设置日志级别
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
#if CONFIG_AVFILTER
avfilter_register_all();
#endif
av_register_all();
//初始化网络,windows下需要
avformat_network_init();
show_banner();
term_init();
//分析命令行输入的参数们
parse_options(&o, argc, argv, options, opt_output_file);
//文件的转换就在此函数中发生
if (transcode(output_files, nb_output_files, input_files, nb_input_files)< 0)
exit_program(1);
exit_program(0);
return 0;
}
下面是transcode()函数,转换就发生在它里面.不废话,看注释吧,应很详细了
static int transcode(
OutputFile *output_files,//输出文件数组
int nb_output_files,//输出文件的数量
InputFile *input_files,//输入文件数组
int nb_input_files)//输入文件的数量
{
int ret, i;
AVFormatContext *is, *os;
OutputStream *ost;
InputStream *ist;
uint8_t *no_packet;
int no_packet_count = 0;
int64_t timer_start;
int key;
if (!(no_packet = av_mallocz(nb_input_files)))
exit_program(1);
//设置编码参数,打开所有输出流的编码器,打开所有输入流的解码器,写入所有输出文件的文件头,于是准备好了
ret = transcode_init(output_files, nb_output_files, input_files,nb_input_files);
if (ret < 0)
goto fail;
if (!using_stdin){
av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
}
timer_start = av_gettime();
//循环,直到收到系统信号才退出
for (; received_sigterm == 0;)
{
int file_index, ist_index;
AVPacket pkt;
int64_t ipts_min;
double opts_min;
int64_t cur_time = av_gettime();
ipts_min = INT64_MAX;
opts_min = 1e100;
/* if 'q' pressed, exits */
if (!using_stdin)
{
//先查看用户按下了什么键,跟据键做出相应的反应
static int64_t last_time;
if (received_nb_signals)
break;
/* read_key() returns 0 on EOF */
if (cur_time - last_time >= 100000 && !run_as_daemon){
key = read_key();
last_time = cur_time;
}else{
<span> </span>.................................
}
/* select the stream that we must read now by looking at the
smallest output pts */
//下面这个循环的目的是找一个最小的输出pts(也就是离当前最近的)的输出流
file_index = -1;
for (i = 0; i < nb_output_streams; i++){
&nb
补充:移动开发 , Android ,