視訊序列

宏塊結構
NALU分層
H264的主要目标是為了有高的視訊壓縮比和良好的網絡親和性,為了達成這兩個目标,H264的解決方案是将系統架構分為兩個層面,
VCL(視訊編碼層)和 NAL(網絡提取層).
- VCL:包括核心壓縮引擎和塊,宏塊和片的文法級别定義,設計目标是盡可能地獨立于網絡進行高效的編碼。
- NAL:負責将VCL産生的比特字元串适配到各種各樣的網絡和多元環境中,覆寫了所有片級以上的文法級别。
NALU:(Network Abstract Layer Unit)網絡抽象層單元。
RBSP:(Raw Byte Sequence Payload)原始位元組序列載荷。
SODB:String Of Data Bits (原始資料比特流, 長度不一定是8的倍數,故需要補齊,是由VCL産生)。
SODB是以值為1的一個比特結束,如果沒有位元組對齊,就用0補齊,是以從後往前第一個值為1的位置就為,SODB的最後一個位元組。
邏輯關系:RBSP trailing bits 是拖尾位元組,用于位元組對齊。
![]()
H.264(一)NALU解析 其實嚴格來說,這個等式是不成立的,因為RBSP并不等于NALU刨去NALU Header。嚴格來說,NALU的組成部分應為:
NALU = NALU Header + EBSP
其中的EBSP為擴充位元組序列載荷(Encapsulated Byte Sequence Payload),而RBSP為原始位元組序列載荷(Raw Byte Sequence Payload)。那為什麼我們上面,沒有使用2式而使用了1式呢?那是因為,在h264的文檔中,并沒有EBSP這一名詞出現,但是在h264的官方參考軟體JM裡,卻使用了EBSP。
EBSP相較于RBSP,多了防止競争的一個位元組:0x03。
我們知道,NALU的起始碼為0x000001或0x00000001,同時H264規定,當檢測到0x000000時,也可以表示目前NALU的結束。那這樣就會産生一個問題,就是如果在NALU的内部,出現了0x000001或0x000000時該怎麼辦?
是以H264就提出了“防止競争”這樣一種機制,當編碼器編碼完一個NAL時,應該檢測NALU内部,是否出現如下左側的四個序列。當檢測到它們存在時,編碼器就在最後一個位元組前,插入一個新的位元組:0x03。
這樣一來,當我們拿到EBSP時,就需要檢測EBSP内是否有序列:0x000003,如果有,則去掉其中的0x03。這樣一來,我們就能得到原始位元組序列載荷:RBSP。![]()
H.264(一)NALU解析
總結:H264的碼流結構如下:
H.264(一)NALU解析
NALU分層結構
RTP包的NALU類型介紹
單一類型:一個RTP包隻包含一個NALU
組合類型:一個RTP包含多個NALU,類型是24 —— 27
分片類型:一個NALU單元分成多個RTP包,類型是28和29
單一NALU的RTP包
組合NALU的RTP包
分片NALU的RTP包
H264句法元素解析流程
而當我們拿到RBSP或SODB之後,就可以對照各類型的NALU,去解析它們的文法元素,進而再根據文法元素,重建圖像。其中解析文法元素的框圖如下:
由圖可見,解析NALU的各個句法元素并不難,隻要根據h264文檔對應章節的句法,并配合相應的編解碼算法解析即可。而相應的編解碼算法如指數哥倫布編碼、CAVLC、CABAC、算術編碼,我們會一步步涉獵。