碼率控制(一):理解碼率控制模式(x264,x264,vpx)

碼率控制(一):理解碼率控制模式(x264,x264,vpx)

什麼是“碼率控制”?它是編碼器決定爲每幀視頻分配多少比特的工具。


視頻編碼(有損)的目標是儘可能多的節省比特(碼率)的同時儘量保持視頻質量。碼率控制是平衡碼率和質量的重要工具。

碼率控制有多種方式,你將會瞭解到"1-pass","2-pass","CBR","VBR","VBV Encoding"和"CRF"等。

下面是不同碼率控制模式的簡單示例,它告訴你作爲終端用戶應該在什麼時候用什麼模式。注意這裏不包含RDO的具體細節。

序言:可變碼率 VS 固定碼率

很多人可能更熟悉音頻編碼器,尤其是那些經歷了MP3年代的人。不過從CD的發展史來說,最開始使用固定碼率(Constant Bitrate,CBR)編碼,後來發展出了可變碼率(Variable Bitrate,VBR)。VBR可以確保在給定限制下使用最少的比特情況下保持最高質量。

簡單說,VBR可以使編碼器在難編碼的地方花費更多比特,在編碼簡單的地方花費更少比特。對編碼來說“難編碼”和“容易編碼”代表什麼呢?通常有大量運動的視頻需要更多比特,空間細節豐富和紋理複雜的視頻也較難編碼。

編碼場景有哪些?

選擇哪種碼率控制模式往往取決於你的應用場景。通常有以下幾種常見場景:

  1. 存檔:壓縮一個文件存到硬盤或網盤上。這時你希望文件編碼後質量儘可能好同時碼率儘可能低,但是你不關心壓縮後文件的具體大小。

  2. 流媒體:你想要通過網絡傳輸一個文件。這是你要確保文件碼率不超過網絡帶寬,或者你需要在不同帶寬下提供不同碼率的文件。(例如,在網上看視頻網絡不好時將視頻從高清切換到低清)。

  3. 直播流:和2類似,但是你需要儘快編碼(實時),並且直播時你無法提前預知視頻內容。

  4. 面向設備的編碼:例如你想向DVD或藍光碟上存放文件,你想使文件編碼後達到特定大小(正好佔滿碟片空間)。

瞭解使用場景可以幫助你選擇碼率控制模式。

碼率控制模式

下面介紹不同的碼率控制模式,這些模式基於ffmpeg中的x264x265libvpx編碼器。你可以在ffmpeg文檔找到詳細參數介紹。

注意:編碼器默認不會“填塞”比特。意味着,當編碼簡單的幀時,實際使用比特可能低於設定的比特,這時編碼器不會浪費比特強行達到設定比特。

固定QP(Constant QP,CQP)

量化參數(Quantization Parameter,QP)控制着壓縮大小。QP越大壓縮率越高同時質量越低,QP越小壓縮率越低同時質量越高。在H.264和H.265中,QP的範圍是0-51間的整數。你可以很容易的在x264和x265中設置固定QP來編碼。注意:libvpx沒有固定QP模式。

ffmpeg -i <input> -c:v libx264 -qp 23 <output>
ffmpeg -i <input> -c:v libx265 -x265-params qp=23 <output>

可以參考這個教程瞭解更多QP的作用原理。

除非你明確的知道你想要做什麼,否則不要使用這個模式。採用CQP模式會導致根據場景複雜度不同比特率波動很大,你無法控制實際比特率。

好處:視頻編碼研究。

壞處:幾乎其他所有應用。

平均比特率(Average Bitrate,ABR)

下面是給定編碼器一個目標碼率,編碼器計算如何達到這個碼率:

ffmpeg -i <input> -c:v libx264 -b:v 1M <output>
ffmpeg -i <input> -c:v libx265 -b:v 1M <output>
ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M <output>

避免使用這個模式!x264的主要開發者之一說你應該永遠不要使用它。爲什麼?因爲編碼器不知道後面還未編碼的內容,所以它不得不猜測如何達到給定碼率。這意味着碼率要一直變化,尤其是在開始時。對於 HAS-type流,這會導致在短時間內質量巨大波動。

ABR不是一種恆定碼率模式而是可變碼率模式。

好處:快速編碼。

壞處:幾乎其他所有應用。

恆定碼率(Constant Bitrate,CBR)

通過設置nal-hrd可以使編碼器強制保持在特定碼率。

ffmpeg -i <input> -c:v libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v 1M -minrate 1M -maxrate 1M -bufsize 2M <output>

輸出文件必須是MPEG-2 TS文件,因爲mp4不支持NAL填充。注意這種模式對於簡單的視頻會浪費帶寬,但是它保證整個流的碼率一致。你可以在這裏找到更多用例。在某些應用中使用這種模式是有意義的,但是你可能希望在可能的時候碼率更低。

對於VP9使用CBR的命令如下:

ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -maxrate 1M -minrate 1M <output>

好處:保持恆定碼率;視頻流(例如:Twitch)。

壞處:文檔存儲;高效使用帶寬的場景。

2-Pass Average Bitrate (2-Pass ABR)

如果允許編碼器兩遍(或更多)編碼那麼它就可以預先估計未來還未編碼的內容。它可以在第一遍編碼是計算編碼代價,然後在第二遍編碼是更高效的利用比特。這種模式使得在特定碼率下輸出的質量最好。

對於x264:

ffmpeg -i <input> -c:v libx264 -b:v 1M -pass 1 -f null /dev/null
ffmpeg -i <input> -c:v libx264 -b:v 1M -pass 2 <output>.mp4

