2016-05-15 22 views
0

我有一個帶有DTS音軌的mkv文件。ffmpeg avcodec_open2在AVCodecContext中更改了音頻格式

在調用avcodec_open2之後,AVCodexContext中的sample_fmt改變了。是否預計?

AVCodecContext* avAudioCodecCtx = avFormatCtx->streams[audioStreamIndex]->codec; 

AVSampleFormat f = avAudioCodecCtx->sample_fmt; // AV_SAMPLE_FMT_FLTP 
avcodec_open2(avAudioCodecCtx, avAudioCodec, NULL); 
AVSampleFormat f2 = avAudioCodecCtx->sample_fmt; // AV_SAMPLE_FMT_S32P 

ffprobe

ffprobe version N-79143-g8ff0f6a Copyright (c) 2007-2016 the FFmpeg developers 
    built with gcc 5.3.0 (GCC) 
    configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmfx --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib 
    libavutil  55. 19.100/55. 19.100 
    libavcodec  57. 30.100/57. 30.100 
    libavformat 57. 29.101/57. 29.101 
    libavdevice 57. 0.101/57. 0.101 
    libavfilter  6. 40.102/6. 40.102 
    libswscale  4. 0.100/4. 0.100 
    libswresample 2. 0.101/2. 0.101 
    libpostproc 54. 0.100/54. 0.100 

Stream #0:1(eng): Audio: dts (DTS), 48000 Hz, 5.1(side), fltp, 768 kb/s (default) 

解碼

avcodec_decode_audio4(avAudioCodecCtx, frame, &frameComplete, avPacket); 
frame->format // contains AV_SAMPLE_FMT_FLTP 

回答

1

是的,這是預期。所以,這可能有點煩人,但avcodec_open2()只是簡單地將sample_fmt設置爲在打開編解碼器時給出存儲在AVCodecContext中的信息的「最可能」格式。對於某些格式,所有這些信息都在比特流數據包中,所以他們只是不知道。

實際對於每個解碼分組(或解碼分組後的AVCodecContext->sample_fmt),在AVFrame->format中設置格式。這在整個流中通常是恆定的,但這不能保證。格式與AVCodecContext->format之前調用avcodec_open2()之前的格式相同的原因是分路器(或更具體地說,avformat_find_stream_info())可能打開解碼器並嘗試解碼幀;當這種情況發生,AVCodecContext->sample_fmt設置爲相同的值AVFrame->format,但是當你調用avcodec_open2()開始實際的比特流解碼這個值被再次改寫......

結論:使用AVCodecContext->sample_fmt作爲參考,並依靠AVFrame->format任何實際使用。

+0

謝謝你的詳細解答。這是否意味着,不是每個音頻流只有一個SwrContext,我必須爲每個幀創建新的SwrContext,其格式爲swr_convert的輸入格式? – user1083577

+0

只有格式更改。儘管對於某些編解碼器而言,它可能每幀都發生變化,但這應該被認爲是非常不尋常的,因此應該對這些上下文進行緩存以提高常見情況下的性能。 –