劉敏慧,賀波濤
(1.武漢郵電科學研究院,湖北武漢430074;2.武漢烽火眾智數字技術有限公司,湖北武漢430074)
隨著我國經濟和社會的發展,網絡視頻監控在城鄉治安、交通等方面日益發揮著重要的作用,流媒體編解碼和監控視頻實時傳輸等技術是網絡視頻監控的關鍵技術[1]。從如今的編解碼技術來看,被市場廣泛采用的是H.264 標準,同時新一代的H.265 標準市場占比正在穩步提升,其優秀的視頻壓縮性能可以節約傳輸帶寬和存儲空間[2]。同時,網絡視頻監控[3]對實時的網絡傳輸有很大需求[4],實時傳輸協議(Real-time Transport Protocol,RTP)[5]解決了該問題,RTP 可采用用戶數據包協議(User Datagram Protocol,UDP)來實時傳輸數據,攝像頭在采集到監控視頻后,其H.265 碼流會被封裝在RTP信息包中,RTP 信息包被再次封裝為UDP 的負載,最終封裝在ip 數據包的負載中。文中研究的內容是如何從Wireshark 抓取的RTP 包中提取出H.265碼流并保存,且實現該碼流的高清流暢播放,保存的H.265 碼流可用作關鍵幀的提取、轉碼及圖像處理研究,具有較高的研究價值。
H.265 是繼H.264 之后,由ITU-T VCEG 組織發布的新一代視頻編碼標準[6]。H.265 標準基于現有的H.264 視頻編碼標準[7],保留了一部分原有技術,同時改進了一些相關技術。新標準使用先進的技術來改善碼流、編碼質量、延遲和算法復雜度之間的關系,以實現最佳設置。具體研究內容包括提高壓縮效率、提高魯棒性和錯誤恢復能力、降低實時時延、降低信道采集時間和隨機訪問時延、降低復雜度[8]。HEVC[9]不僅提升視頻質量,而且在相同的視頻質量的情況下,相比H.264 實現了兩倍的壓縮率,同時可支持4K清晰度,甚至最高清晰度可達到8K(8 192×4 320)[10]。
H.265 碼流[11]的圖像幀序列由起始碼(00 00 00 01 或00 00 01)、VPS、SPS、PPS、SEI、IDR 幀、P 幀、B幀、I幀等組成。
網絡抽象層(Network Abstraction Layer,NAL)是H.265 視頻編碼標準的一部分,NAL 負責格式化視頻數據并提供頭信息,從而保證視頻數據在各種信道和存儲介質上的穩定傳輸。H.265 碼流由一系列的NALU 組成,每個VPS、SPS、PPS、SEI、I 幀、P 幀都可以稱為一個NALU,常見NALU 類型如表1所示。

表1 常見NALU類型
NALU 的結構為NALU 頭+NALU 負載。H.265碼流的NALU 頭由兩個字節組成,它的語法如圖1所示。

圖1 NALU結構/FU indicator結構
F:1 bit,forbidden_zero_bit,在H.265 規范中規定了這一位必須為0。禁止位0 表示正常,1 表示錯誤,一般都是0。Type:6 bit,nal_unit_type,常見NALU 類型如表1所示。LayerID:6 bit,nuh_reserved_zero_6bits,為0。TID:3 bit,nuh_temporal_id_plus1,為1。
從RTP 數據包中提取H.265 碼流,首先需要抓取數據包。Wireshark 作為全世界最為流行的網絡封包分析軟件之一,可以抓取網絡封包,并且盡可能地顯示出最為詳細的信息。抓取的數據包可以保存為pcap 格式[12]的文件,文中就是從包含已抓取數據包的pcap 文件中提取H.265 碼流信息的[13]。pcap 文件的格式如圖2所示。

