簡體   English   中英

如何確定編解碼器/容器組合是否與 FFmpeg 兼容?

[英]How can I determine if a codec / container combination is compatible with FFmpeg?

我正在考慮重新混合一些包含音頻和視頻的容器,以便我提取最好的第一個音頻流,並將其存儲在一個新的容器中,例如只有音頻流存在。

FFmpeg 的輸出上下文是這樣創建的:

AVFormatContext* output_context = NULL;
avformat_alloc_output_context2( &output_context, NULL, "mp4", NULL );

我有一個可接受輸出的候選清單,例如 MP4、M4A 等……基本上是 Apple 的音頻文件服務可讀的那些:

kAudioFileAIFFType              = 'AIFF',
kAudioFileAIFCType              = 'AIFC',
kAudioFileWAVEType              = 'WAVE',
kAudioFileSoundDesigner2Type    = 'Sd2f',
kAudioFileNextType              = 'NeXT',
kAudioFileMP3Type               = 'MPG3',   // mpeg layer 3
kAudioFileMP2Type               = 'MPG2',   // mpeg layer 2
kAudioFileMP1Type               = 'MPG1',   // mpeg layer 1
kAudioFileAC3Type               = 'ac-3',
kAudioFileAAC_ADTSType          = 'adts',
kAudioFileMPEG4Type             = 'mp4f',
kAudioFileM4AType               = 'm4af',
kAudioFileM4BType               = 'm4bf',
kAudioFileCAFType               = 'caff',
kAudioFile3GPType               = '3gpp',
kAudioFile3GP2Type              = '3gp2',
kAudioFileAMRType               = 'amrf'

我的問題是:在 FFmpeg 中是否有一個簡單的 API 可以利用它來選擇兼容的輸出容器給定音頻流所在的編解碼器?

有一種動態方法可以解決這個問題。 這枚舉了每個容器的編解碼器,但您也會得到相反的結果:

// enumerate all codecs and put into list
std::vector<AVCodec*> encoderList;
AVCodec * codec = nullptr;
while (codec = av_codec_next(codec))
{
    // try to get an encoder from the system
    auto encoder = avcodec_find_encoder(codec->id);
    if (encoder)
    {
        encoderList.push_back(encoder);
    }
}
// enumerate all containers
AVOutputFormat * outputFormat = nullptr;
while (outputFormat = av_oformat_next(outputFormat))
{
    for (auto codec : encoderList)
    {
        // only add the codec if it can be used with this container
        if (avformat_query_codec(outputFormat, codec->id, FF_COMPLIANCE_STRICT) == 1)
        {
            // add codec for container
        }
    }
}

如果您只想要特定的容器或編解碼器,您可以使用帶有nameid字段的白名單,並在枚舉時使用它。

對於每個單獨的多路復用器,通常有一個編解碼器標記寫入函數。該函數將檢查另一個源文件中的列表或通過相同的switch語句工作。 沒有中央花名冊或容器匹配效用函數。 最好的辦法是在libavcodec/allcodecs.c識別編解碼器 ID,然后在libavformat/ grep 為該 ID,特別是在后綴為 enc 的文件中,例如matroskaenc.c

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM