x264中的碼率控制算法

1. 碼率控制的選擇策略:�率失真優化模型

RDO: rate-distortion optimization率失真優化

限定碼率值Rc,選擇合適的編碼模式,使得失真D最小。

編碼模式包括量化步長、宏塊模式選擇、幀內/幀間預測模式選擇等。

碼率控制的RDO模型的目標是確定每幀或每個宏塊合適的量化步長。

1.1 Lagrangian RDO

H.264標準使用了一種基於Lagrangian優化算法的RDO模型實現碼率控制,數學原理很完美,但實際效果不是很好,所以實用中很少使用。

在數學最優化問題中,拉格朗日乘數法是一種尋找變量受一個或多個條件所限制的多元函數的極值的方法。這種方法將一個有n 個變量與k 個約束條件的最優化問題轉換爲一個有n + k個變量的方程組的無條件極值問題,進而採用偏微分或全微分法就能很容易求出其極值。

1.2 X264碼率控制算法

而X264編碼器的碼率控制算法與H.264標準的有很大差別,主要是根據經驗總結出來的算法。

2. X264的碼率控制的幾個基本原則

(1) 我們希望獲得恆定視覺質量的編碼碼流,但是恆定視覺質量並不意味着恆定的PSNR或QP。對高複雜度、高運動感的圖像,人眼並不會注意到細節,因而可以在某種程度上增大QP而達到相同的視覺質量。

(2) 根據圖像的重要性來確定不同的QP。由於B幀不用於預測任一其他幀,故其重要性相對於I、P幀要低,因而B幀的量化步長可以較大。

3. X264的RDO模型

X264採用一種半精度幀的SATD(sum of absolute transformed difference)作爲模式選擇的依據。SATD是將殘差做hadamard變換再取絕對值的總和,它作爲一種簡單的時頻變換,能在一定程度上衡量生成碼流的大小。下圖是一個簡單的2x2的Hadamard變換矩陣:

 

4. 碼率控制的三種思路-CBR,VBR,ABR

CBR: constants bit rate, 固定碼率編碼器的輸出碼率是一個固定值。

在一個帶寬受限的信道中進行多媒體通訊的時候CBR是非常有用的,但是CBR不適合進行存儲,因爲CBR會導致沒有足夠的碼率對複雜的內容進行編碼,使複雜內容的質量下降,同時對簡單的內容會浪費一些碼率,這時VBR是較好的選擇。

VBR: Variable Bit Rate,可變比特率

其原理就是將圖像中的複雜部分用高比特率編碼,簡單部分用低比特率編碼,通過這種動態調整編碼速率的方式,進一步得到視頻質量和比特率之間的平衡。它的主要優點是可以讓每一幀都能大致達到相同的視覺質量,缺點是編碼時無法估計壓縮出來的文件大小。

ABR: Average Bit Rate,平均比特率

可以做爲VBR和CBR的一種折衷選擇

5. X264中所用的ABR算法

第一,對當前圖像做抽樣濾波,得到分辨率是原來一半的小圖,在小圖上做半像素精度預測,與原圖相減得到殘差Xd,再對Xd做hadamond變換並求絕對和得到SATD,當前圖像的複雜度就是由當前幀SATD與之前幀SATD值的加權平均構成。

如:設第一幀SATD1=100262,第二幀SATD2=12812,第三幀SATD3=12022,則當前幀的複雜度爲:

接着由速率控制公式計算相應的qpscale:

其中qcomp爲線性量化控制參數,0爲固定碼率,1爲固定QP,默認值是0.6。

第二,再由之前圖像的編碼信息確定比例因子rate_factor調整qpscale的值,使得編碼速率儘可能接近所要求的平均比特率。若之前已編碼幀的實際比特數越是大於目標比特數,rate_factor越小,縮放後的qpscale就越大,量化步長也越大,生成的比特流越小,從而達到調整比特率的目的。

rate_factor的確定

編碼前會初始化一個長期複雜度累積因子:

complex_sum = 0.01 * 700000f_qcompress * sqrt(mb_count)

當前幀編碼完會使用下述公式累積長期複雜度累積因子:

complex_sum += bits * (0.85 * 2(qp-12)/6) / qp

  由上式可以看出長期複雜度因子與已編碼的比特數正相關。

