1. 程式人生 > >使用RTP傳輸H.264格式視訊

使用RTP傳輸H.264格式視訊

一、H.264碼流

H.264功能分為兩層:視屏編碼層(VCL)和網路提取層(NAL)

VCL:被壓縮編碼的視訊資料序列

NAL:VCL需要封裝到NAL單元中進行傳輸儲存

NAL單元分析

Nal頭 RBSP Nal頭 RBSP

幾個概念:

  • SODB:資料位元串–>最原始的編碼資料

  • RBSP:原始位元組序列載荷–>在SODB後面新增結尾位元(一位元1和若干位元0)位元組對齊

  • EBSP:擴充套件位元組序列載荷–>在RBSP基礎上加入仿校驗位元組(0x03)

原因:在NALU加到Annexb上時,需要在NALU之前新增開始碼。如果該NALU對於的slice為一幀的開始則用4位位元組0x00000001表示,否則用3位位元組0x000001。為了確保NALU主體中不包括與開始碼相沖突,在編碼時沒遇到連續兩位元組的0就新增一個位元組的0x03。解碼時在去掉該位元組脫殼。

一個NAL單元由:1位元組的HAL頭即3個定長的欄位、1個位元組數不定的編碼段組成

NAL頭:(5bit)NALU型別、(2bit)重要性指示、(1bit)禁止位

NALU型別:1~12由H.264使用,24~31由H.264以外的應用使用。

重要性指示:標誌該NAL單元用於重建時的重要性,值越大,越重要。

禁止位:網路發現NAL單元有位元錯誤時可設定該位元為1,以便接收方丟掉該單元

NAL型別介紹:

(1)引數集:以往視訊編解碼標準中GOB\GOP\影象等頭資訊是至關重要的,包含這些資訊的包的丟失常導致與這些資訊相關的影象不能解碼。為此H.264將這些很少變化並且對大量VCL NALU起作用的資訊放在引數集中傳送。引數集分為兩種,即序列引數集和影象引數集。為適應多種網路環境,引數集可以帶內傳送,也可以採用帶外方式傳送。

  • SPS :序列的引數集(SPS):包括了一個影象序列的所有資訊

  • PPS :影象的引數集(PPS):包括了一個影象所有片的資訊。

二、RTP/RTCP協議

RTP 協議是在 1996 年提出的適合實時資料傳輸的新型協議。

RTP 協議實際上是由實時傳輸協議RTP(Real-time Transport Protocol)和實時傳輸控制協議RTCP(Real-time Transport Control Protocol)兩部分組成。RTP 協議基於多播或單播網路為使用者提供連續媒體資料的實時傳輸服務;RTCP 協議是 RTP 協議的控制部分,用於實時監控資料傳輸質量,為系統提供擁塞控制和流控制。

RTP包頭格式

一個 RTP 資料包都由固定包頭(Header )和載荷(Payload)兩個部分組成,其中包頭前12個位元組的含義是固定的,而載荷則可以是音訊或視訊資料。

其中比較關鍵的引數設定解釋如下:

  • 標示位(M ):1 位,該標示位的含義一般由具體的媒體應用框架(profile )定義, 目的在於標記處RTP 流中的重要事件。
  • 載荷型別(PT):7 位,用來指出RTP負載的具體格式。在RFC3551中,對常用的音視訊格式的RTP 傳輸載荷型別做了預設的取值規定,例如,型別2 表明該RTP資料包中承載的是用ITU G.721 演算法編碼的語音資料,採用頻率為 8000HZ,並且採用單聲道。
  • 序號:16 位,每傳送一個 RTP 資料包,序號加 1。接受者可以用它來檢測分組丟失和恢復分組順序。
  • 時間戳:32 位,時間戳表示了 RTP 資料分組中第一個位元組的取樣時間,反映出各RTP 包相對於時間戳初始值的偏差。對於RTP 傳送端而言,取樣時間必須來源於一個線性單調遞增的時鐘。

三、使用RTP傳輸H.264

使用RTP協議來傳輸H.264視訊一個有效的辦法就是從H.264視訊中剝離出每個NALU,在每個NALU前新增相應的RTP包頭,然後將包含RTP 包頭和NALU 的資料包傳送出去。

