1. YUV數據在使用avfilter scale時在特定的分辨率下UV份量不對
因爲是小視頻,那麼分辨率不須要過高,可是有的視頻源是1080p,甚至有的是4K的,因此對視頻源進行scale很是有必要。scale操做可使用avfilter或者sws_scale完成,具體參考:html
在對視頻數據進行decode後,獲得了包含YUV數據的AVFrame,AVFrame中的data[0], data[1], data[2]分別表示YUV三個份量,YUV三個份量的數據量之比是4:1:1,每行的字節數分別是linesize[0], linesize[1], linesize[2]。git
假定圖像長寬分別爲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數據的份量信息,對於解決問題很是有幫助。app
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數據波形,有無爆音等問題。spa
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了。debug
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. 編碼後視頻前幾幀黑屏
緣由是開啓了多線程編碼,可是單線程編碼效率很低,這個問題還須要細研究一下。
參考資料:
2. FFMpeg學習(六) 用libavfilter對視頻尺寸進行裁切
3. https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio