H264編碼的場格式編碼
視訊的幀和場是由於歷史原因引入的,早期的視訊採集和輸出裝置效率不高導致。
在CIF,D1影象大小的標清年代,CRT顯示器傳輸頻寬不夠,逐行掃描的方法通常從上到下地掃描每幀影象。這個過程消耗的時間比較長,陰極射線的熒光衰減將造成人視覺的閃爍感覺。當頻寬受限,以至於不可能快到使用逐行掃描而且沒有閃爍效應時,通常採用一種折衷的辦法,即每次只傳輸和顯示一半的掃描線,即場。一場只包含偶數行(即偶場)或者奇數行(即奇場)掃描線。由於視覺暫留效應,人眼不會注意到兩場只有一半的掃描行,而會看到完整的一幀。
攝像機採集的方式和隔行掃描顯示的方式是完全相同的。當攝像機採集影象時,偶場和奇場不是同時採集的。例如在一個每秒50場的攝像機中,第122行和124行的採集在第121行和123行的採集大約1/50秒之後進行。所以如果把一個偶場和奇場簡單的拼合在一起,水平方向的運動會造成兩場邊界上不能完美的拼合。
隨著時代的進步,當代的顯示器,電視,攝像機,由於逐行顯示和採集的重新整理率的提高,已經不會再感覺到閃爍現象,因此,隔行掃描技術逐漸被取代。
但歷史帶來的遺留問題也遺留了下來,雖然現在一些視訊採集和播放裝置能支援高清,超高清和逐行掃描,但隔行這種場格式還是保留了下來。
H264對幀場的支援
H264標準也是標清時代的產物,所以H264編碼器是支援幀和場的。
H264編碼序列幀、場編碼方式
1.固定幀編碼
整個視訊序列的幀始終採用幀編碼方式。這是我們最常用的方式,高清時代都基本都是幀編碼。這是我們最常用的一種模式。
2.固定場編碼
整個視訊序列中幀被分成兩個場(頂場和底場)獨立編碼。
1) I幀可編碼成 II, IP
II是指兩個I場,即第一個I幀是上半場,第二個I幀是下半場。
IP是指編碼成IP,即第一個I幀是上半場,第二個P幀內容是下半場。
2)P幀可編碼成PP、PB.
PP是指第一個P幀是上半場,第二個P幀是下半場。
PB是指第一個P幀是上半場,第二個B幀內容是下半場。
3) B幀可編碼成兩個B場,BB
BB是指第一個B幀是上半場,第二個B幀是下半場。
3.影象級幀、場自適應編碼 (PAFF)
視訊序列以幀為單位,被編碼成一個幀或兩個場,自適應選擇原則是根據採用該種編碼方式的每一幀的RD值。
這種模式在實際H264編碼中用的很少,除非是為了演算法研究,做應用的同學們可以忽略。
4.巨集塊級幀、場自適應(MBAFF)
視訊序列以巨集塊為單位,MBAFF採用了巨集塊級幀場自適應.,巨集塊級採用了巨集塊對(MBP)為基本編碼單元。
同樣這種模式在實際H264編碼中用的很少,除非是為了演算法炫技,做應用的同學們可以忽略。
幀場在H264碼流裡的標誌位
在H.264的碼流裡有四個引數來描述上一小節的內容。
frame_mbs_only_flag
標識位說明巨集塊的編碼方式。當該標識位為0時,巨集塊可能為幀編碼或場編碼;該標識位為1時,所有巨集塊都採用幀編碼。根據該標識位取值不同,PicHeightInMapUnits的含義也不同,為0時表示一場資料按巨集塊計算的高度,為1時表示一幀資料按巨集塊計算的高度。
按照巨集塊計算的影象實際高度FrameHeightInMbs的計算方法為:
FrameHeightInMbs = ( 2 − frame_mbs_only_flag ) * PicHeightInMapUnits
mb_adaptive_frame_field_flag
標識位,說明是否採用了巨集塊級的幀場自適應編碼。當該標識位為0時,不存在幀編碼和場編碼之間的切換;當標識位為1時,巨集塊可能在幀編碼和場編碼模式之間進行選擇。
field_pic_flag
標識位說明當前影象是幀編碼(0)還是場編碼(1)。這個元素在同一影象的所有片中應具有相同值。僅當序列引數集中的frame_mbs_only_flag為0時,這個元素才會出現在碼流中。
bottom_field_flag
標識位說明當前的場是頂場還是底場。值為1 時表示當前影象是屬於底場;等於 0 時表示當前影象是屬於頂場。這個標識位僅當field_pic_flag存在且為1時,才會出現在碼流中。
frame_mbs_only_flag | mb_adaptive_frame_field_flag | field_pic_flag | 模式 |
1 | 無 | 無 | 幀編碼 |
0 | 0 | 0 | 幀編碼 |
0 | 0 | 1 | 場編碼 |
0 | 1 | 0 | 幀場自適應 |
0 | 1 | 1 | 場編碼 |
H264場格式碼流例子
從上面的例子碼流標識中可以看到
frame_mbs_only_flag = 0 ; //視訊內巨集塊可能為幀編碼或場編碼
mb_adaptive_frame_field_flag = 0; //幀編碼和場編碼之間沒有自適應切換
field_pic_flag = 1; //確定當前影象是場編碼,I幀是頂場,P幀是低場。用的是IP和PP模式
目前有的解碼器能支援頂場和低場分別送給解碼器解碼,有的解碼器不支援,需要把上下半場合在一起送給解碼器解碼才能正常解碼,輸出完整影象。