然後計算截止到當前幀的目標比特數:

wanted_bits_window += bitrate/fps

而rate_factor就是wanted_bits_window與complex_sum的比值:

rate_factor = wanted_bits_window / complex_sum

第三,對qpscale做溢出補償處理,通過補償能夠合理控制文件的大小,但在一定程度上會降低質量:

            qpscale = qpscale x overflow

            overflow  = 1.0 +(total_bits – wanted_bits_window)/abr_buffer

如果實際編碼比特數total_bits大於目標比特數,overflow大於1,qpscale被放大,從而生成更少的碼流;相反如果實際比特數小於目標比特數,overflow小於1,qpscale被縮小,量化步長變小,從而生成更多的碼流,調整了比特率。   

第四,由qpscale得到當前幀的量化步長qp:

6. X264中所用的CBR算法

第一步與ABR算法一樣,算出當前幀的複雜度之後,使用qcomp=0來計算當前幀的qpscale:

在第二步中CBR所用的rate_factor不是由前面幀確定的,而是由當前vbv_buffer的大小決定的。

Video Buffering Verifier,視頻緩存檢驗器

VBV buffer 的作用是處理各幀編碼後大小不一和輸出CBR 的矛盾。

CBR規定encoder的輸出碼率爲恆定,但是各幀編碼後的大小不是固定的(I,B,P幀的存在),因此需要在encoder後面加入VBV buffer。�可以將VBV buffer想象成爲一個水池,水池的入口連接着encoder的輸出,水池的出口爲恆定的碼率輸出。�爲了使得輸出恆定,encoder必須保證水池既不上溢也不下溢。下溢會導致無數據輸出,上溢會導致數據丟失。�所以encoder在編碼一幀時會參考當前vbv buffer的充盈情況,推算出一個rate_factor,用來調整當前幀的量化步長,進而確定當前幀應當編碼多少比特才能保證vbv_buffer既不上溢也不下溢。

第三,CBR的溢出補償更加嚴格,而且在VBV接近0時將會強制限制QP。但在VBV沒用完時並不會強制限制QP,所以CBR的結果多少會比目標碼率低一點。還要注意的是,如果在所有機制過後,一個幀還是超出了VBV的限制,那它是不會被重新編碼的。

7. X264中所用的CRF算法

恆定碼率因子碼率控制算法

第一步同ABR算法。

第二步rate_factor恆定爲參數-crf所指定的值。

第三步沒有溢出補償。

8. X264所用的CQP算法

恆定量化參數碼率控制法

QP只是簡單的和幀類型相關

比如I幀使用QP=26的量化步長,P幀使用QP=28,B幀使用QP=30。

9. X264所用的自適應量化模型

自適應量化模式Adaptive Quantization Mode。

AQ可以更好把碼率分配到各個宏塊中。

它的基本原理也是根據當前宏塊的複雜度SADT,並與當前幀的平均複雜度做對比,若高於平均,則分配更多的碼率,即用小於當前幀QP值的量化步長;低於平均值則分配更少的碼率,即用大於當前幀的QP值的量化步長。

具體到每一個mb,x264又使用了一種複雜的mb-tree的宏塊級的碼率分配算法。

10. 動態碼率分配

針對丟包率相對固定的環境,動態碼率分配(DBA)功能可以在視頻通話過程中自動且動態地調整視頻碼率,以消除或避免丟包。例如,在一個384 kbps的視頻通話中(320 kbps用於視頻,64kbps用於音頻)檢測到一個穩定在10%的丟包率,DBA就會降低約10%視頻碼率,由320kbps降到288kbps左右。然後重新採樣信號,觀察是否還存在丟包現象。如果有必要,DBA可以進一步降低視頻碼率,直到在數秒內不再出現丟包爲止。   

在降低碼率後,如果DBA測定丟包只是暫時的(持續時間不到幾秒鐘),DBA將逐步增加視頻碼率。然而,如果DBA持續檢測到丟包現象,它就不再調整視頻碼率,並將通話繼續進行下去。這一方法,使得DBA非常適合於由網絡過度使用或因吞吐量問題引起的丟包現象。

11. 在不同碼控下的測試結果

 



作者:青劍湖畔
鏈接:https://www.jianshu.com/p/ce7d2d23ed66
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

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