ffmpeg学习日记11-使用ffmpeg将视频格式转换为视频编码h264格式

ffmpeg学习日记11-使用ffmpeg将视频格式转换为视频编码h264格式 前言 将一种视频格式,例如mp4的视频,转换成对饮的视频编码h264格式的文件,实现功能的

ffmpeg学习日记11-使用ffmpeg将视频格式转换为视频编码h264格式

前言

将一种视频格式,例如mp4的视频,转换成对饮的视频编码h264格式的文件,实现功能的方式有两种,一种是调用ffmpeg工具,通过命令行进行转换,另一种是通过调用ffmpeg的函数,自己写代码进行转换,我们现在的要用第二种实现来完成这个功能。

ffmpeg工具源码分析

ffmpeg源码版本:4.1
通过全文检索,确定生成ffmpeg工具的Makefile是在/fftools/Makefile中,makefile的内容比较简单,不做过多分析

先看fftools/ffmpeg.c文件中的main:

int main(int argc, char **argv)
{
    int i, ret;
    BenchmarkTimeStamps ti;

    init_dynload();		//对应win平台的dll加载

    register_exit(ffmpeg_cleanup);	//相当于c++的析构,这里用了回调,用来释放空间

    setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */  //设置环境变量

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

#if CONFIG_AVDEVICE
    avdevice_register_all();			//驱动设备注册
#endif
    avformat_network_init();			//网络驱动初始化

    show_banner(argc, argv, options);

    /* parse options and open all input/output files */
    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);
    }

    /* file converter / grab */
    if (nb_output_files <= 0) {
        av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
        exit_program(1);
    }

    for (i = 0; i < nb_output_files; i++) {
        if (strcmp(output_files[i]->ctx->oformat->name, "rtp"))
            want_sdp = 0;
    }

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

ffmpeg_parse_options函数在ffmpeg_opt.c文件中:


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

个人理解

示例代码

函数释义

解码步骤

参考

  • 最简单的基于FFMPEG的封装格式转换器(无编解码)
  • FFmpeg音视频文件解封装实现
  • RTSP再学习 – 利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中
  • 音视频数据处理(一)-H264/AVC视频码流分析
  • 【音视频技术】AVC H264的一些基本概念和知识点
  • 视音频数据处理入门:H.264视频码流解析

发布者:admin,转转请注明出处:http://www.yc00.com/web/1754491327a5166253.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信