FFmpeg源码分析:av_parser_init

查找编码器

AVCodecParserContext *av_parser_init(int codec_id);

实现

AVCodecParserContext *av_parser_init(int codec_id)
{
    AVCodecParserContext *s = NULL;
    const AVCodecParser *parser;
    void *i = 0;
    int ret;

    if (codec_id == AV_CODEC_ID_NONE)
        return NULL;
    // 1.基于id查找AVCodecParser解析器
    while ((parser = av_parser_iterate(&i))) {
        if (parser->codec_ids[0] == codec_id ||
            parser->codec_ids[1] == codec_id ||
            parser->codec_ids[2] == codec_id ||
            parser->codec_ids[3] == codec_id ||
            parser->codec_ids[4] == codec_id)
            goto found;
    }
    return NULL;

    
found:
    // 2.分配解析器上下文
    s = av_mallocz(sizeof(AVCodecParserContext));
    if (!s)
        goto err_out;

    // 3.解析器上下文初始化
    s->parser = (AVCodecParser*)parser;
    s->priv_data = av_mallocz(parser->priv_data_size);
    if (!s->priv_data)
        goto err_out;
    s->fetch_timestamp=1;
    s->pict_type = AV_PICTURE_TYPE_I;
    // 4.解析器初始化
    if (parser->parser_init) {
        ret = parser->parser_init(s);
        if (ret != 0)
            goto err_out;
    }
    s->key_frame            = -1;
#if FF_API_CONVERGENCE_DURATION
FF_DISABLE_DEPRECATION_WARNINGS
    s->convergence_duration = 0;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
    s->dts_sync_point       = INT_MIN;
    s->dts_ref_dts_delta    = INT_MIN;
    s->pts_dts_delta        = INT_MIN;
    s->format               = -1;

    return s;

err_out:
    // 5.查找失败,释放priv_data 返回NULL
    if (s)
        av_freep(&s->priv_data);
    av_free(s);
    return NULL;
}
const AVCodecParser *av_parser_iterate(void **opaque)
{
    uintptr_t i = (uintptr_t)*opaque;
    const AVCodecParser *p = parser_list[i];

    if (p)
        *opaque = (void*)(i + 1);

    return p;
}

这里主要分为几步:

  1. 基于id查找AVCodecParser解析器,可以发现就在parser_list数组里找的
  2. 分配解析器上下文
  3. 解析器上下文初始化
  4. 解析器初始化
  5. 查找失败,释放priv_data 返回NULL
原文地址:https://www.cnblogs.com/vczf/p/14813835.html