FFMpeg筆記(五) 錄制小視頻時幾個問題解決


1. YUV數據在使用avfilter scale時在特定的分辨率下UV分量不對

    由於是小視頻,那么分辨率不需要太高,但是有的視頻源是1080p,甚至有的是4K的,所以對視頻源進行scale非常有必要。scale操作可以使用avfilter或者sws_scale完成,具體參考:

    在對視頻數據進行decode后,得到了包含YUV數據的AVFrame,AVFrame中的data[0], data[1], data[2]分別表示YUV三個分量,YUV三個分量的數據量之比是4:1:1,每行的字節數分別是linesize[0], linesize[1], linesize[2]。

    假定圖像長寬分別為w和h,那么Y分量字節數為w*h,linesize[0]等於w,U/V分量字節數均為0.5w*0.5h,linesize[1]等於linesize[2]等於0.5w。但是實際使用時發現,特定分辨率下scale后的UV分量顯示不正常,進一步發現UV的linesize有時不等於0.5w,對此FFMpeg(avframe.h)是這么解釋的:

     * @note The linesize may be larger than the size of usable data -- there * may be extra padding present for performance reasons. */
    int linesize[AV_NUM_DATA_POINTERS];

    實際上確實發現UV分量的linesize不等於0.5w,這樣的話,在拷貝UV分量的時候,就需要一行一行拷貝,每行拷貝0.5w,這個問題也就解決了。

Tips:Mac下使用GLYUVPlay.app軟件,導入原始的YUV數據,輸入分辨率,YUV格式等信息,可以查看原始YUV數據的分量信息,對於解決問題非常有幫助。

2. PCM在使用FFMpeg的aac編碼器編碼時提示編碼失敗

    在特定的手機上,aac會編碼失敗,提示的是"Input contains (near) NaN/+-Inf\n"。但是很奇怪,只在特定的手機出現該問題,查了半天沒有結果,看到有人說libfdk-aac庫可能會解決這個問題,將fdk-aac添加進FFMpeg后,編碼沒有問題,但是編碼出來后的數據有爆音,使用Audacity軟件查看dump下的數據,確實有爆音,也就是說程序還是有問題。仔細審代碼最后發現,aac編碼輸入的PCM數據只有一個聲道的,而編碼參數里寫的輸入為兩個聲道,而第二個聲道的數據沒有賦值,將第二個聲道拷貝了輸入數據后,問題就解決了。。

    總結一下,不是所有的手機都沒問題,那就證明程序還是有問題。

Tips:Mac下使用Audacity軟件,輸入原始PCM數據的采樣率、音頻數據格式后,可以查看原始PCM數據波形,有無爆音等問題。

 3. 視頻尺寸裁切不生效

    視頻尺寸裁切時,用libavfilter的crop參數,我之前的理解,av_buffersink_get_frame出來的frame數據就變成了裁切后的尺寸,后來發現不是這樣。av_buffersink_get_frame后的frame只是width, height變成了裁切尺寸的長寬,data[]指針和linesize大小都沒有變。debug發現,frame的crop相關參數變了,在重新編碼時,就會根據crop參數和width, height參數編碼成裁切后的尺寸。

 4. 錄制GIF時花屏

    按照錄制視頻的代碼去錄制GIF時發現錄制后的GIF花屏,查閱資料可以,GIF的out format必須是AV_PIX_FMT_RGB8,把pixel_format改成RGB8后就OK了。

5. 對帶有HE-AAC的視頻編碼失敗

    之前一直以為服務器的視頻都是LC-AAC格式的,這種格式的采樣樣本數nb_samples是1024個,而HE-AAC視頻的nb_samples是2048個,並且FFmpeg自帶的aac編碼器只支持LC-AAC編碼。於是不得已,只能換為fdk-aac編碼器,根據文檔,fdk-aac編碼器兩種格式的aac都支持。但是fdk-aac編碼器只支持S16格式的PCM,因此對解碼后得到的PCM又加了一層resample,將原來FLTP格式的PCM resample成S16格式,之后編碼成功。附FFmpeg支持的音頻編碼器信息:

Dolby Digital: ac3
Dolby Digital Plus: eac3
MP2: libtwolame, mp2
Windows Media Audio 1: wmav1
Windows Media Audio 2: wmav2
AAC LC: libfdk_aac, aac
HE-AAC: libfdk_aac
Vorbis: libvorbis, vorbis
MP3: libmp3lame, libshine
Opus: libopus

6. 編碼后視頻前幾幀黑屏

    原因是開啟了多線程編碼,但是單線程編碼效率很低,這個問題還需要細研究一下。

參考資料:

1. FFMpeg學習(三) 音頻處理基本概念

2. FFMpeg學習(六) 用libavfilter對視頻尺寸進行裁切

3. https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio


免責聲明!

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



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