圖2 pcap文件格式
文中需要抓取的是攜帶著H.265 碼流信息的RTP 數據包,抓取時不可避免地捕獲ARP、TCP 等非必須數據包,可用Wireshark 本身的過濾規則來除去,也可在自制的提取碼流方案中添加規則過濾。文中推薦使用第二種方法,該方法普適性更好,給研發人員的自主性更大,在提取時也不會因為個別包的疏漏而出現問題。
從pcap 文件中提取H.265 碼流,需要獲取H.265碼流在網絡傳輸時的打包方式。文中的H.265 碼流在傳輸層采用的是UDP 協議,UDP 是開放式系統互聯(Open System Interconnection,OSI)參考模型中的一種無連接的傳輸層協議。相比于傳輸層另一種協議——傳輸控制協議(Transport Control Protocol,TCP),UDP 雖然提供不可靠的信息傳輸服務,但它額外開銷小、時延短、無連接,非常適合多媒體數據流的傳輸,在文中情況下,UDP 也是個好選擇[14]。
RTP 協議[15]規定了在互聯網上傳輸視頻和音頻的標準數據包格式,它創建在UDP 之上,并與之結合使用,方便RTP 使用其端口號和效驗服務,依托UDP低傳輸時延的特點,更好地匹配視頻傳輸業務。
RTP 包由包頭和負載兩部分組成[16],H.265 碼流數據存儲在RTP 數據包的負載中,其包頭中存儲了負載類型(payload typePT)、序列號(Sequence Number)、時間戳(Timestamp)、同步源標識符(SSRC)等信息,包頭的信息不是必要的,在設計時可以直接偏移12 字節到負載部分。
在以太網中,數據鏈路層能夠確定發送的一個數據包的最大長度稱為最大傳輸單元(Maximum Transmission Unit,MTU),為1 500 字節,文中采用的監控視頻的分辨率是1 920×1 080,由于通過H.265標準壓縮后的每幀圖像遠遠超過1 500 字節,因此為了實現H.265 碼流在網絡上的傳輸,必須對每幀圖像進行分割再打包成適合在以太網上傳輸的大小合適的RTP 數據包。
上文已知H.265 碼流由一系列的NALU 組成,每個VPS、SPS、PPS、SEI、I 幀、P 幀都可以稱為一個NALU,不同類型的NALU 之間大小差距很大[17]。對于VPS、SPS、PPS、SEI 等小于MTU 的NALU,打包時只需將該NALU 去掉起始碼并添加在RTP 包頭后即可。對于I 幀、P 幀等大于MTU 的NALU,使用FU 打包,就是將一個NALU 分片打包成幾個RTP 數據包,即fragmentation unit,簡稱FU。每個分片單元為12字節的RTP 包頭和2 字節的FU indicator、1 個字節的FU Header 及被分割的H.265 碼流段的組合。RTP 包負載結構如圖3所示。

圖3 RTP負載結構
首先分析FU indicator 結構,如圖1所示,與上文NALU 頭的格式完全一致。F:1 bit,為禁止位,通常情況下為0。Type:6 bit,表示的是分片封包的類型,NALU 的Type 表示當前NALU(幀)的類型,在文中為49。LayerId 為0,TID 為1。如圖4所示,FU Header 結構中,S:1 bit,開始位,若為1 表示分片NAL 單元的開始。若跟隨的FU 負載不是分片NALU 的首個包,則開始位為0。E:1 bit,結束位,若為1,則表示分片NALU 的結束,即跟隨的FU 負載是分片NALU 的最后一個包,當跟隨的FU 負載不是分片NALU 的最后分片時,結束位設為0。此結構中的Type 表示被分片的原始圖像幀的類型,注意與FU indicator 中的Type 相區別。

圖4 FU Header結構
文中抓取的RTP 數據包存儲在pcap 文件中,若要提取RTP 數據包負載的H.265 碼流,則需要去掉不需要網絡傳輸中添加的各種頭信息,如pcap 文件頭、pcap 數據包頭、數據鏈路層頭、ip 頭、UDP 頭、RTP 頭等,并為每個NALU 恢復起始碼及分片包的原始NALU 頭。
根據圖5,在用UDP 頭的src_port 來判定是否為文中所需數據包時,需要先做一些準備工作,根據圖2pacp 文件結構解析,為了獲得負載上的H.265 碼流數據,首先將pcap 文件的24 字節文件頭去掉,對于單個pacp 的數據包n,需去掉數據包頭n,使用包頭信息的caplen 項作為遍歷指針的偏移依據,以實現對每個pcap 數據包負載的遍歷。

圖5 pcap文件中的H.265碼流提取
通過src_port 確定了是否為所需RTP 包,若為假則繼續遍歷pcap 文件,若為真則開始寫H.265 輸出文件。首先寫入起始碼,判斷該RTP 包是否為分片包,若為假,則直接將RTP 負載寫入輸出文件;若為真且為圖像幀的首個分片包[18],則將FU indicator 的Type 位清零,并與FU Header 的Type 位組合為新的NALU 頭,將其寫入H.265 輸出文件。去掉RTP 數據包的RTP 頭和FU 分片頭,將剩余的負載部分寫入H.265 輸出文件,若非圖像幀的首個分片包,則只需去掉RTP 數據包的RTP 頭和FU 分片頭并將RTP數據包的剩余部分寫入H.265 輸出文件,每處理完一個RTP 數據包就繼續遍歷pcap 文件,直至文件結束。
提取H.265 視頻完成后可用ffplay 進行播放,直接用VLC 多媒體播放器(Video LAN Client,VLC)拉流播放的效果如圖6所示。文中提取的H.265 碼流播放效果如圖7所示,由圖7可看出,圖像質量已還原成攝像頭直接采集的播放效果。

圖6 VLC拉流播放效果

圖7 文中提取的H.265碼流播放效果
文中通過對H.265 碼流結構、RTP 打包方式、pcap 文件格式及數據包在以太網上的傳輸的剖析,設計并實現了從網絡上抓取H.265 碼流并將其從保存的pcap 文件中提取出來,提取成功的H.265 碼流文件可用作標準H.265 序列,也可以用來提取I 幀、B幀等,利于對單幀圖像進行研究。在工程上,該提取視頻的實現方法能為廣大的視頻開發人員提供一些參考,便于分析RTP 包和視頻幀序列。對于廣大視頻用戶來說,每次視頻方面研究的完成,都預示著將來更清晰、更高幀率、更小帶寬的視頻服務。