Android流媒體處理流程分析

1. WiFiDisplay簡介

WiFiDisplay是一系列協議棧的組合,運行在基於WiFi-P2P協議建立起來的IP網絡上,Source端與Sink端設備都分配到一個IP,IP網段爲192.168.49.xx,在這個網段內,Source設備與Sink設備通過一系列應用層協議,如RTSP、RTP以及RTCP等建立流媒體傳輸通道,完成Source設備鏡像傳輸。
在這裏插入圖片描述
WiFiDisplay協議棧

2.RTSP協議流程分析

RTSP過程屬於媒體能力協商過程,主要包括以下內容協商
1.音視頻參數
2.媒體端口協商
– M1 : Source 端發送 RTSP Options 請求
Source端想知道Sink端支持那些Options方法
在這裏插入圖片描述
– M2 : Sink 響應 RTSP Options
Sink端回覆Source端自己支持Options方法,並回復200OK狀態碼
在這裏插入圖片描述
– M3 : Source 發送 RTSP Get Parameter 消息
用於向Sink端描述自己想要請求獲取的顯示能力
在這裏插入圖片描述
wfd_content_protection //內容保護,和HDCP有關
wfd_video_formats //支持的視頻分辨率
wfd_audio_codecs //支持的音頻編碼
wfd_client_rtp_ports //rtp 端口
– M3 : Sink 響應Source端 的RTSP Get Parameter 請求
響應支持的能力參數,不支持的能力參數不響應
在這裏插入圖片描述

– M4 : Source端決定選擇那些參數用於會話,發送RTSP Set Parameter給Sink 初始化
在這裏插入圖片描述
– M4 : Sink 回覆Source 200Ok狀態碼
在這裏插入圖片描述
在這裏插入圖片描述

– M5 : Source 發送 RTSP Set Parameter 請求,並攜帶“setup”出發器
在這裏插入圖片描述

– M5 : Sink 響應 RTSP Set Parameter 200OK狀態碼
在這裏插入圖片描述
– M6 : Sink 發送 RTSP Setup 請求 用於建立RTP端口
在這裏插入圖片描述

– M6 : Source 響應 RTSP Setup 端口信息以及結果狀態碼
在這裏插入圖片描述

– M7 : Sink 發送 RTSP Play請求到 Source
告訴Source端,我已經準備好接收RTP流了
在這裏插入圖片描述
– M7 : Source 響應 RTSP Play ,包括200Ok狀態碼,timeout,Range:流開始時間
•
到此,協商完成,Source開始向Sink端指定端口傳流。

在傳輸中Source端通過RTSP get Parameter 消息用於保活的, 該消息中不帶任何參數。
在這裏插入圖片描述

3. 流媒體協議簡介

在協議棧圖中和媒體相關的協議包括RTSP、RTP、MPEG2TS、HDCP,其中HDCP協議與數字版權有關,在HDMI高清認證中有這一項認證。在WIFIDisplay協議中,HDCP協議屬於可選實現,就是說不實現也可以傳輸鏡像,RTSP協議屬於流媒體控制協議,RTP用於傳輸音視頻流,通常使用UDP協議傳輸,也可以使用TCP傳輸,RTP的payload是mpeg2ts流,這是一種流媒體封裝格式,mpeg2ts包大小是固定,每個包長188byte, mpeg2ts的payload是真正的H264裸流或者AAC音頻流。

下圖中展示了 WiFiDisplay傳輸的流媒體格式
WFD流媒體傳輸格式
WFD Source設備通過MPEG2TS封裝格式來封裝AV信息,然後依次包裝進RTP、UDP、IP協議中,然後傳輸給WFD Sink設備

– WFD Source將音頻和/或視頻流通過多路複用技術打包進單個MPEG2傳輸流中
– WFD Source可以選擇性的將音視頻流放到單獨的MPEG2流中處理,允許耦合接收操作

4. RTP、RTCP協議簡介

4.1 RTP協議

