1. 程式人生 > >B幀對視訊清晰度/位元速率的影響

B幀對視訊清晰度/位元速率的影響

0. 前言

在H264 Extended Profile中就引入了B幀編碼,一直以來同行都對B幀的意義存在爭議:

  • 正方:B幀能夠大幅減少視訊位元速率,並提高運動場景下的清晰度;
  • 反方:B幀對位元速率和清晰度沒多大幫助

筆者針對這個爭議找了一個視訊,用x264和Android MediaCodec測試驗證B幀到底有沒有優化效果。

1. 什麼是B幀

1.1 什麼是B幀?

B幀法(B frame)是雙向預測的幀間壓縮演算法。當把一幀壓縮成B幀時,它根據相鄰的前一幀、本幀以及後一幀資料的不同點來壓縮本幀,也即僅記錄本幀與前後幀的差值。

1.2 B幀的優點

一般地,I幀壓縮效率最低,P幀較高,B幀最高。

B幀能夠提升運動場景清晰度。

PS:有些專家說對高速運動的場景收益是負向,但是本人沒有驗證過。

1.3 B幀的缺點

由於B幀參考了前後幀,帶來更所以編碼複雜度更高,也提高了解碼複雜度。

2. B幀編碼測試

2.1 軟編碼實驗

2.1.1 測試方案

對同一個視訊,通過ffmpeg/x264進行轉碼,在相同位元率等條件,選擇開啟/關閉B幀,對比PSNR。

2.1.2 測試視訊

理論上B幀對運動場景編碼,所以本次實驗採用一個跳舞的視訊,視訊資訊系如下:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from ‘dance_test.mp4’:
Metadata:
major_brand : qt
minor_version : 0
compatible_brands: qt
creation_time : 2018-08-06 13:08:32
genre : aweme_6585043390285482760
Duration: 00:00:13.60, start: 0.000000, bitrate: 5375 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, smpte170m/bt709/bt709), 540x960, 5244 kb/s, 30 fps, 30 tbr, 600 tbn, 1200 tbc (default)
Metadata:
creation_time : 2018-08-06 13:08:32
handler_name : Core Media Data Handler
encoder : H.264
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 124 kb/s (default)
Metadata:
creation_time : 2018-08-06 13:08:32
handler_name : Core Media Data Handler

2.1.3 FFmpeg/x264命令

--bframes <integer> (x264)
-bf <integer> (FFmpeg)

B-frames are a core element of H.264 and are more efficient in H.264 than any previous standard. Some specific targets, such as HD-DVD and Blu-Ray, have limitations on the number of consecutive B-frames. Most, however, do not; as a result, there is rarely any negative effect to setting this to the maximum (16) since x264 will, if B-adapt is used, automatically choose the best number of B-frames anyways. This parameter simply serves to limit the max number of B-frames. Note that Baseline Profile, such as that used by iPods, does not support B-frames. Recommended default: 16

ffmpeg轉碼非B幀視訊示例:

ffmpeg -i dance_test.mp4 -c:v libx264 -profile:v high -level:v 4.0 -r 30 -s 540x960 -b:v 1500k -g 200 -bf 0  -c:a copy -movflags faststart -y b0_1500.mp4

ffmpeg轉碼B幀視訊示例:

ffmpeg -i dance_test.mp4 -c:v libx264 -profile:v high -level:v 4.0 -r 30 -s 540x960 -b:v 1500k -g 200 -bf 1 -c:a copy -movflags faststart -y b1_1500.mp4

2.1.4 評估方法
採用PSNR評估B幀對視訊質量的提升,命令如下:

ffmpeg -video_size 540x960  -i dance_test.yuv -video_size 540x960  -i b0_1500.yuv -lavfi  psnr="stats_file=psnr.log" -f null -

2.1.5 測試結果

位元速率 B幀設定 PSNR
1500 PSNR y:30.96 u:43.46 v:42.37 average:32.55 min:31.15 max:38.65
1500 PSNR y:30.46 u:42.97 v:41.87 average:32.05 min:30.61 max:38.42
2000 PSNR y:32.76 u:44.56 v:43.49 average:34.33 min:32.64 max:40.77
2000 PSNR y:32.13 u:43.93 v:42.84 average:33.70 min:32.22 max:40.48

測試結論: B幀沒有明顯收益

2.2 Android硬編碼實驗

另外,Android平臺只有高通晶片支援B幀編碼,而且Android現有的API中沒有開啟B幀功能的介面,預設是關閉B幀的,只有小米和三星等少數平臺開啟了B幀編碼。

2.2.1 測試方案

Android平臺只有高通支援B幀,並且受限於Android系統,無法控制B幀是否開啟,除非修改Android原始碼。目前只有小米和三星兩家的高通手機對高通支援比較好。

所以本人選取兩臺手機:

機型 Android CPU 是否支援B幀
Mi 5s 7.0 驍龍821
Pixel 9.0 驍龍821

輸入同一個視訊,用硬編碼進行轉碼,引數設定如下:

Bitrate: 3000Kb/s
Bitrate-Mode: VBR
Profile: High Profile
Frame-Rate: 30
Frame-Interval: 1

2.2.2 測試視訊

同軟編碼實驗。

2.2.3 評估方法

同軟編碼實驗。

2.2.4 測試結果

機型 是否支援B幀 PSNR
mi5s PSNR y:44.02 u:42.74 v:44.60 average:43.83 min:42.15 max:46.13
pixel PSNR y:44.10 u:42.91 v:44.77 average:43.94 min:42.08 max:46.13

2.2.5 總結

很尷尬……硬編碼測試的結果都說明B幀收益不大-_-!!

3. 結論

B幀不管是軟編碼還是硬編碼都沒什麼收益。