ffmpeg 如何选择具有相同AVCodecID的编解码器 (AVCodec)

AVStream 指明的码流的基本信息。对一个码流来说最基本的是 AVCodecID。AVCodecID 指明码流对应的标准,比如h264/h263/mp3/aac。同一个 AVCodecID 可能对应多个不同的编解码器 (AVCodec),他们有不同的 AVCodec.name。ffmpeg在选择时除了优先选择non-EXPERIMENTAL的codec, 不会试图去做其它优先选择,只是简单选取最早注册的那个:

下面是根据AVCodecID寻找编码器的代码选段:

static AVCodec *find_encdec(enum AVCodecID id, int encoder)
{
    AVCodec *p, *experimental = NULL;
    p = first_avcodec;
    id= remap_deprecated_codec_id(id);
    while (p) {
        if ((encoder ? av_codec_is_encoder(p) : av_codec_is_decoder(p)) && p->id == id)
        {
            if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) {
                experimental = p;
            } else
                return p;
        }
        p = p->next;
    }

    return experimental;
}

以AAC为例,若不在命令行手动指定 "-acodec xxxx", ffmpeg 会优先选择内部的 ff_aac_decoder 作为解码器:

AVCodec ff_aac_decoder = {
    .name            = "aac",
    .id              = AV_CODEC_ID_AAC,
    .priv_data_size  = sizeof(AACContext),
};

AVCodec ff_libfdk_aac_decoder = {
    .name           = "libfdk_aac",
    .id             = AV_CODEC_ID_AAC,
    .priv_data_size = sizeof(FDKAACDecContext),
};

void avcodec_register_all(void)
{
    ...
    REGISTER_ENCDEC (AAC,               aac);
    REGISTER_DECODER(AAC_LATM,          aac_latm);
    REGISTER_ENCODER(LIBFAAC,           libfaac);
    REGISTER_ENCDEC (LIBFDK_AAC,        libfdk_aac);
    REGISTER_ENCODER(LIBVO_AACENC,      libvo_aacenc);
    REGISTER_ENCODER(LIBAACPLUS,        libaacplus);
    REGISTER_PARSER(AAC,                aac);
    REGISTER_PARSER(AAC_LATM,           aac_latm);
    REGISTER_BSF(AAC_ADTSTOASC,         aac_adtstoasc);
    ...
}

ffmpeg 内部倒是有一个寻找所有AVCodecID对应的AVCodec的函数,但只用于print cmdl help.

static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,int encoder);
原文地址:https://www.cnblogs.com/jogh/p/4970977.html