RTP全名是Real-time Transport Protocol(實時傳輸協議)。定義在RFC3550不僅定義了RTP,與其配套的相關協議RTCP(Real-time Transport Control Protocol,即實時傳輸控制協議)。RTP用來爲IP網上的語音、圖像、傳真等多種需要實時傳輸的多媒體數據提供端到端的實時傳輸服務。RTP爲Internet上端到端的實時傳輸提供時間信息和流同步,但並不保證服務質量,服務質量由RTCP來提供。

  1. RTP使用場景
    RTP用於在單播或多播網絡中傳送實時數據,具體場景包括:
    1.簡單的多播音頻會議。
    2.翻譯器和混合器。
    3.音頻和視頻會議。
  2. 流媒體概念

流媒體是指Internet上使用流式傳輸技術的連續時基媒體。當前在Internet上傳輸音頻和視頻等信息主要有兩種方式:下載和流式傳輸兩種方式。
下載情況下,用戶需要先下載整個媒體文件到本地,然後才能播放媒體文件。
流式傳輸是實現流媒體的關鍵技術。使用流式傳輸可以邊下載邊觀看流媒體節目。由於Internet是基於分組傳輸的,所以接收端收到的數據包往往有延遲和亂序(流式傳輸構建在UDP上)。要實現流式傳輸,就是要從降低延遲和恢復數據包時序入手。在發送端,爲降低延遲,往往對傳輸數據進行預處理(降低質量和高效壓縮)。在接收端爲了恢復時序,採用了接收緩衝;而爲了實現媒體的流暢播放,則採用了播放緩衝。
使用接收緩衝,可以將接收到的數據包緩存起來,然後根據數據包的封裝信息(如包序號和時戳等),將亂序的包重新排序,最後將重新排序了的數據包放入播放緩衝播放。

到目前爲止,Internet 上使用較多的流式視頻格式主要有以下三種:RealNetworks 公司的RealMedia, Apple 公司的QuickTime 以及Microsoft 公司的Advanced Streaming Format (ASF) 。這些流式媒體格式只是編解碼有不同,但對於RTP來說,它們都是待封裝傳輸的流媒體數據而沒有什麼不同。

RTP所處的網絡體系層次位於TCP、UDP之上,被劃分在傳輸層,它建立在UDP上。同UDP協議一樣,爲了實現其實時傳輸功能,RTP也有固定的封裝形式。RTP用來爲端到端的實時傳輸提供時間信息和流同步,但並不保證服務質量。服務質量由RTCP來提供。
在這裏插入圖片描述

RTP協議格式

RTP協議頭信息
版本號(V):2 bits,用來標誌使用的RTP版本。

填充位(P):1 bits,如果該位置位,則該RTP包的尾部就包含附加的填充字節。

擴展位(X):1 bits,如果該位置位的話,RTP固定頭部後面就跟有一個擴展頭部。

CSRC計數器(CC):4 bits,含有固定頭部後面跟着的CSRC的數目。

標記位(M):1 bit,該位的解釋由配置文檔(Profile)來承擔.

載荷類型(PT):7 bits,標識了RTP載荷的類型, 用於說明RTP報文中有效載荷的類型,如GSM音頻、JPEM圖像等,在流媒體中大部分是用來區分音頻流和視頻流的,這樣便於客戶端進行解析。

序列號(SN):16 bits,發送方在每發送完一個RTP包後就將該域的值增加1,接收方可以由該域檢測包的丟失及恢復包序列。序列號的初始值是隨機的。

時間戳:32 bits,記錄了該包中數據的第一個字節的採樣時刻。在一次會話開始時,時間戳初始化成一個初始值。即使在沒有信號發送時,時間戳的數值也要隨時間而不斷地增加(時間在流逝嘛)。時間戳是去除抖動和實現同步不可缺少的。

同步源標識符(SSRC):32 bits,同步源就是指RTP包流的來源。在同一個RTP會話中不能有兩個相同的SSRC值。該標識符是隨機選取的 RFC1889推薦了MD5隨機算法。

貢獻源列表(CSRC List):0~15項,每項32 bits,用來標誌對一個RTP混合器產生的新包有貢獻的所有RTP包的源。由混合器將這些有貢獻的SSRC標識符插入表中。SSRC標識符都被列出來,以便接收端能正確指出交談雙方的身份。

相關頭信息的詳細解釋參考

RTP協議分析和詳解
RTP與RTCP解釋.含同步時間戳 相關章節

分包大小限制

分包大小:<= 1500-20(IP頭)-8(UDP)-12(rtp) 1460

4.1 RTP載荷H264碼流

參考 RTP協議全解析(H264碼流和PS流)RTP荷載H264碼流 章節中的相關描述。

4.2 RTP載荷PS碼流

參考 RTP協議全解析(H264碼流和PS流)RTP荷載PS流 章節中的相關描述。

4.2 RTP載荷MPEG2TS碼流

4.2.1 基本概念

1.ES–Elementary Streams(原始流)是直接從編碼器出來的數據流,ES經過PES打包器之後,轉換成PES包。

ES僅是包含一種數據內容的數據流,如h.264視頻或者aac音頻數據。打包之後的PES也是隻包含一種的ES,如只含視頻ES的PES或者只含音頻ES的PES。每個ES都由若干個存取單元(AU)組成,每個視頻AU或者音頻AU都由頭部和編碼數據兩部分組成,一個AU相當於編碼的一幅視頻圖像或一個音頻幀。

2.PES–Packetized Elementary Streams(分組的ES),ES形成的分組成爲PES分組,是用來傳遞ES的一種數據結構。
在PES打包器打包ES的過程中完成了將ES流分組,打包,加入包頭信息等操作(是對ES流的第一次打包操作)。PES流的基本單位是PES包。PES包由包頭和payload組成。

3.TS–Transport Streams(傳輸流)由定長的TS包組成(188字節),而TS包是對PES的一種重新封裝(到這裏,ES經過了兩層封裝)。PES包的包頭信息依然存在於TS包中。

參考:https://blog.csdn.net/rootusers/article/details/42772657

WFD流媒體傳輸格式 圖的描述中,每n個MPEG-TS Packet打包爲一個RTP,然後每個RTP再打包爲一個UDP。其中打包RTP的方法就是在MPEG-TS數據前面加上RTP Header,而打包RTP的方法就是在RTP數據前面加上UDP Header。

TS包打包流程
TS包打包流程如下:

1.A/D轉換後,通過MPEG-2壓縮編碼得到ES基本流。該流數據量很大,並且只是I P B幀的取樣信息。

2.通過PES打包器,打包並在每個幀中插入PTS/DTS標識,編程PES。原來是流的格式,現在成了數據包的分割形式。

3.PES根據需要打包成PS或者TS包進行存儲。

4.2.2 PES相關

PES是打包過的ES,已經插入PTS和DTS,一般一個PES是一幀圖像。

PES包結構說明
PES經過打包成TS或PS流,往往一個PES會分存到多個TS包中。

1.PES包的包起始碼:包起始碼前綴是一個固定的碼字結構,它的值是0x000001,用於收發兩端對PES包進行同步。
2.PES包的長度:PES包的長度是可變的,PES包長度域有兩個字節,共16比特,因此PES包的最大長度是65535字節
3.PES包頭:PES包頭的功能根據特定的應用場合有所不同,包括加擾控制,優先級,ES流速率和CRC等,其中有兩個重要的工作:PTS和DTS。
原文鏈接:https://blog.csdn.net/rootusers/article/details/42772657

4.2.2 TS相關

  1. 包結構說明
    TS頭部信息

1.sync_byte 8bits 同步字節, 值爲0x47

2.transport_error_indicator 1bit 錯誤指示信息
值爲1時,表示相關的傳送包中至少有一個不可糾正的錯誤位,只有錯誤位糾正後,該位才能置0;

3.payload_unit_start_indicator 1bit 負載單元開始標誌
當TS包帶有PES包數據時,payload_unit_start_indicator值爲1時,表示TS包的負載以PES包的第一個字節開始,值爲0,表示TS包開始的不是PES包。

當TS包帶有PSI數據時,payload_unit_start_indicator值爲1時,表示TS包帶有PSI部分的第一個字節,即第一個字節帶有指針pointer_field;置爲0,表示TS包不帶有一個PSI部分的第一個字節,即在有效淨荷中沒有指針的pointer_field.
空包payload_unit_start_indicator應置爲0.

4.transport_priority 1bit 傳輸優先級標誌
置1表示相關的包比其他具有相同PID但transport_priority爲0的包有更高的優先級;

5.PID 13bit packet ID號碼,唯一的號碼對應不同的包
表示淨荷的數據類型。具體的取值對應關係如下
在這裏插入圖片描述
在這裏插入圖片描述

