H.264碼流格式
SODB: String Of Data Bits 原始資料比特流, 熵編碼輸出結果, 以bit為機關。
RBSP: Raw Byte Sequence Payload 原始位元組序列負載, 在SODB最後加上trailing bits補齊為一個位元組
EBSP: Extent Byte Sequence Payload 擴充位元組序列負載, RBSP裡面加入防僞起始碼位元組(0x03)
NALU: Network Abstraction Layer Units. 網絡抽象層單元, 在EBSP前面加上一個位元組的NALU type.
H264起始碼
一個H.264碼流就是很多個NALU的串接,NALU之間靠起始碼分隔,找不到起始碼就找不到下一個NALU的開始,也就找不到目前NALU的結束。是以起始碼對于H.264碼流非常重要。
在264碼流裡面一般會用到兩種起始碼,4位元組 0x00 00 00 01或者3位元組 0x00 00 01. 一般4位元組起始碼用于SPS,PPS和每幀的第一個Slice,3位元組起始碼用于其他的NALU(例如多slice時一幀内的非第一slice)。
由于起始碼起到分隔NALU的作用,是以如果RBSP裡面恰好也出現了0x00 00 01的位元組組合,解碼端就會誤認為是下一個NALU的開始,這樣會造成解碼錯誤。是以要破壞掉RBSP裡面的這種位元組組合,這就是RBSP到EBSP的過程。
SODB -> RBSP
RBSP = SODB + trailing bits, 以位元組為機關
SODB是以比特為機關的,熵編碼的最後一個比特可能是一個位元組的任意位,這時候要先增加1個rbsp_stop_one_bit, 然後是n個rbsp_alignement_zero_bit.例如SODB寫到一個位元組的2比特,會補1個"1",5個"0"比特,寫滿這個位元組。
RBSP -> EBSP
EBSP = RBSP 加入防僞起始碼位元組(0x03)
周遊RBSP找 0x00 00 0z z=1,2,3的位元組組合,如果發現有這樣的組合,就在0z之前強行插入0x03位元組,破壞掉類似起始碼的位元組組合.
具體點說就是做一下的操作。(為什麼對02/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後,對于EBSP,掃描一遍剔除 0x 00 00 03 0z (z=0,1,2,3)之間的03位元組,生成RBSP。
EBSP -> NALU
NALU = 1位元組 NALU type | EBSP
NALU type: 1 bit | 2bits | 5bits
禁止比特 恒為0 nalu重要性比特 nalu類型比特