1. 程式人生 > >H.264編碼格式分析

H.264編碼格式分析

mas rail head nalu 比特流 包括 val slice raw

  H.264的重要性不再提了。本文主要記錄一下H.264的編碼格式。H.264官方文檔:https://github.com/jiayayao/DataSheet/tree/master/encode-decode/h264。

  H.264從層次來看分為兩層:視頻編碼層(VCL, Video Coding Layer)和網絡提取層(NAL,Network Abstraction Layer)。VCL輸出的是原始數據比特流(SODB,String of data bits),表示H.264的語法元素編碼完成後的實際的原始二進制碼流。SODB通常不能保證字節對齊,故需要補齊為原始字節序列負荷(RBSP,Raw Byte Sequence Payload)。NAL層實際上就是最終輸出的H.264碼流,它是由一個個NALU組成的,每個NALU包括一組對應於視頻編碼數據的NAL頭信息和一個原始字節序列負荷(RBSP,Raw Byte Sequence Payload)。以上名詞之間的關系如下:

RBSP = SODB + RBSP trailing bits
NALU = NAL header(1 byte) + RBSP
H.264 = Start Code Prefix(3 bytes) + NALU + Start Code Prefix(3 bytes) + NALU +…

  所以H.264碼流的結構如下:

技術分享

  每個NALU之間由起始碼(Start Code Prefix)分隔,起始碼分為兩種:0x000001(3 bytes) or 0x00000001(4 bytes). 如果NALU 對應的Slice 為一幀的開始,則用4 字節表示,即0x00000001;否則用3 字節表示,0x000001.NALU針對起始碼設計了防止沖突機制,如果出現連續的0x000000,0x000001,0x000002,0x000003時,會在兩個0之間插入03,如下:

0x00 00 00 -> 0x00 00 03 00
0x00 00 01 -> 0x00 00 03 01
0x00 00 02 -> 0x00 00 03 02
0x00 00 03 -> 0x00 00 03 03

  一個NALU就是編碼後的一幀數據。NAL header是一個字節:

  forbidden_zero_bit(1 bit) 禁止位,等於0;

  nal_ref_idc(2 bit)指示當前NAL的優先級,取值範圍為0~3,值越高,表示當前NAL越重要。H.264規定,如果當前NAL是序列參數集,或是圖像參數等,該值必須大於0.比如nal_unit_type等於5時,nal_ref_idc大於0;nal_unit_type等於6,9,10,11或12時,nal_ref_idc等於0;

  nal_unit_type表示當前NALU的類型,表格如下:

nal_unit_type

NAL類型

C

0

未使用

1

不分區、非IDR圖像的片

2,3,4

2

片分區A

2

3

片分區B

3

4

片分區C

4

5

IDR圖像中的片

2,3

6

補充增強信息單元(SEI)

5

7

序列參數集(SPS)

0

8

圖像參數集(PPS)

1

9

分界符

6

10

序列結束

7

11 碼流結束 8
12 填充 9
13~23 保留
24~31 未使用

  nal_unit_type=5時,表示當前NAL是IDR圖像的一個片,此時,IDR圖像中的每個片的nal_unit_type都應該等於5.

  一般H.264原始碼流是以SPS->PPS->SEI->IDR->SCLICE->SCLICE…開頭的。

  附:

  leixiaohua的H.264分析器,本人在此基礎上做了大量註釋,方便理解H.264:https://github.com/jiayayao/h264_analysis。

H.264編碼格式分析