6.transport_scrambling_control 2bit 加密標誌, 指示TS包有效淨荷的加擾方式,如果首部包括調整字段,則不應該被加擾,對於空包,值要置“00”;
在這裏插入圖片描述

7.adaptation_field_control 2bit 附加區域控制也就是MPEG-2 TS包調整字段

在ts中,爲了傳送打包後的長度不足188B的不完整TS,或者爲了在系統層插入節目時鐘參考PCR字段,需要在TS包中插入可變長字節的調整字段。調整字段是一個可變長的域,它是由存在於TS包頭中的調整字段控制值來標識的。
在這裏插入圖片描述
adaption_field_control爲“調整字段控制”,表示TS分組首部後面是否跟隨有調整字段和有效負載。01僅含有效負載,10僅含調整字段,11含有調整字段和有效負載。爲00解碼器不進行處理。空分組沒有調整字段。如果有調整字段就是包數據的第一位(除去包頭)指定調整字段長度。
因爲00和10都沒有有效負載所以不進行處理,爲1表示只有有效負載,數據從第5個字節(數組下標爲4)開始;如果爲11則從調整字段後一位(第6個字節,數組下標5)加上調整字段長度爲包有效數據開始位置。
8.continuity_counter 4bit 包遞增計數器
隨着具有相同PID TS包的增加而增加,當達到最大時,又恢復爲0,如果調整字段控制值adaptation_field_control爲“00”或“10”,則該連續計數器不增加;在TS中,當複用的包可能被作爲兩個連續的具有相同PID的TS包傳送出去時,則複用的傳送包與原傳送包具有相同的continuity_counter,而adaptation_field_control字段值應爲“01”或者"10"。在複用的包中,除了節目參考時鐘PCR有效字段的值被重新編碼外,原包中每個字節將被複制。

在特定的TS中具有相同PID包的continuity_counter是連續的,或與前一個具有相同PID的包相差1,但是遇到adaptation_field_control爲“00”或“10”等不增加條件,或在調整字段中discontinuity_indicator爲“1”時,continuity_counter將不連續。
對於 adaption_field_control 字段域詳細的描述參考TS Stream 詳解 中關於 自適應調整字段 章節的描述。

  1. 包類型說明
    一個TS包的載荷中,可以包含PAT包、PMT包、多個音頻包、多個視頻包、多個PCR包、以及其他信息包。
    TS包中負載傳送的信息主要有4種類型:
    1.視頻和音頻的PES包以及輔助數據。
    2.描述單路節目的節目映射表(PMT)與描述多路節目複用信息的節目關聯表(PAT)以及對CA系統所要求的條件訪問表(CAT)。
    3.各種業務信息表。
    4.DVB數據廣播信息,包括數據管道,異步數據報,同步,被同步數據流,多協議封裝,循環數據,循環對象。

TS包負載部分可以分成兩種類型:
1、視頻、音頻的PES包以及輔助數據。其中音視頻的ES需要被打包成爲PES,而輔助數據不需要被打包成PES
2、節目專用信息PSI,包括下面幾種:
PAT:節目關聯表。提供了節目好和對應PMT表格的PID的對應關係
PMT:節目映射表。定義了與特定節目相關的PID信息,例如:音頻包的pid,視頻包的pid、pcr的pid
CAT:條件接收表。用於流加擾情況下配置參數。
NIT:網絡信息表。可選的,標準未詳細定義
TSDT:傳輸流描述表。可選的。

