FFMPEG函数open_output_file()

FFMPEG代码为3.2 release版本, 文件位于ffmpeg_opt.c。

函数open_output_file()主要功能

打开输出文件,并且给指针数组output_files赋值。如果存在的话给指针数组output_streams赋值。

open_output_file()函数中的代码执行,很多都依赖于配置选项

即options[]中的内容。例如配置:

-to,影响值stop_time

-t,影响值recording_time

-ss,影响值start_time

-fs,影响值limit_filesize

-shortest,影响值shortest

-map,影响值nb_stream_maps

-vn,影响值video_disable

-an,影响值audio_disable

-sn,影响值subtitle_disable

-dn,影响值data_disable

注释:

从FFMPEG release 3.2发现-dn没有起作用,所以代码有冗余:

        /* Data only if codec id match */
        if (!o->data_disable ) {
            enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_DATA);
            for (i = 0; codec_id != AV_CODEC_ID_NONE && i < nb_input_streams; i++) {
                if (input_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_DATA
                    && input_streams[i]->st->codecpar->codec_id == codec_id )
                    new_data_stream(o, oc, i);
            }
        }

-attach,影响值nb_attachments

OptionsContext int nb_metadata_map没有赋值的地方,该代码也是冗余:

    /* copy metadata */
    for (i = 0; i < o->nb_metadata_map; i++) {
        char *p;
        int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);

        if (in_file_index >= nb_input_files) {
            av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
            exit_program(1);
        }
        copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
                      in_file_index >= 0 ?
                      input_files[in_file_index]->ctx : NULL, o);
    }

 

OptionsContext int nb_program没有赋值的地方,该代码也是冗余:

    /* process manually set programs */
    for (i = 0; i < o->nb_program; i++) {
        const char *p = o->program[i].u.str;
        int progid = i+1;
        AVProgram *program;

        while(*p) {
            const char *p2 = av_get_token(&p, ":");
            const char *to_dealloc = p2;
            char *key;
            if (!p2)
                break;

            if(*p) p++;

            key = av_get_token(&p2, "=");
            if (!key || !*p2) {
                av_freep(&to_dealloc);
                av_freep(&key);
                break;
            }
            p2++;

            if (!strcmp(key, "program_num"))
                progid = strtol(p2, NULL, 0);
            av_freep(&to_dealloc);
            av_freep(&key);
        }

        program = av_new_program(oc, progid);

        p = o->program[i].u.str;
        while(*p) {
            const char *p2 = av_get_token(&p, ":");
            const char *to_dealloc = p2;
            char *key;
            if (!p2)
                break;
            if(*p) p++;

            key = av_get_token(&p2, "=");
            if (!key) {
                av_log(NULL, AV_LOG_FATAL,
                       "No '=' character in program string %s.\n",
                       p2);
                exit_program(1);
            }
            if (!*p2)
                exit_program(1);
            p2++;

            if (!strcmp(key, "title")) {
                av_dict_set(&program->metadata, "title", p2, 0);
            } else if (!strcmp(key, "program_num")) {
            } else if (!strcmp(key, "st")) {
                int st_num = strtol(p2, NULL, 0);
                av_program_add_stream_index(oc, progid, st_num);
            } else {
                av_log(NULL, AV_LOG_FATAL, "Unknown program key %s.\n", key);
                exit_program(1);
            }
            av_freep(&to_dealloc);
            av_freep(&key);
        }
    }

OptionsContext int nb_metadata没有赋值的地方,该代码也是冗余:


    /* process manually set metadata */
    for (i = 0; i < o->nb_metadata; i++) {
        AVDictionary **m;
        char type, *val;
        const char *stream_spec;
        int index = 0, j, ret = 0;

        val = strchr(o->metadata[i].u.str, '=');
        if (!val) {
            av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
                   o->metadata[i].u.str);
            exit_program(1);
        }
        *val++ = 0;

        parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
        if (type == 's') {
            for (j = 0; j < oc->nb_streams; j++) {
                ost = output_streams[nb_output_streams - oc->nb_streams + j];
                if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
                    av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
                    if (!strcmp(o->metadata[i].u.str, "rotate")) {
                        ost->rotate_overridden = 1;
                    }
                } else if (ret < 0)
                    exit_program(1);
            }
        }
        else {
            switch (type) {
            case 'g':
                m = &oc->metadata;
                break;
            case 'c':
                if (index < 0 || index >= oc->nb_chapters) {
                    av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
                    exit_program(1);
                }
                m = &oc->chapters[index]->metadata;
                break;
            case 'p':
                if (index < 0 || index >= oc->nb_programs) {
                    av_log(NULL, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index);
                    exit_program(1);
                }
                m = &oc->programs[index]->metadata;
                break;
            default:
                av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
                exit_program(1);
            }
            av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
        }
    }

 

函数avformat_alloc_output_context2()

根据配置的输出文件格式,获取AVOutputFormat内容

函数new_video_stream()

如果输出视频数据的话,需要执行该函数

函数new_audio_stream()

如果输出音频数据的话,需要执行该函数

函数avio_open2()

打开输出文件

 

转载于:https://my.oschina.net/u/2326611/blog/809828

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
av_dump_format函数FFmpeg中的一个非常有用的函数,可以用来打印音视频文件的信息,比如文件格式、时长、编码器等等。 该函数的定义如下: ```c void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output); ``` 其中,参数ic是一个AVFormatContext指针,表示音视频文件的上下文,它包含了音视频文件的所有信息;参数index表示要打印的流的索引,如果index为负数,则表示打印所有流的信息;参数url是一个字符串,表示音视频文件的文件名;参数is_output表示该文件是输入文件还是输出文件,如果是输入文件,则is_output为0,否则为1。 使用av_dump_format函数非常简单,只需要在打开音视频文件后调用该函数即可,例如: ```c AVFormatContext *ic = avformat_alloc_context(); if (avformat_open_input(&ic, filename, NULL, NULL) < 0) { printf("Failed to open file '%s'\n", filename); return -1; } if (avformat_find_stream_info(ic, NULL) < 0) { printf("Failed to retrieve input stream information\n"); return -1; } av_dump_format(ic, 0, filename, 0); ``` 这个例子中,我们首先使用avformat_alloc_context函数创建了一个AVFormatContext对象,然后通过avformat_open_input函数打开了音视频文件,再通过avformat_find_stream_info函数获取音视频文件的流信息,最后调用av_dump_format函数打印出文件的信息。 注意,av_dump_format函数会将信息打印到标准输出流中,如果需要将信息保存到文件中,可以重定向标准输出流。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值