2016-02-05 937 views
1

我有一個視頻文件,並且我在近3年前將視頻信息轉儲到ffmpeg的txt文件中。音頻採樣格式s16p,ffmpeg或音頻編解碼器錯誤?

... 
Stream #0:1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16, 256 kb/s 
Stream #0:2[0x1c1]: Audio: mp2, 48000 Hz, stereo, s16, 256 kb/s 

但是我發現,當我使用的更新ffprobe(ffprobe版本N-78046-g46f67f4版權所有(C)2007-2016 FFmpeg的開發者)的格式改變。

... 
Stream #0:1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 256 kb/s 
Stream #0:2[0x1c1]: Audio: mp2, 48000 Hz, stereo, s16p, 256 kb/s 

對於相同的視頻,其示例格式更改爲s16p。

我實現了一個簡單的使用ffmpeg的視頻播放器。它可以在3年前播放視頻,但在更改ffmpeg後無法輸出正確的pcm流。我花了很多時間,終於發現音頻應該是s16而不是s16p。解碼後的音頻流的作品後,我打電話avcodec_decode_audio4之前增加了行,

audio_codec_ctx->sample_fmt = AV_SAMPLE_FMT_S16 

,但它只是一個黑客。有沒有人遇到過這個問題?如何使ffmpeg正確工作?任何暗示是讚賞。謝謝!

+0

請參閱http://stackoverflow.com/q/18888986/5726027 – Mulvya

+0

我知道s16和s16p之間的區別。我的問題是關於ffmpeg用新舊版本輸出不同的音頻信息。我的測試視頻是s16,但新的ffmpeg說它是s16p。 – Arton

+0

ffplay可以很好地播放視頻,所以我認爲界面可能會發生很大變化,我會跟蹤ffplay來找出根本原因。 – Arton

回答

3

輸出格式changed。原因是相當複雜和技術性的,但讓我嘗試解釋它。

大多數音頻編解碼器的結構使得每個通道的輸出最好單獨進行重構,並且將通道合併(將「左」和「右」緩衝器交織成一排樣本,排序爲left0 right0 left1 right1 [etc ])發生在最後。您大概可以想象,如果編碼器想要再次解交織,則音頻轉碼涉及兩個冗餘操作(交織/解交織)。因此,所有有意義的解碼器都切換到輸出平面音頻(因此s16變爲s16p,其中p表示平面),其中每個通道都是自己的緩衝區。因此:現在,在解碼之後使用重新採樣庫(libswresample)完成交織,而不是作爲解碼的組成部分,並且僅在用戶明確希望這樣做時,而不是自動/總是。

確實可以將請求採樣格式設置爲S16,以強制解碼爲s16而不是s16p。考慮到這是一個兼容性破解,它將在某些時候被刪除,因爲它可以工作的少數解碼器,以及一個不適用於新解碼器的解碼器。相反,考慮在應用程序中添加libswresample支持,以便在解碼器的本機輸出格式和用於進一步數據處理(例如使用聲卡播放)的格式之間進行轉換。

+0

但是爲什麼當前ffprobe不能正確地報告舊文件中使用的打包方案? – Mulvya

+0

打包不依賴於文件(或編解碼器,例如mp2),它取決於解碼器(實現)。目前的ffprobe使用當前的ffmpeg mp2解碼器,該解碼器本身爲所有文件輸出s16p。舊的ffprobe使用舊的ffmpeg mp2解碼器,它本身爲所有文件輸出s16。 –

+0

這可以幫助我很多!描述非常清楚。非常感謝你! – Arton