————————————————
原文鏈接:https://blog.csdn.net/rootusers/article/details/42970859

  1. 獲取TS包中的音視頻數據
    如果給定一個TS文件,怎麼去尋找解碼音視頻解碼數據呢?每個TS包的前4個字節的包頭裏都有一個PID

      1、首先,一個個遍歷TS包,我們找到PID爲0的TS包,這個包叫PAT,這個PAT包裏包含了PMT的PID   號
      2、遍歷TS包又可以找到名爲PMT的TS包,PMT裏有什麼呢?PMT裏包含了video TS包的PID和它的codec,audio TS包的PID和它的codec 。有了codec我們知道要選擇什麼解碼器,有PID我們就可以獲得解碼數據。
      3、我們先來說說video數據和audio數據是怎麼分散在TS包裏的。video和audio其實都是以一種叫PES(Packetized Elementary Stream)的形式組織的。一幀視頻就是一個PES包。我們都知道一個TS包只有188個字節,除掉包頭還剩184個字節,這是不可能放下一幀的。
      4、實際上一個PES包是分配在連續的幾個TS包中,所以如果我們要獲得一幀數據,那麼我們需要把連續的幾個TS包裏的數據全部取出來才能組合成一個PES。
      5、那我們怎麼知道一個PES的開始和結尾呢?那我們還是一個個遍歷每一個TS包,尋找包頭裏payload_unit_start_indicator爲1包,這個標誌位代表着是一個PES的開始,那麼我從這開始,一直到下一個payload_unit_start_indicator爲1,這中間的TS包組成起來就是一個PES。
    
  2. 解析TS流數據的流程

     1、查找PID爲0x0的包,解析PAT,PAT包中的program_map_PID表示PMT的PID;
     2、查找PMT,PMT包中的elementary_PID表示音視頻包的PID,PMT包中的PCR_PID表示PCR的PID,
     3、有的時候PCR的PID跟音頻或者視頻的PID相同,說明PCR會融進音視頻的包
     4、有的時候PCR是自己單獨的包;
     5、CAT、NIT、SDT、EIT的PID分別爲: 0x01、0x10、0x11、0x12。
    

4.2.3 編碼相關

MPEG2的三類幀
I幀:是幀內編碼幀,其編碼不依賴BP兩幀,同時他是BP幀編解碼的參考圖像
P幀:前向預測編碼圖像,像素的預測值取爲前面與其相鄰的I幀或P幀中對應像素的值,即採用幀間運動補償前值預測。
B幀:雙向預測編碼圖像,像素的預測值取爲前後與其距離最近的I幀或P幀相應像素的加權平均,即採用幀間運動補償前後平均,需要指出,B幀不能作爲其他B幀或P幀的編碼參考圖像。
編碼順序:
傳輸流中編碼圖像的順序按照IPB的順序

顯示順序:
在解碼輸出端重建圖像的順序,按照IBP的順序。

一個視頻圖像,是由圖像組(Grop)組成的。每個圖像組由一個I幀和3個P幀8個B幀組成的。
圖像的顯示順序爲:1I,2B,3B,4B, 5B,6B,7P,8B,9B,10P,11B,12B,13I
圖像的編碼順序爲:1I,4P, 2B,3B, 7P,5B,6B,10P,8B,9B,13I,11B,12B
————————————————
原文鏈接:https://blog.csdn.net/rootusers/article/details/42970859

注意事項:

在MPEG2-TS相關開發的時候注意兩點:
1、對於RTP協議頭,由於大小端對結構體的位域也有影響,定義的時候要考慮大小端問題。
2、對於每次發送UDP包中TS包的個數。
考慮到以太網數據幀的最大長度爲1500,所以一般規定,每7個TS數據包封裝在一起進行發送。
另外我在測試的過程中通過ffmpeg進行ts數據包推流,每次socket接受到的UDP數據包大小爲1328byte,也就是7*188+12,這裏12爲rtp協議頭大小。
UDP_RTP+MPEG2-TS淺析:https://blog.csdn.net/h514434485/article/details/52120625

參考
視音頻數據處理入門:UDP-RTP協議解析
https://blog.csdn.net/leixiaohua1020/article/details/50535230

RTP 協議
https://www.cnblogs.com/qingquan/archive/2011/07/28/2120440.html

4.2 RTCP協議

RTCP的主要功能是:服務質量的監視與反饋、媒體間的同步,以及多播組中成員的標識。在RTP會話期 間,各參與者週期性地傳送RTCP包。RTCP包中含有已發送的數據包的數量、丟失的數據包的數量等統計資料,因此,各參與者可以利用這些信息動態地改變傳輸速率,甚至改變有效載荷類型。RTP和RTCP配合使用,它們能以有效的反饋和最小的開銷使傳輸效率最佳化,因而特別適合傳送網上的實時數據。

RTCP也是用UDP來傳送的,但RTCP封裝的僅僅是一些控制信息,因而分組很短,所以可以將多個RTCP分組封裝在一個UDP包中。RTCP有如下五種分組類型。

