zoukankan      html  css  js  c++  java
  • FFmpeg源码分析:avcodec_find_decoder

    查找解码器

    /**
     * Find a registered decoder with a matching codec ID.
     *
     * @param id AVCodecID of the requested decoder
     * @return A decoder if one was found, NULL otherwise.
     */
    AVCodec *avcodec_find_decoder(enum AVCodecID id);

    分析

    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;
    }
    
    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;
    }

    可以发现解码器最终从codec_list数组里获取,不过这个是编译的时候生成的,比如ff_aac_decoder

    AVCodec ff_aac_decoder = {
        .name            = "aac",
        .long_name       = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
        .type            = AVMEDIA_TYPE_AUDIO,
        .id              = AV_CODEC_ID_AAC,
        .priv_data_size  = sizeof(AACContext),
        .init            = aac_decode_init,
        .close           = aac_decode_close,
        .decode          = aac_decode_frame,
        .sample_fmts     = (const enum AVSampleFormat[]) {
            AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
        },
        .capabilities    = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
        .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
        .channel_layouts = aac_channel_layout,
        .flush = flush,
        .priv_class      = &aac_decoder_class,
        .profiles        = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
    };
  • 相关阅读:
    iOS 有用的代码片段
    iOS 限制软盘输入法
    UIlabel 遇到\n 换行iOS
    关于delegate 与 protocol 的理解 iOS
    ios 跳转到app store
    iOS 上下左右滑动手势
    求某段程序运行的高精度时间
    转载——GDB中应该知道的几个调试方法
    文章翻译——使用 GNU 的 GDB调试器,内存布局和栈——01
    第十章扩展——__cdecl 的压栈方式——printf
  • 原文地址:https://www.cnblogs.com/vczf/p/14810261.html
Copyright © 2011-2022 走看看