ffmpeg 之ffmpeg 整理流程分析
這個篇文檔主要對ffmpeg? 命令分析:主要分析ffmpeg 程序主要流程:
?1. 分析命令行函數,解析出輸入文件及輸出文件
?ffmpeg_parse_option?
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;}/* 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; }2.?transcode 轉碼處理
static int transcode(void) {int ret, i;AVFormatContext *os;OutputStream *ost;InputStream *ist;int64_t timer_start;int64_t total_packets_written = 0;ret = transcode_init(); // 轉碼初始化if (ret < 0)goto fail;if (stdin_interaction) {av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");}timer_start = av_gettime_relative();#if HAVE_THREADSif ((ret = init_input_threads()) < 0)goto fail; #endifwhile (!received_sigterm) {int64_t cur_time= av_gettime_relative();/* if 'q' pressed, exits */if (stdin_interaction)if (check_keyboard_interaction(cur_time) < 0)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 < 0 && ret != AVERROR_EOF) {av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));break;}/* dump report by using the output first video and audio streams */print_report(0, timer_start, cur_time);} #if HAVE_THREADSfree_input_threads(); #endif/* at the end of stream, we must flush the decoder buffers */for (i = 0; i < nb_input_streams; i++) {ist = input_streams[i];if (!input_files[ist->file_index]->eof_reached) {process_input_packet(ist, NULL, 0);}}flush_encoders();term_exit();/* write the trailer if needed and close file */for (i = 0; i < nb_output_files; i++) {os = output_files[i]->ctx;if (!output_files[i]->header_written) {av_log(NULL, AV_LOG_ERROR,"Nothing was written into output file %d (%s), because ""at least one of its streams received no packets.\n",i, os->url);continue;}if ((ret = av_write_trailer(os)) < 0) {av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", os->url, av_err2str(ret));if (exit_on_error)exit_program(1);}}/* dump report by using the first video and audio streams */print_report(1, timer_start, av_gettime_relative());/* close each encoder */for (i = 0; i < nb_output_streams; i++) {ost = output_streams[i];if (ost->encoding_needed) {av_freep(&ost->enc_ctx->stats_in);}total_packets_written += ost->packets_written;if (!ost->packets_written && (abort_on_flags & ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM)) {av_log(NULL, AV_LOG_FATAL, "Empty output on stream %d.\n", i);exit_program(1);}}if (!total_packets_written && (abort_on_flags & ABORT_ON_FLAG_EMPTY_OUTPUT)) {av_log(NULL, AV_LOG_FATAL, "Empty output\n");exit_program(1);}/* close each decoder */for (i = 0; i < nb_input_streams; i++) {ist = input_streams[i];if (ist->decoding_needed) {avcodec_close(ist->dec_ctx);if (ist->hwaccel_uninit)ist->hwaccel_uninit(ist->dec_ctx);}}hw_device_free_all();/* finished ! */ret = 0;fail: #if HAVE_THREADSfree_input_threads(); #endifif (output_streams) {for (i = 0; i < nb_output_streams; i++) {ost = output_streams[i];if (ost) {if (ost->logfile) {if (fclose(ost->logfile))av_log(NULL, AV_LOG_ERROR,"Error closing logfile, loss of information possible: %s\n",av_err2str(AVERROR(errno)));ost->logfile = NULL;}av_freep(&ost->forced_kf_pts);av_freep(&ost->apad);av_freep(&ost->disposition);av_dict_free(&ost->encoder_opts);av_dict_free(&ost->sws_dict);av_dict_free(&ost->swr_opts);av_dict_free(&ost->resample_opts);}}}return ret; }? 2.1? transcode_step? ? ?// 轉換流程。
? ? ? ? ? ? ? ?process_input
? ? ? ? ? ? ? ? ? ? ? process_input_packet
?3.?do_streamcopy
do_streamcopy
?? ?output_packet
?? ??? ?write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
?? ??? ??? ?av_interleaved_write_frame
?? ??? ??? ??? ?write_packets_common
?? ??? ??? ??? ??? ?write_packet(AVFormatContext *s, AVPacket *pkt)
?? ??? ??? ??? ??? ??? ?s->oformat->write_packet
?? ??? ??? ??? ??? ??? ??? ? AVOutputFormat *oformat; mux ?中函數:? ? ? ? ? ? ? ??
總結
以上是生活随笔為你收集整理的ffmpeg 之ffmpeg 整理流程分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++自学教程第一课——你好世界,我是柠
- 下一篇: Oracle 天数计算函数