RTCP的5種分組類型
發送端報告分組SR(Sender Report)用來使發送端以多播方式向所有接收端報告發送情況。SR分組的主要內容有:相應的RTP流的SSRC,RTP流中最新產生的RTP分組的時間戳和NTP,RTP流包含的分組數,RTP流包含的字節數。SR包的封裝如下圖所示。
RTCP頭部格式
版本(V):2 bits 同RTP包頭域。

填充(P):1bits 同RTP包頭域。

接收報告計數器(RC):5bits,該SR包中的接收報告塊的數目,可以爲零。

包類型(PT):8 bits,SR包是200。

長度域(Length):16 bits,其中存放的是該SR包以32 bits爲單位的總長度減一。

同步源(SSRC):SR包發送者的同步源標識符。與對應RTP包中的SSRC一樣。

NTP Timestamp(Network time protocol):32 bits, SR包發送時的絕對時間值。NTP的作用是同步不同的RTP媒體流。

RTP Timestamp:32 bits, 與NTP時間戳對應,與RTP數據包中的RTP時間戳具有相同的單位和隨機初始值。

Sender’s packet count:32 bits, 從開始發送包到產生這個SR包這段時間裏,發送者發送的RTP數據包的總數. SSRC改變時,這個域清零。

Sender`s octet count:32 bits, 從開始發送包到產生這個SR包這段時間裏,發送者發送的淨荷數據的總byte數(不包括頭部和填充)。發送者改變其SSRC時,這個域要清零。

同步源n的SSRC標識符:32 bits, 該報告塊中包含的是從該源接收到的包的統計信息。

丟失率(Fraction Lost):8 bits, 表明從上一個SR或RR包發出以來從同步源n(SSRC_n)來的RTP數據包的丟失率。

累計的包丟失數目:24bits, 從開始接收到SSRC_n的包到發送SR,從SSRC_n傳過來的RTP數據包的丟失總數。

收到的擴展最大序列號:32 bits, 從SSRC_n收到的RTP數據包中最大的序列號,

接收抖動(Interarrival jitter):32 bits, RTP數據包接受時間的統計方差估計

上次SR時間戳(Last SR,LSR):32 bits, 取最近從SSRC_n收到的SR包中的NTP時間戳的中間32比特。如果目前還沒收到SR包,則該域清零。

上次SR以來的延時(Delay since last SR,DLSR):32 bits, 上次從SSRC_n收到SR包到發送本報告的延時。

4.3 RTP會話過程

當應用程序建立一個RTP會話時,應用程序將確定一對目的傳輸地址。目的傳輸地址由一個網絡地址和一對端口組成,有兩個端口:一個給RTP包,一個給RTCP包,使得RTP/RTCP數據能夠正確發送。RTP數據發向偶數的UDP端口,而對應的控制信號RTCP數據發向相鄰的奇數UDP端口(偶數的UDP端口+1),這樣就構成一個UDP端口對。 RTP的發送過程如下,接收過程則相反。

  1. RTP協議從上層接收流媒體信息碼流(如H.264),封裝成RTP數據包;RTCP從上層接收控制信息,封裝成RTCP控制包。
  2. RTP將RTP 數據包發往UDP端口對中偶數端口;RTCP將RTCP控制包發往UDP端口對中的接收端口。

4.4 常見問題以及解決方案

  1. 怎樣重組亂序的數據包
    可以根據RTP包的序列號來排序。

  2. 怎樣獲得數據包的時序
    可以根據RTP包的時間戳來獲得數據包的時序。

  3. 聲音和圖像怎麼同步
    根據聲音流和圖像流的相對時間(即RTP包的時間戳),以及它們的絕對時間(即對應的RTCP包中的RTCP),可以實現聲音和圖像的同步。

  4. 接收緩衝和播放緩衝的作用
    如1.3.1所述,接收緩衝用來排序亂序了的數據包;播放緩衝用來消除播放的抖動,實現等時播放。

5. 參考

[RTP協議分析]
https://blog.csdn.net/u011006622/article/details/80675054
[RTP協議全解析(H264碼流和PS流)]
https://blog.csdn.net/chen495810242/article/details/39207305

6. 測試資源

rtsp在線資源
https://blog.csdn.net/pkueecser/article/details/8677022
rtmp在線資源
https://blog.csdn.net/language_zcx/article/details/96011836

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章