avformat_open_input()

来源:互联网 发布:全额返现 知乎 编辑:程序博客网 时间:2024/06/08 16:04

该接口是ffmpeg媒体打开过程的开始,avformat_open_input()内部处理的逻辑为:

  • 输入输出结构体AVIOContext的初始化
  • 输入数据的识别:例如RTP?或者是file文件的识别,其通过一套机制来进行,判断后缀或者是文件头数据信息等
  • 使用获得评分最高的文件协议对应的URLProtocol,通过函数指针的方式,与ffmpeg进行连接
  • 然后调用该URLProtocol的函数进行open,read等操作
int avformat_open_input(AVFormatContext **ps, const char *filename,                        AVInputFormat *fmt, AVDictionary **options){    AVFormatContext *s = *ps;    int i, ret = 0;    AVDictionary *tmp = NULL;    ID3v2ExtraMeta *id3v2_extra_meta = NULL;    if (!s && !(s = avformat_alloc_context()))        return AVERROR(ENOMEM);    if (!s->av_class) {        av_log(NULL, AV_LOG_ERROR, "Input context has not been properly allocated by avformat_alloc_context() and is not NULL either\n");        return AVERROR(EINVAL);    }    if (fmt)        s->iformat = fmt;    if (options)        av_dict_copy(&tmp, *options, 0);    if (s->pb) // must be before any goto fail        s->flags |= AVFMT_FLAG_CUSTOM_IO;    if ((ret = av_opt_set_dict(s, &tmp)) < 0)        goto fail;    if ((ret = init_input(s, filename, &tmp)) < 0)        goto fail;    s->probe_score = ret;    if (!s->protocol_whitelist && s->pb && s->pb->protocol_whitelist) {        s->protocol_whitelist = av_strdup(s->pb->protocol_whitelist);        if (!s->protocol_whitelist) {            ret = AVERROR(ENOMEM);            goto fail;        }    }    if (!s->protocol_blacklist && s->pb && s->pb->protocol_blacklist) {        s->protocol_blacklist = av_strdup(s->pb->protocol_blacklist);        if (!s->protocol_blacklist) {            ret = AVERROR(ENOMEM);            goto fail;        }    }    if (s->format_whitelist && av_match_list(s->iformat->name, s->format_whitelist, ',') <= 0) {        av_log(s, AV_LOG_ERROR, "Format not on whitelist \'%s\'\n", s->format_whitelist);        ret = AVERROR(EINVAL);        goto fail;    }    avio_skip(s->pb, s->skip_initial_bytes);    /* Check filename in case an image number is expected. */    if (s->iformat->flags & AVFMT_NEEDNUMBER) {        if (!av_filename_number_test(filename)) {            ret = AVERROR(EINVAL);            goto fail;        }    }    s->duration = s->start_time = AV_NOPTS_VALUE;    av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename));    /* Allocate private data. */    if (s->iformat->priv_data_size > 0) {        if (!(s->priv_data = av_mallocz(s->iformat->priv_data_size))) {            ret = AVERROR(ENOMEM);            goto fail;        }        if (s->iformat->priv_class) {            *(const AVClass **) s->priv_data = s->iformat->priv_class;            av_opt_set_defaults(s->priv_data);            if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)                goto fail;        }    }    /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */    if (s->pb)        ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, 0);    if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)        if ((ret = s->iformat->read_header(s)) < 0)            goto fail;    if (id3v2_extra_meta) {        if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac") ||            !strcmp(s->iformat->name, "tta")) {            if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)                goto fail;        } else            av_log(s, AV_LOG_DEBUG, "demuxer does not support additional id3 data, skipping\n");    }    ff_id3v2_free_extra_meta(&id3v2_extra_meta);    if ((ret = avformat_queue_attached_pictures(s)) < 0)        goto fail;    if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->internal->data_offset)        s->internal->data_offset = avio_tell(s->pb);    s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;    update_stream_avctx(s);    for (i = 0; i < s->nb_streams; i++)        s->streams[i]->internal->orig_codec_id = s->streams[i]->codecpar->codec_id;    if (options) {        av_dict_free(options);        *options = tmp;    }    *ps = s;    return 0;fail:    ff_id3v2_free_extra_meta(&id3v2_extra_meta);    av_dict_free(&tmp);    if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))        avio_closep(&s->pb);    avformat_free_context(s);    *ps = NULL;    return ret;}


原创粉丝点击