對RTP包頭的設定

RTP包頭的格式如上圖,如下介紹詳細設定:

  • V:版本號,2 位。根據RFC3984,目前使用的RTP 版本號應設為0x10。

  • P:填充位,1 位。當前不使用特殊的加密演算法,因此該位設為 0。

  • X:擴充套件位,1 位。當前固定頭後面不跟隨頭擴充套件,因此該位也為 0。

  • CC:CSRC 計數,4 位。表示跟在 RTP 固定包頭後面CSRC 的數目,沒有用到混合器,該位也設為 0x0。

  • M:標示位,1 位。如果當前 NALU為一個接入單元最後的那個NALU,那麼將M位置 1;或者當前RTP 資料包為一個NALU 的最後的那個分片時(NALU 的分片在後面講述),M位置 1。其餘情況下M 位保持為 0。

  • PT:載荷型別,7 位。對於H.264 視訊格式,當前並沒有規定一個預設的PT 值。因此選用大於 95 的值可以。此處設為0x60(十進位制96)。

  • SQ:序號,16 位。序號的起始值為隨機值,此處設為 0,每傳送一個RTP 資料包,序號值加 1。

  • TS:時間戳,32 位。同序號一樣,時間戳的起始值也為隨機值,此處設為0。根據RFC3984, 與時間戳相應的時鐘頻率必須為90000HZ。

  • SSRC:同步源標示,32 位。SSRC應該被隨機生成,以使在同一個RTP會話期中沒有任何兩個同步源具有相同的SSRC 識別符。此處僅有一個同步源,因此將其設為0x12345678。

RTP分包

對於每一個NALU,根據其包含的資料量的不同,其大小也有差異。在IP網路中,當要傳輸的IP 報文大小超過最大傳輸單元MTU(Maximum Transmission Unit )時就會產生IP分片情況。在乙太網環境中可傳輸的最大 IP 報文(MTU)的大小為 1500 位元組。如果傳送的IP資料包大於MTU,資料包就會被拆開來傳送,這樣就會產生很多資料包碎片,增加丟包率,降低網路速度。對於視訊傳輸而言,若RTP 包大於MTU 而由底層協議任意拆包,可能會導致接收端播放器的延時播放甚至無法正常播放。因此對於大於MTU 的NALU 單元,必須進行拆包處理。

RFC3984 給出了3 中不同的RTP 打包方案:

  • Single NALU Packet:在一個RTP 包中只封裝一個NALU,在本文中對於小於 1400位元組的NALU 便採用這種打包方案。
  • Aggregation Packet:在一個RTP 包中封裝多個NALU,對於較小的NALU 可以採用這種打包方案,從而提高傳輸效率。
  • Fragmentation Unit:一個NALU 封裝在多個RTP包中,在本文中,對於大於1400位元組的NALU 便採用這種方案進行拆包處理。

四、H.264傳輸系統實現

一個完整的流媒體傳輸系統包含伺服器端和客戶端兩個部分。

H.264服務端客戶端傳設計

對於伺服器端,其主要任務是讀取H.264 視訊,從碼流中分離出每個NALU 單元,分析NALU 的型別,設定相應的 RTP 包頭,封裝 RTP 資料包併發送。而對於客戶端來說,其主要任務則是接收 RTP資料包,從RTP 包中解析出NALU 單元,然後送至客戶端進行解碼播放。該流媒體傳輸系統的框架如圖3 所示:

服務端處理流程如下圖4:

H.264解碼過程

如下圖解碼流程圖:

NAL 單元解碼的流程為:首先從 NAL 單元中提取出 RBSP 語法結構,然後按照如圖 4 所示的流程處理 RBSP 語法結構。輸入的是 NAL 單元,輸出結果是經過解碼的當前影象的 樣值點。

NAL 單元中分別包含了序列引數集和影象引數集。影象引數集和序列引數集在其他 NAL 單元傳輸過程中作為參考使用,在這些資料 NAL 單元的片頭中,通過語法元素 pic_parameter_set_id 設定它們所使用的影象引數集編號;而相應的每個影象引數集中,通過 語法元素 seq_paramter_set_id 設定他們使用的序列引數集編號。

參考連線: