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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM