FFmpeg解碼多出一幀?菜雞定位一個尚未解決的BUG

最近在做demo時,需要使用 FFmpeg 解碼。

由於只需要評測編碼器的性能,不需要考慮解碼器的效率,所以自然而然想到直接使用命令行調用 FFmpeg.exe 就行(主要是怕麻煩+菜雞)。
當時使用了以下代碼:

char* decFileName = "output.yuv";
sprintf(cmd, "ffmpeg -i %s -vframes %d %s -y", outFileName, numEncode, decFileName); //outFileName --> xxx.264
system(cmd);

很輕鬆的解碼得到 YUV 文件,再送到後面的質量評估模塊去計算 PSNR + SSIM 等等指標。

**so easy,我會心一笑。 **

可是,問題出現了!

除了第一幀 PSNR 和 SSIM 看似正確,後面的幀計算得到的 PSNR 和 SSIM 出現斷崖式下降。
在這裏插入圖片描述
這是什麼問題呢?難道是 PSNR 和 SSIM 計算模塊代碼有BUG? 認真Check一遍,發現沒有大的問題。

在網上找了兩個開源的 PSNR 計算工具,對比了下,計算的和我算出的也相同,說明後續的質量評估模塊應該OK。
再對比輸入輸出 YUV 文件的大小和幀數,也沒有發現問題。

於是乎,我就把問題定位到了兩個可能的方向:

1. 解碼沒問題,編碼器性能差。比如說,可能編碼器的碼控策略優化的不好,I幀分配太多Bits,P幀分配的Bits數目不夠導致質量斷崖式下降。

2. 編碼沒問題,解碼出了問題。

針對第一個方向,我用 YUV 播放器對比了編碼前後重建的 YUV 文件,發現肉眼所見質量幾乎無變化,不可能使得 PSNR 下降超過10。所以說,編碼器在編碼質量這個方面應該沒有問題。

於是,我又查看之後每一幀的視頻質量,在對比了幾百幀,直到出現了一個 場景切換幀 後,我才發現了問題。原來是出現了幀延遲 ==> 拿着第 N 幀 和 第 N+1 幀做 比較,PSNR 和 SSIM 當然會出現大差別。

所以,我重新開始從第一幀追查,發現第一幀重複了兩次。也就是說,解碼後的圖像是 1、 1、 2、 3、 4、 5、 6、 …、 N-1的次序,然而計算質量時,對比的是原始序列第 1、 2、 3、 4、 5、 6、 …、 N-1、N 的次序。所以說,只有第一幀是匹配的,後面匹配都有問題。在場景切換幀之前,雖然誤匹配,但是兩幀肉眼差別很小,主觀基本看不出差別,然而 PSNR 是逐像素對比計算的,即使主觀區別不大,其數值也會出現斷崖式下降,成功破案

比如說,這是第2幀的匹配錯誤,肉眼很難分辨區別,但是逐像素對比就會差別很大。
在這裏插入圖片描述
這是後續幀出現了明顯的誤匹配(上方橫條),PSNR會掉至低於20,促使我發現了問題所在。

在這裏插入圖片描述

繼續定位BUG。之前檢查過,輸出YUV的幀數和原始YUV的幀數相同,那麼最後一幀豈不是丟幀了?

再次查看 FFmpeg 調用代碼,發現是因爲在調用時指定了解碼幀數。把之前的代碼去掉解碼幀數的限制,如下所示:

char* decFileName = "output.yuv";
sprintf(cmd, "ffmpeg -i %s %s -y", outFileName, decFileName); //outFileName --> xxx.264
system(cmd);

果然,解碼出的 YUV幀數是 numEncode + 1 幀,第一幀莫名其妙地重複了一次!

繼續進行問題定位,定位以下兩個方向:

1. 還是編碼器出了問題,第一幀的碼流 repeat 一次。

2. 調用 FFmpeg 的方式不對,或者 FFmpeg針對過大的文件解碼可能會錯誤( > 2500幀, 720p)

針對第一個方向,我用 H264VISA 查看了碼流,確實碼流沒有問題,並未重複第一幀。

所以,現在我認爲我出現的問題是 “調用 FFmpeg 的方式不對,或者 FFmpeg針對過大的文件解碼可能會錯誤( > 2500幀, 720p)”,目前該BUG還未解決,有可能又是像上次一樣,基礎的小BUG導致這個問題。如果有人之前遇到過這個問題,希望可以指導一下我,多謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章