ffmpeg 碼率控制(總結篇)

本文僅探討ffmpeg API編碼的方式進行碼率控制,文中測試數據使用的是網絡傳輸場景,非本地測試,可能收到網絡的影響。如有不足之處,請及時指正。

CQP

CQP:Constant Quantization Parameter - 固定質量參數

每一幀圖像在壓縮時,採用相同的量化參數QP(量化參數QP定義了從一個像素宏塊中丟掉多少信息),單位像素丟掉的數據比例是一致的,然後再結合運動矢量,最終形成壓縮後的幀,不決定相對碼率的大小。

運行比較劇烈的幀相對於運動不劇烈的幀,單位時間內要表現的內容該多還是多,單位時間的碼率該高還是高。

代碼實現:

// CQP
av_opt_set(pOutVideoCodecCtx->priv_data, "qp", "23", AV_OPT_SEARCH_CHILDREN);

測試表現:
CQP

CRF

CRF:Constant Rate Factor - 限制碼率因子

CRF是264和265中默認的質量/碼率控制設置。這個值可以在0到51之間,值越低,質量越好,文件大小越大。

  1. 量化比例的範圍爲0~51,其中0爲無損模式,23爲缺省值,51可能是最差的。該數字越小,圖像質量越好。從主觀上講,18~28是一個合理的範圍。18往往被認爲從視覺上看是無損的,它的輸出視頻質量和輸入視頻一模一樣或者說相差無幾。但從技術的角度來講,它依然是有損壓縮。

  2. 若Crf值加6,輸出碼率大概減少一半;若Crf值減6,輸出碼率翻倍。通常是在保證可接受視頻質量的前提下選擇一個最大的Crf值,如果輸出視頻質量很好,那就嘗試一個更大的值,如果看起來很糟,那就嘗試一個小一點值。

CRF比CQP要一些,CRF會用將每一幀的壓縮不同的大小,爲了讓主觀的質量感受差不多,會用不同的QP。他是通過把運動也考慮進來做到這一點的。在編碼中,如果Qp=18,則每一幀都是QP=18,當然根據幀的類型不同會有一些微小的波動,忽略之。設置CRF=18的時候,對於運動比較大的場景,會把QP設得更高一些,對於運動比較比較不劇烈的幀,會降低QP。這會導致比特率的分配隨時間變化不同。

代碼實現:

// CRF
av_opt_set(pOutVideoCodecCtx->priv_data, "crf", "23", AV_OPT_SEARCH_CHILDREN);

測試表現:
CRF

CBR

CBR:Constant BitRate - 固定比特率

是恆定(固定)比特率,指文件每秒鐘的碼率是固定不變的。

CBR VBR ABR的區別
可參考:https://blog.csdn.net/Martin_chen2/article/details/105714088

代碼實現:

// CBR
int bitRate = 800000;
pOutVideoCodecCtx->bit_rate = bitRate;
pOutVideoCodecCtx->rc_min_rate = bitRate;
pOutVideoCodecCtx->rc_max_rate = bitRate;
pOutVideoCodecCtx->bit_rate_tolerance = bitRate;
pOutVideoCodecCtx->rc_buffer_size = bitRate;
pOutVideoCodecCtx->rc_initial_buffer_occupancy = pOutVideoCodecCtx->rc_buffer_size * 3 / 4;
pOutVideoCodecCtx->rc_buffer_aggressivity = (float)1.0;
pOutVideoCodecCtx->rc_initial_cplx = 0.5;

測試表現:
CBR從測試表現來看,ffmpeg只能盡力保證單位時間內的碼率爲相同值,但存在輕微的波動。

VBR

VBR:Variable BitRate - 動態比特率

單位時間內的碼率是可變的,使用VBR編碼時,系統將自動爲內容的簡單部分分配較少的比特,從而留出足量的比特用於生成高質量的複雜部分。

對於複雜性恆定的內容(例如新聞播音)不會受益於VBR編碼。對混合內容使用 VBR 編碼時,在文件大小相同的條件下,VBR編碼的輸出結果要比CBR編碼的輸出結果質量好得多。在某些情況下,與CBR編碼文件質量相同的VBR編碼文件, 其大小可能只有前者的一半。

代碼實現:

// VBR
pOutVideoCodecCtx->flags |= CODEC_FLAG_QSCALE;
pOutVideoCodecCtx->rc_min_rate = bitRate - 400000;
pOutVideoCodecCtx->rc_max_rate = bitRate + 400000;
pOutVideoCodecCtx->bit_rate = bitRate;

測試表現:
VBR從測試結果上看,VBR在傳輸時,碼率確實會上下浮動。

ABR

ABR:Average Bitrate - 平均碼率

平均比特率,是VBR的一種插值參數。Lame針對CBR不佳的文件體積比和VBR生成文件大小不定的特點獨創了這種編碼模式。ABR也 被稱爲“Safe VBR”,它是在指定的平均Bitrate內,以每50幀(30幀約1秒)爲一段,低頻和不敏感頻率使用相對低的流量,高頻和大動態表現時使用高流量。

代碼實現:

// ABR
pOutVideoCodecCtx->bit_rate = 800000;

測試表現:
ABR從測試結果上看,ABR相對於VBR,碼率更穩定一些。

H264編碼控制

ffmpeg中採用H264,H265標準編碼時,可能需要設置profilepresettune,ffmpeg中需要採用額外參數AVDictionary傳入avcodec_open2()函數中實現。

profile

H.264有四種畫質級別,分別是baseline, extended, main, high

profile取值 含義 釋義
baseline 基本畫質 支持I/P 幀,只支持無交錯(Progressive)和CAVLC
extended 進階畫質 支持I/P/B/SP/SI 幀,只支持無交錯(Progressive)和CAVLC(用的少)
main 主流畫質 提供I/P/B 幀,支持無交錯(Progressive)和交錯(Interlaced),也支持CAVLC 和CABAC 的支持
high 高級畫質 在main Profile 的基礎上增加了8x8內部預測、自定義量化、 無損視頻編碼和更多的YUV 格式

H.264 baseline profile、extended profile和main profile都是針對8位樣本數據、4:2:0格式(YUV)的視頻序列。在相同配置情況下,high profile(HP)可以比main profile(MP)降低10%的碼率。

根據應用領域的不同,Baseline profile多應用於實時通信領域,Main profile多應用於流媒體領域,High profile則多應用於廣電和存儲領域。

代碼實現:

// profile
av_dict_set(&param, "profile", "main", 0);

preset

preset值 釋義
ultrafast 極快
superfast 超快
veryfast 非常快
faster 更快
fast
medium
slow
slower 更慢
veryslow 非常慢
placebo 超慢

編碼加快,意味着信息丟失越嚴重,輸出圖像質量越差。

他們之間的區別這取決於源材料,目標比特率和您的硬件配置。 通常,比特率越高,編碼所需的時間越多。
這是一個示例,顯示了1080p視頻的兩次通過編碼的(標準化)編碼時間:
preset不同點示例

從中到慢,所需時間增加了約40%。 相反,變慢會導致所需時間增加大約100%(將花費兩倍的時間)。 與中等速度相比,veryslow需要原始編碼時間的280%,而質量較慢的速度只有很少的改進。
使用快速可節省大約10%的編碼時間,快則可節省25%。 超快將節省55%的成本,但質量要低得多。

代碼實現:

// preset
av_dict_set(&param, "preset", "veryfast", 0);

如果未配置該選項,或者採取較慢的速度,會導致CPU消耗過大的問題

tune

主要配合視頻類型和視覺優化的參數況。如果視頻的內容符合其中一個可用的調整值又或者有其中需要,則可以使用此選項,否則建議不使用(如tune grain是爲高比特率的編碼而設計的)。

tune值 釋義
film 電影、真人類型
animation 動畫
grain 需要保留大量的grain時用
stillimage 靜態圖像編碼時使用
psnr 爲提高psnr做了優化的參數
ssim 爲提高ssim做了優化的參數
fastdecode 可以快速解碼的參數
zerolatency 零延遲,用在需要非常低的延遲的情況下,比如電視電話會議的編碼

代碼實現:

// tune
av_dict_set(&param, "tune", "zerolatency", 0);

參考鏈接:
https://blog.csdn.net/owen7500/article/details/51832035
https://blog.csdn.net/DONGHONGBAI/article/details/84776431
https://www.cnblogs.com/tinywan/p/6402007.html
https://www.cnblogs.com/sunny-li/p/9979796.html
https://trac.ffmpeg.org/wiki/Encode/H.264

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