對於x265:

ffmpeg -i <input> -c:v libx265 -b:v 1M -x265-params pass=1 -f null /dev/null
ffmpeg -i <input> -c:v libx265 -b:v 1M -x265-params pass=2 <output>.mp4

對於VP9:

ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -pass 1 -f null /dev/null
ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -pass 2 <output>.webm

這是對流進行編碼的最簡單的方法。但有兩點注意:你不知道最終結果的質量如何,所以你必須進行多次實驗以確保給定的碼率足夠編碼複雜內容。另一點是這種模式碼率可能出現局部峯值,意味着發送能力可能超過客戶端的接受能力。對於碼率的選擇,你可以參考YouTube的推薦設置,但是注意這些都是爲了讓你上傳高質量的照片而優化的,實際中你可以選擇更低的碼率。

好處:達到特定碼率;面向設備的編碼。

壞處:如果你需要快速編碼(例如,直播流)。

Constant Quality (CQ) / Constant Rate Factor (CRF)

CRF可以保持整個視頻流質量恆定。

ffmpeg -i <input> -c:v libx264 -crf 23 <output>
ffmpeg -i <input> -c:v libx265 -crf 28 <output>
ffmpeg -i <input> -c:v libvpx-vp9 -crf 30 -b:v 0 <output>

在H.264和H.265中,CRF取值爲0到51間的整數(和QP類似)。x264默認值是23,x265默認值是28。CRF增減6會導致碼率減半或加倍。對於VP9,CRF取值範圍0到63,推薦值爲15-35。

這種模式缺點是無法確定最終文件的碼率和碼率波動。

好處:文檔存儲;達到儘可能好的質量。

壞處:流媒體;需要特定碼率(或文件大小)。

VBV(Video Buffering Verifier)

對於VBV可以確保碼率不超過某個最大值。這對於流媒體非常有用,你現在可以確定你不會發送比你承諾的更多的比特。VBV可以和2-pass VBR(在兩遍編碼中都使用)或CRF一起使用。

ffmpeg -i <input> -c:v libx264 -crf 23 -maxrate 1M -bufsize 2M <output>
ffmpeg -i <input> -c:v libx265 -crf 28 -x265-params vbv-maxrate=1000:vbv-bufsize=2000 <output>

VP9有類似的模式,不叫VBV,但是原理一樣:

ffmpeg -i <input> -c:v libvpx-vp9 -crf 30 -b:v 2M <output>

如果你在直播流中應用VBV,且你想加速編碼過程,你可以使用-tune zerolatency和-preset ultrafast選項。這會犧牲一部分質量來加速編碼。

在受約束的ABR-VBV中使用這種模式:

ffmpeg -i <input> -c:v libx264 -b:v 1M -maxrate 1M -bufsize 2M -pass 1 -f null /dev/null
ffmpeg -i <input> -c:v libx264 -b:v 1M -maxrate 1M -bufsize 2M -pass 2 <output>

對x265:

ffmpeg -i <input> -c:v libx265 -b:v 1M -x265-params pass=1:vbv-maxrate=1000:vbv-bufsize=2000 -f null /dev/null
ffmpeg -i <input> -c:v libx265 -b:v 1M -x265-params pass=2:vbv-maxrate=1000:vbv-bufsize=2000 <output>

對VP9:

ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -maxrate 1M -bufsize 2M -pass 1 -f null /dev/null
ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -maxrate 1M -bufsize 2M -pass 2 <output>

如何設置bufsize?這取決於你期望碼率的波動情況。一個好的設置方法是將bufsize設爲maximum rate的兩倍。如果客戶端緩存比較小,設置bufsize等於maxrate。如果你想限制碼流的碼率,設置bufsize爲maximum rate的一半或更小。

好處:帶寬受限的流媒體;直播流(使用CRF,1-pass);VoD流。

壞處:文檔存儲。

對比實驗

下面是不同碼率控制算法的比較。使用Big Buck BunnyTears of Steel序列,每個序列截取三段(每段30秒)。使用libx264編碼器,除了碼率控制模式不同外,其他都是默認設置。設置了不同的目標碼率(750,1500,3000,7500kbit/s)和最大碼率(針對VBV)和QP/CRF值(17,23,29,35)。

注意這個實驗並不充分,你可以嘗試更多的序列和使用不同編碼器。

下圖是使用不同碼率控制模式的結果。左邊是3000kbit/s的結果,右邊是7500kbit/s的結果。另兩種結果的圖像差不多,這裏不再展示。每條線代表不同模式下碼流的碼率變化情況。

從BBB1看出,ABR(藍綠色線)和ABR+VBV(紫色線)開始時錯估了視頻複雜度,實際是BBB視頻的開始部分比較平滑,運動比較小只需要很少的比特就可以保證質量。2-pass模式在開始時正確估計了複雜度,起始使用了低碼率節省了帶寬。視頻的後1/3部分,空間細節豐富使得2-pass模式消耗了大量比特,超過了起始節省的比特。

BBB2視頻裏,不同模式實際上比預期要好。但是2-pass的波動還是比其他模式更多。

 

下面是CQP和CRF的實驗情況,這裏只展示了CRF/CQP爲17和23的結果。CRF的效果更好。

 

下面是CRF+VBV在不同碼率下的結果。爲CRF選擇合適的目標碼率和最大碼率通常需要多次嘗試,完全取決於視頻源。

 

翻譯自Understanding Rate Control Modes (x264, x265, vpx)

感興趣的請關注微信公衆號Video Coding

 

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