劉敏慧,賀波濤
(1.武漢郵電科學(xué)研究院,湖北武漢430074;2.武漢烽火眾智數(shù)字技術(shù)有限公司,湖北武漢430074)
隨著我國(guó)經(jīng)濟(jì)和社會(huì)的發(fā)展,網(wǎng)絡(luò)視頻監(jiān)控在城鄉(xiāng)治安、交通等方面日益發(fā)揮著重要的作用,流媒體編解碼和監(jiān)控視頻實(shí)時(shí)傳輸?shù)燃夹g(shù)是網(wǎng)絡(luò)視頻監(jiān)控的關(guān)鍵技術(shù)[1]。從如今的編解碼技術(shù)來(lái)看,被市場(chǎng)廣泛采用的是H.264 標(biāo)準(zhǔn),同時(shí)新一代的H.265 標(biāo)準(zhǔn)市場(chǎng)占比正在穩(wěn)步提升,其優(yōu)秀的視頻壓縮性能可以節(jié)約傳輸帶寬和存儲(chǔ)空間[2]。同時(shí),網(wǎng)絡(luò)視頻監(jiān)控[3]對(duì)實(shí)時(shí)的網(wǎng)絡(luò)傳輸有很大需求[4],實(shí)時(shí)傳輸協(xié)議(Real-time Transport Protocol,RTP)[5]解決了該問(wèn)題,RTP 可采用用戶數(shù)據(jù)包協(xié)議(User Datagram Protocol,UDP)來(lái)實(shí)時(shí)傳輸數(shù)據(jù),攝像頭在采集到監(jiān)控視頻后,其H.265 碼流會(huì)被封裝在RTP信息包中,RTP 信息包被再次封裝為UDP 的負(fù)載,最終封裝在ip 數(shù)據(jù)包的負(fù)載中。文中研究的內(nèi)容是如何從Wireshark 抓取的RTP 包中提取出H.265碼流并保存,且實(shí)現(xiàn)該碼流的高清流暢播放,保存的H.265 碼流可用作關(guān)鍵幀的提取、轉(zhuǎn)碼及圖像處理研究,具有較高的研究?jī)r(jià)值。
H.265 是繼H.264 之后,由ITU-T VCEG 組織發(fā)布的新一代視頻編碼標(biāo)準(zhǔn)[6]。H.265 標(biāo)準(zhǔn)基于現(xiàn)有的H.264 視頻編碼標(biāo)準(zhǔn)[7],保留了一部分原有技術(shù),同時(shí)改進(jìn)了一些相關(guān)技術(shù)。新標(biāo)準(zhǔn)使用先進(jìn)的技術(shù)來(lái)改善碼流、編碼質(zhì)量、延遲和算法復(fù)雜度之間的關(guān)系,以實(shí)現(xiàn)最佳設(shè)置。具體研究?jī)?nèi)容包括提高壓縮效率、提高魯棒性和錯(cuò)誤恢復(fù)能力、降低實(shí)時(shí)時(shí)延、降低信道采集時(shí)間和隨機(jī)訪問(wèn)時(shí)延、降低復(fù)雜度[8]。HEVC[9]不僅提升視頻質(zhì)量,而且在相同的視頻質(zhì)量的情況下,相比H.264 實(shí)現(xiàn)了兩倍的壓縮率,同時(shí)可支持4K清晰度,甚至最高清晰度可達(dá)到8K(8 192×4 320)[10]。
H.265 碼流[11]的圖像幀序列由起始碼(00 00 00 01 或00 00 01)、VPS、SPS、PPS、SEI、IDR 幀、P 幀、B幀、I幀等組成。
網(wǎng)絡(luò)抽象層(Network Abstraction Layer,NAL)是H.265 視頻編碼標(biāo)準(zhǔn)的一部分,NAL 負(fù)責(zé)格式化視頻數(shù)據(jù)并提供頭信息,從而保證視頻數(shù)據(jù)在各種信道和存儲(chǔ)介質(zhì)上的穩(wěn)定傳輸。H.265 碼流由一系列的NALU 組成,每個(gè)VPS、SPS、PPS、SEI、I 幀、P 幀都可以稱為一個(gè)NALU,常見(jiàn)NALU 類型如表1所示。
表1 常見(jiàn)NALU類型
NALU 的結(jié)構(gòu)為NALU 頭+NALU 負(fù)載。H.265碼流的NALU 頭由兩個(gè)字節(jié)組成,它的語(yǔ)法如圖1所示。
圖1 NALU結(jié)構(gòu)/FU indicator結(jié)構(gòu)
F:1 bit,forbidden_zero_bit,在H.265 規(guī)范中規(guī)定了這一位必須為0。禁止位0 表示正常,1 表示錯(cuò)誤,一般都是0。Type:6 bit,nal_unit_type,常見(jiàn)NALU 類型如表1所示。LayerID:6 bit,nuh_reserved_zero_6bits,為0。TID:3 bit,nuh_temporal_id_plus1,為1。
從RTP 數(shù)據(jù)包中提取H.265 碼流,首先需要抓取數(shù)據(jù)包。Wireshark 作為全世界最為流行的網(wǎng)絡(luò)封包分析軟件之一,可以抓取網(wǎng)絡(luò)封包,并且盡可能地顯示出最為詳細(xì)的信息。抓取的數(shù)據(jù)包可以保存為pcap 格式[12]的文件,文中就是從包含已抓取數(shù)據(jù)包的pcap 文件中提取H.265 碼流信息的[13]。pcap 文件的格式如圖2所示。
圖2 pcap文件格式
文中需要抓取的是攜帶著H.265 碼流信息的RTP 數(shù)據(jù)包,抓取時(shí)不可避免地捕獲ARP、TCP 等非必須數(shù)據(jù)包,可用Wireshark 本身的過(guò)濾規(guī)則來(lái)除去,也可在自制的提取碼流方案中添加規(guī)則過(guò)濾。文中推薦使用第二種方法,該方法普適性更好,給研發(fā)人員的自主性更大,在提取時(shí)也不會(huì)因?yàn)閭€(gè)別包的疏漏而出現(xiàn)問(wèn)題。
從pcap 文件中提取H.265 碼流,需要獲取H.265碼流在網(wǎng)絡(luò)傳輸時(shí)的打包方式。文中的H.265 碼流在傳輸層采用的是UDP 協(xié)議,UDP 是開(kāi)放式系統(tǒng)互聯(lián)(Open System Interconnection,OSI)參考模型中的一種無(wú)連接的傳輸層協(xié)議。相比于傳輸層另一種協(xié)議——傳輸控制協(xié)議(Transport Control Protocol,TCP),UDP 雖然提供不可靠的信息傳輸服務(wù),但它額外開(kāi)銷小、時(shí)延短、無(wú)連接,非常適合多媒體數(shù)據(jù)流的傳輸,在文中情況下,UDP 也是個(gè)好選擇[14]。
RTP 協(xié)議[15]規(guī)定了在互聯(lián)網(wǎng)上傳輸視頻和音頻的標(biāo)準(zhǔn)數(shù)據(jù)包格式,它創(chuàng)建在UDP 之上,并與之結(jié)合使用,方便RTP 使用其端口號(hào)和效驗(yàn)服務(wù),依托UDP低傳輸時(shí)延的特點(diǎn),更好地匹配視頻傳輸業(yè)務(wù)。
RTP 包由包頭和負(fù)載兩部分組成[16],H.265 碼流數(shù)據(jù)存儲(chǔ)在RTP 數(shù)據(jù)包的負(fù)載中,其包頭中存儲(chǔ)了負(fù)載類型(payload typePT)、序列號(hào)(Sequence Number)、時(shí)間戳(Timestamp)、同步源標(biāo)識(shí)符(SSRC)等信息,包頭的信息不是必要的,在設(shè)計(jì)時(shí)可以直接偏移12 字節(jié)到負(fù)載部分。
在以太網(wǎng)中,數(shù)據(jù)鏈路層能夠確定發(fā)送的一個(gè)數(shù)據(jù)包的最大長(zhǎng)度稱為最大傳輸單元(Maximum Transmission Unit,MTU),為1 500 字節(jié),文中采用的監(jiān)控視頻的分辨率是1 920×1 080,由于通過(guò)H.265標(biāo)準(zhǔn)壓縮后的每幀圖像遠(yuǎn)遠(yuǎn)超過(guò)1 500 字節(jié),因此為了實(shí)現(xiàn)H.265 碼流在網(wǎng)絡(luò)上的傳輸,必須對(duì)每幀圖像進(jìn)行分割再打包成適合在以太網(wǎng)上傳輸?shù)拇笮『线m的RTP 數(shù)據(jù)包。
上文已知H.265 碼流由一系列的NALU 組成,每個(gè)VPS、SPS、PPS、SEI、I 幀、P 幀都可以稱為一個(gè)NALU,不同類型的NALU 之間大小差距很大[17]。對(duì)于VPS、SPS、PPS、SEI 等小于MTU 的NALU,打包時(shí)只需將該NALU 去掉起始碼并添加在RTP 包頭后即可。對(duì)于I 幀、P 幀等大于MTU 的NALU,使用FU 打包,就是將一個(gè)NALU 分片打包成幾個(gè)RTP 數(shù)據(jù)包,即fragmentation unit,簡(jiǎn)稱FU。每個(gè)分片單元為12字節(jié)的RTP 包頭和2 字節(jié)的FU indicator、1 個(gè)字節(jié)的FU Header 及被分割的H.265 碼流段的組合。RTP 包負(fù)載結(jié)構(gòu)如圖3所示。
圖3 RTP負(fù)載結(jié)構(gòu)
首先分析FU indicator 結(jié)構(gòu),如圖1所示,與上文NALU 頭的格式完全一致。F:1 bit,為禁止位,通常情況下為0。Type:6 bit,表示的是分片封包的類型,NALU 的Type 表示當(dāng)前NALU(幀)的類型,在文中為49。LayerId 為0,TID 為1。如圖4所示,F(xiàn)U Header 結(jié)構(gòu)中,S:1 bit,開(kāi)始位,若為1 表示分片NAL 單元的開(kāi)始。若跟隨的FU 負(fù)載不是分片NALU 的首個(gè)包,則開(kāi)始位為0。E:1 bit,結(jié)束位,若為1,則表示分片NALU 的結(jié)束,即跟隨的FU 負(fù)載是分片NALU 的最后一個(gè)包,當(dāng)跟隨的FU 負(fù)載不是分片NALU 的最后分片時(shí),結(jié)束位設(shè)為0。此結(jié)構(gòu)中的Type 表示被分片的原始圖像幀的類型,注意與FU indicator 中的Type 相區(qū)別。
圖4 FU Header結(jié)構(gòu)
文中抓取的RTP 數(shù)據(jù)包存儲(chǔ)在pcap 文件中,若要提取RTP 數(shù)據(jù)包負(fù)載的H.265 碼流,則需要去掉不需要網(wǎng)絡(luò)傳輸中添加的各種頭信息,如pcap 文件頭、pcap 數(shù)據(jù)包頭、數(shù)據(jù)鏈路層頭、ip 頭、UDP 頭、RTP 頭等,并為每個(gè)NALU 恢復(fù)起始碼及分片包的原始NALU 頭。
根據(jù)圖5,在用UDP 頭的src_port 來(lái)判定是否為文中所需數(shù)據(jù)包時(shí),需要先做一些準(zhǔn)備工作,根據(jù)圖2pacp 文件結(jié)構(gòu)解析,為了獲得負(fù)載上的H.265 碼流數(shù)據(jù),首先將pcap 文件的24 字節(jié)文件頭去掉,對(duì)于單個(gè)pacp 的數(shù)據(jù)包n,需去掉數(shù)據(jù)包頭n,使用包頭信息的caplen 項(xiàng)作為遍歷指針的偏移依據(jù),以實(shí)現(xiàn)對(duì)每個(gè)pcap 數(shù)據(jù)包負(fù)載的遍歷。
圖5 pcap文件中的H.265碼流提取
通過(guò)src_port 確定了是否為所需RTP 包,若為假則繼續(xù)遍歷pcap 文件,若為真則開(kāi)始寫(xiě)H.265 輸出文件。首先寫(xiě)入起始碼,判斷該RTP 包是否為分片包,若為假,則直接將RTP 負(fù)載寫(xiě)入輸出文件;若為真且為圖像幀的首個(gè)分片包[18],則將FU indicator 的Type 位清零,并與FU Header 的Type 位組合為新的NALU 頭,將其寫(xiě)入H.265 輸出文件。去掉RTP 數(shù)據(jù)包的RTP 頭和FU 分片頭,將剩余的負(fù)載部分寫(xiě)入H.265 輸出文件,若非圖像幀的首個(gè)分片包,則只需去掉RTP 數(shù)據(jù)包的RTP 頭和FU 分片頭并將RTP數(shù)據(jù)包的剩余部分寫(xiě)入H.265 輸出文件,每處理完一個(gè)RTP 數(shù)據(jù)包就繼續(xù)遍歷pcap 文件,直至文件結(jié)束。
提取H.265 視頻完成后可用ffplay 進(jìn)行播放,直接用VLC 多媒體播放器(Video LAN Client,VLC)拉流播放的效果如圖6所示。文中提取的H.265 碼流播放效果如圖7所示,由圖7可看出,圖像質(zhì)量已還原成攝像頭直接采集的播放效果。
圖6 VLC拉流播放效果
圖7 文中提取的H.265碼流播放效果
文中通過(guò)對(duì)H.265 碼流結(jié)構(gòu)、RTP 打包方式、pcap 文件格式及數(shù)據(jù)包在以太網(wǎng)上的傳輸?shù)钠饰?,設(shè)計(jì)并實(shí)現(xiàn)了從網(wǎng)絡(luò)上抓取H.265 碼流并將其從保存的pcap 文件中提取出來(lái),提取成功的H.265 碼流文件可用作標(biāo)準(zhǔn)H.265 序列,也可以用來(lái)提取I 幀、B幀等,利于對(duì)單幀圖像進(jìn)行研究。在工程上,該提取視頻的實(shí)現(xiàn)方法能為廣大的視頻開(kāi)發(fā)人員提供一些參考,便于分析RTP 包和視頻幀序列。對(duì)于廣大視頻用戶來(lái)說(shuō),每次視頻方面研究的完成,都預(yù)示著將來(lái)更清晰、更高幀率、更小帶寬的視頻服務(wù)。