avcodec_find_encoder/avcodec_find_encoder_by_name

关键函数

/**
 * Find a registered encoder with a matching codec ID.
 * 利用编码器ID查找编码器(AVCodec.id)
 * @param id AVCodecID of the requested encoder
 * @return An encoder if one was found, NULL otherwise.
 */
AVCodec *avcodec_find_encoder(enum AVCodecID id);

/**
 * Find a registered encoder with the specified name.
 * 利用编码器名称查找编码器(AVCodec.name)
 * @param name name of the requested encoder
 * @return An encoder if one was found, NULL otherwise.
 */
AVCodec *avcodec_find_encoder_by_name(const char *name);

编码器说明

  • 编码器存储方式是数组
    AVCodec *codec_list[]={NULL, NULL}

    # configure文件
    ENCODER_LIST=$(find_things_extern encoder AVCodec libavcodec/allcodecs.c)
    DECODER_LIST=$(find_things_extern decoder AVCodec libavcodec/allcodecs.c)
    CODEC_LIST="
        $ENCODER_LIST
        $DECODER_LIST
    "
    
    // codec_list的初始化
    static AVOnce av_codec_static_init = AV_ONCE_INIT;
    static void av_codec_init_static(void)
    {
        for (int i = 0; codec_list[i]; i++) {
            if (codec_list[i]->init_static_data)
                codec_list[i]->init_static_data((AVCodec*)codec_list[i]);
        }
    }
    
  • avcodec_find_encoderavcodec_find_encoder_by_name就是通过遍历codec_list来查找指定编码器的,找到这返回指定编码器,否则返回NULL

    // avcodec_find_encoder
    AVCodec *avcodec_find_encoder(enum AVCodecID id)
    {
        return find_codec(id, av_codec_is_encoder);
    }
    
    static AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *))
    {
        const AVCodec *p, *experimental = NULL;
        void *i = 0;
    
        id = remap_deprecated_codec_id(id);
    
        while ((p = av_codec_iterate(&i))) {
            if (!x(p))
                continue;
            if (p->id == id) {
                if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) {
                    experimental = p;
                } else
                    return (AVCodec*)p;
            }
        }
    
        return (AVCodec*)experimental;
    }
    
    // avcodec_find_encoder_by_name
    AVCodec *avcodec_find_encoder_by_name(const char *name)
    {
        return find_codec_by_name(name, av_codec_is_encoder);
    }
    
    static AVCodec *find_codec_by_name(const char *name, int (*x)(const AVCodec *))
    {
        void *i = 0;
        const AVCodec *p;
    
        if (!name)
            return NULL;
    
        while ((p = av_codec_iterate(&i))) {
            if (!x(p))
                continue;
            if (strcmp(name, p->name) == 0)
                return (AVCodec*)p;
        }
    
        return NULL;
    }
    
    // 迭代器的方式遍历codec_list
    const AVCodec *av_codec_iterate(void **opaque)
    {
        uintptr_t i = (uintptr_t)*opaque;
        const AVCodec *c = codec_list[i];
    
        ff_thread_once(&av_codec_static_init, av_codec_init_static);
    
        if (c)
            *opaque = (void*)(i + 1);
    
        return c;
    }
    

libavcodec/allcodecs.c

/**
 * @file
 * Provide registration of all codecs, parsers and bitstream filters for libavcodec.
 */
extern AVCodec ff_a64multi_encoder;
extern AVCodec ff_a64multi5_encoder;
extern AVCodec ff_aasc_decoder;
extern AVCodec ff_aic_decoder;
extern AVCodec ff_alias_pix_encoder;
extern AVCodec ff_alias_pix_decoder;
extern AVCodec ff_agm_decoder;
extern AVCodec ff_amv_encoder;
extern AVCodec ff_amv_decoder;
extern AVCodec ff_anm_decoder;
extern AVCodec ff_ansi_decoder;
extern AVCodec ff_apng_encoder;
extern AVCodec ff_apng_decoder;
...
posted @ 2021-12-10 00:14  flxx  阅读(1100)  评论(0编辑  收藏  举报