音視訊高手課07-視訊流H264碼流分析實戰
1.1 H.264編碼格式
H.264的功能分為兩層:
- 視訊編碼層
- 網絡提取層
H.264 的編碼視訊序列包括一系列的NAL 單元,每個NAL 單元包含一個RBSP。一個原始的H.264由N個NALU單元組成、 NALU 單元常由 [StartCode] [NALU Header] [NALU Payload] 三部分組成,其中 Start Code 用于标示這是一個NALU 單元的開始,必須是"00 00 00 01" 或"00 00 01"。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SNwIDMlZjY3QTO5MTOiJTOmV2NlljYwEWNiRTNxUDN48CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
1.2 H.264網絡傳輸
H.264的編碼視訊序列包括一系列的NAL單元,每個NAL單元包含一個RBSP,
見表1。編碼片(包括資料分割片IDR片)和序列RBSP結束符被定義為VCL NAL單元,其餘為NAL單元。
典型的RBSP單元序列如圖2所示。
RBSP 順豐 頭 順豐公司尾部
每個單元都按獨立的NAL單元傳送。單元的資訊頭(一個位元組)定義了RBSP單元的類型,NAL單元的其餘部分為RBSP資料。
- 2.1 H.264碼流結構圖
起始碼:如果NALU對應的Slice為一幀的開始,則用4位元組表示,即0x00000001;否則用3位元組表示,0x000001。 NAL Header:forbidden_bit,nal_reference_bit(優先級),nal_unit_type(類型)。 脫殼操作:為了使NALU主體不包括起始碼,在編碼時每遇到兩個位元組(連續)的0,就插入一位元組0x03,以和起始碼相差別。解碼時,則将相應的0x03删除掉。
H.264解碼 NAL頭資訊的nal_referrence_idc(NRI)用于在重建過程中标記一個NAL單元的重要性,
- 值為0表示這個NAL單元沒有用預測,是以可以被解碼器抛棄而不會有錯誤擴散;
- 值高于0表示NAL單元要用于無漂移重構,且值越高,對此NAL單元丢失的影響越大。
- NAL頭資訊的隐藏比特位,在H.264編碼器中預設為0,當網絡識别到單元中存在比特錯誤時,可将其置為1。隐藏比特位主要用于适應不同種類的網絡環境(比如有線無線相結合的環境)。
NAL單元解碼的流程為:首先從NAL單元中提取出RBSP文法結構,然後按照如圖4所示的流程處理RBSP文法結構。輸入的是NAL單元,輸出結果是經過解碼的目前圖像的樣值點。 NAL單元中分别包含了序列參數集和圖像參數集。圖像參數集和序列參數集在其他NAL單元傳輸過程中作為參考使用,在這些資料NAL單元的片頭中,通過文法元素pic_parameter_set_id設定它們所使用的圖像參數集編号;而相應的每個圖像參數集中,通過文法元素seq_paramter_set_id設定他們使用的序列參數集編号。
幾個例子:
硬解--soc 晶片
軟體 ffmpeg
3、 ffmpeg解析H264流程分析
這是一段實際的碼流
ffmpeg -i input.mp4 -vcodec h264 -preset fast -b:v 2000k hello.h264
後續:
- 音視訊格式封裝原理
- 視訊壓縮原理
- 幀内預測
- 切片
- H264分層
- 手寫H264編碼器