H264編碼系列之profile & level控制

2020-08-11 16:34:36

Sequence Paramater Set(SPS)(序列參數集)

(1). profile_idc:

標識當前H.264碼流的profile。我們知道,H.264中定義了三種常用的檔次profile:

  • 基準檔次:baseline profile;
  • 主要檔次:main profile;
  • 擴充套件檔次:extended profile;

在H.264的SPS中,第一個位元組表示profile_idc,根據profile_idc的值可以確定碼流符合哪一種檔次。判斷規律爲:

  • profile_idc = 66 → baseline profile;
  • profile_idc = 77 → main profile;
  • profile_idc = 88 → extended profile;

在新版的標準中,還包括了High、High 10、High 4:2:2、High 4:4:4、High 10 Intra、High 4:2:2 Intra、High 4:4:4 Intra、CAVLC 4:4:4 Intra等,每一種都由不同的profile_idc表示。

另外,constraint_set0_flag ~ constraint_set5_flag是在編碼的檔次方面對碼流增加的其他一些額外限制性條件。

在我們實驗碼流中,profile_idc = 0x42 = 66,因此碼流的檔次爲baseline profile。

(2). level_idc

標識當前碼流的Level。編碼的Level定義了某種條件下的最大視訊解析度、最大視訊影格率等參數,碼流所遵從的level由level_idc指定。

當前碼流中,level_idc = 0x1e = 30,因此碼流的級別爲3。

(3). seq_parameter_set_id

表示當前的序列參數集的id。通過該id值,影象參數集pps可以參照其代表的sps中的參數。

(4). log2_max_frame_num_minus4

用於計算MaxFrameNum的值。計算公式爲MaxFrameNum = 2^(log2_max_frame_num_minus4 + 4)。MaxFrameNum是frame_num的上限值,frame_num是影象序號的一種表示方法,在幀間編碼中常用作一種參考幀標記的手段。

(5). pic_order_cnt_type

表示解碼picture order count(POC)的方法。POC是另一種計量影象序號的方式,與frame_num有着不同的計算方法。該語法元素的取值爲0、1或2。

(6). log2_max_pic_order_cnt_lsb_minus4

用於計算MaxPicOrderCntLsb的值,該值表示POC的上限。計算方法爲MaxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4)。

(7). max_num_ref_frames

用於表示參考幀的最大數目。

(8). gaps_in_frame_num_value_allowed_flag

標識位,說明frame_num中是否允許不連續的值。

(9). pic_width_in_mbs_minus1

本句法元素加 1 後指明影象寬度,以宏塊爲單位:

PicWidthInMbs = pic_width_in_mbs_minus1 + 1

通過這個句法元素解碼器可以計算得到亮度分量以畫素爲單位的影象寬度:

PicWidthInSamplesL = PicWidthInMbs * 16

從而也可以得到色度分量以畫素爲單位的影象寬度:

PicWidthInSamplesC = PicWidthInMbs * 8

以上變數 PicWidthInSamplesL、PicWidthInSamplesC 分別表示影象的亮度、色度分量以畫素爲單位的寬。

H.264 將影象的大小在序列參數集中定義,意味着可以在通訊過程中隨着序列參數集動態地改變影象的大小,在後文中可以看到,甚至可以將傳送的影象剪裁後輸出。

(10). pic_height_in_map_units_minus1

本句法元素加 1 後指明影象高度:

PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1
PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits

影象的高度的計算要比寬度的計算複雜,因爲一個影象可以是幀也可以是場,從這個句法元素可以在幀模式和場模式下分別計算出出亮度、色度的高。值得注意的是,這裏以 map_unit 爲單位,map_unit的含義由後文敘述。

(11). frame_mbs_only_flag

標識位,說明宏塊的編碼方式。當該標識位爲0時,宏塊可能爲幀編碼或場編碼;該標識位爲1時,所有宏塊都採用幀編碼。根據該標識位取值不同,PicHeightInMapUnits的含義也不同,爲0時表示一場數據按宏塊計算的高度,爲1時表示一幀數據按宏塊計算的高度。

按照宏塊計算的影象實際高度FrameHeightInMbs的計算方法爲:

FrameHeightInMbs = ( 2 − frame_mbs_only_flag ) * PicHeightInMapUnits

(12). mb_adaptive_frame_field_flag

標識位,說明是否採用了宏塊級的幀場自適應編碼。當該標識位爲0時,不存在幀編碼和場編碼之間的切換;當標識位爲1時,宏塊可能在幀編碼和場編碼模式之間進行選擇。

(13). direct_8x8_inference_flag

標識位,用於B_Skip、B_Direct模式運動向量的推導計算。

(14). frame_cropping_flag

標識位,說明是否需要對輸出的影象幀進行裁剪。

(15). vui_parameters_present_flag

標識位,說明SPS中是否存在VUI資訊。

H264編碼profile & level控制

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

  1. Baseline Profile:基本畫質。支援I/P 幀,只支援無交錯(Progressive)和CAVLC;
  2. Extended profile:進階畫質。支援I/P/B/SP/SI 幀,只支援無交錯(Progressive)和CAVLC;(用的少)
  3. Main profile:主流畫質。提供I/P/B 幀,支援無交錯(Progressive)和交錯(Interlaced), 也支援CAVLC 和CABAC 的支援;
  4. High profile:高階畫質。在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主要參數

下圖清楚的給出不同的profile&level的效能區別。

 

不同profile支援的參數特性

Level 主要參數

不同Level對應的特性

ffmpeg如何控制profile&level

舉3個例子:

ffmpeg -i input.mp4 -profile:v baseline -level 3.0 output_baseline_30.h264
ffmpeg -i input.mp4 -profile:v main -level 4.2 output_main_42.h264
ffmpeg -i input.mp4 -profile:v high -level 5.1 output_high_51.h264

轉碼後用mediainfo進行分析

  •  

     

    output_baseline_30.h264 baseline對應profile_idc = 66,level對應level_idc=30。

    output_baseline_30.h264

  •  

     

    output_main_42.h264 baseline對應profile_idc = 77,level對應level_idc=42。

    output_main_42

  •  

     

    output_high_51.h264 baseline對應profile_idc = 100,level對應level_idc=51。

    output_high_51

如果ffmpeg編譯時加了external的libx264,那就這麼寫:

ffmpeg -i input.mp4 -c:v libx264 -x264-params "profile=high:level=3.0" output.mp4

 

 

通常情況下壓縮比例來說,baseline< main < high,對於頻寬比較侷限的線上視訊,可能會選擇high,但有些時候,做個小視訊,希望所有的裝置基本都能解碼(有些低端裝置或早期的裝置只能解碼 baseline),那就犧牲檔案大小吧,用baseline!

不同profile和level壓縮後的檔案大小對比