ffmpeg源码分析之四-----avformat_open_input()下

这篇博客继续分析ffmpeg的avformat_open_input()函数,主要探讨av_probe_input_buffer()及其内部的av_probe_input_format2和av_probe_input_format3。这些函数从全局链表中寻找合适的AVInputFormat结构,根据输入文件格式自动完成匹配。找到格式后,调用read_header()函数,例如在vc1源中匹配到libavformat/mpegts.c的ff_mpegts_demuxer,其read_header指向mpegts_read_header。在mpegts_read_header中,为AVStream和AVCodecContext分配空间,并在特定条件下跳过avformat_new_stream,进入handle_packets流程。
摘要由CSDN通过智能技术生成

  上篇分析到在Init_input中打开一个媒体文件 本篇将分析剩下的流程。看代码

static int init_input(AVFormatContext *s, const char *filename, AVDictionary **options)
{
    int ret;
    AVProbeData pd = {filename, NULL, 0};

    if (s->pb) {
        s->flags |= AVFMT_FLAG_CUSTOM_IO;
        if (!s->iformat)
            return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
        else if (s->iformat->flags & AVFMT_NOFILE)
            av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
                                      "will be ignored with AVFMT_NOFILE format.\n");
        return 0;
    }

    if ( (s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
        (!s->iformat && (s->iformat = av_probe_input_format(&pd, 0))))
        return 0;
	//avio_open2定义在libavformat/aviobuf.c中 但是在avio.h中声明
	//Create and initialize a AVIOContext for accessing the resource indicated by url
    if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ,
                          &s->interrupt_callback, options)) < 0)
        return ret;
    if (s->iformat)
        return 0;
	av_log(0,AV_LOG_INFO,"注意:程序将要执行av_probe_input_buffer\n");
    return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
}


来看av_probe_input_buffer():

int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
                          const char *filename, void *logctx,
                          unsigned int offset, unsigned int max_probe_size)
{
    AVProbeData pd = { filename ? filename : "", NULL, -offset };
    unsigned char *buf = NULL;
    int ret = 0, probe_size;

    if (!max_probe_size) {
        max_probe_size = PROBE_BUF_MAX;
    } else if (max_probe_size > PROBE_BUF_MAX) {
        max_probe_size = PROBE_BUF_MAX;
    } else if (max_probe_size < PROBE_BUF_MIN) {
        return AVERROR(EINVAL);
    }

    if (offset >= max_probe_size) {
        return AVERROR(EINVAL);
    }

    for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt;
        probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) {
        int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0;
        int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1;
        void *buftmp;

        if (probe_size < offset) {
            continue;
        }

        /* read probe data */
        buftmp = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);
        if(!buftmp){
            av_free(buf);
            return AVERROR(ENOMEM);
        }
        buf=buftmp;
        if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) {
            /* fail if error was not end of file, otherwise, lower score */
            if (ret != AVERROR_EOF) {
                av_free(buf);
                re
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值