[FFMPEG源码]Format格式探测

作者: _小老虎_ | 来源:发表于2019-11-12 22:11 被阅读0次

    Version:3.4.6


    ffmpeg对于格式的探测其实是两步:

    • read_probe
    • extensions

    参考分析路径

    
    ./libavformat
      |---- utils.c
            |---- avformat_open_input
            |---- init_input
      |---- format.c
            |---- av_probe_input_buffer2
            |---- av_probe_input_format3
      |---- avformat.h - wtvdec/paf/mgsts/jvdec.c
            |---- read_probe
    
    

    详情

    static int init_input(AVFormatContext *s, const char *filename,
                          AVDictionary **options)
    {
        //...
        return av_probe_input_buffer2(s->pb, &s->iformat, filename,
                                     s, 0, s->format_probesize);
    }
    
    int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt,
                              const char *filename, void *logctx,
                              unsigned int offset, unsigned int max_probe_size)
    {
        //...
        //把AVFormatContext和具体的AVInputFormat联系起来了
         *fmt = av_probe_input_format2(&pd, 1, &score);
        //...
    }
    



    FFmpeg中实现探测的函数是av_probe_input_buffer2av_probe_input_format3

    * format.c - av_probe_input_format3
    /**
     * 遍历所有的Demuxer
     * 是优先使用demuxer的read_probe函数,然后参考文件名的后缀名来关联某个AVInputFormat
     */
        fmt = NULL;
        while ((fmt1 = av_iformat_next(fmt1))) {
            if (!is_opened == !(fmt1->flags & AVFMT_NOFILE) && strcmp(fmt1->name, "image2"))
                continue;
            score = 0;
            if (fmt1->read_probe) {
                score = fmt1->read_probe(&lpd);
                if (score)
                    av_log(NULL, AV_LOG_TRACE, "Probing %s score:%d size:%d\n", fmt1->name, score, lpd.buf_size);
                if (fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions)) {
                    switch (nodat) {
                    case NO_ID3:
                        score = FFMAX(score, 1);
                        break;
                    case ID3_GREATER_PROBE:
                    case ID3_ALMOST_GREATER_PROBE:
                        score = FFMAX(score, AVPROBE_SCORE_EXTENSION / 2 - 1);
    break;
                    case ID3_GREATER_MAX_PROBE:
                        score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
                        break;
                    }
                }
            } else if (fmt1->extensions) {
                if (av_match_ext(lpd.filename, fmt1->extensions))
                    score = AVPROBE_SCORE_EXTENSION;
            }
            if (av_match_name(lpd.mime_type, fmt1->mime_type)) {
                if (AVPROBE_SCORE_MIME > score) {
                    av_log(NULL, AV_LOG_DEBUG, "Probing %s score:%d increased to %d due to MIME type\n", fmt1->name, score, AVPROBE_SCORE_MIME);
                    score = AVPROBE_SCORE_MIME;
                }
            }
            if (score > score_max) {
                score_max = score;
                fmt       = fmt1;
            } else if (score == score_max)
                fmt = NULL;
        }
        if (nodat == ID3_GREATER_PROBE)
            score_max = FFMIN(AVPROBE_SCORE_EXTENSION / 2 - 1, score_max);
        *score_ret = score_max;
    
        return fmt;
    

    相关文章

      网友评论

        本文标题:[FFMPEG源码]Format格式探测

        本文链接:https://www.haomeiwen.com/subject/nqkcictx.html