RTP協議基本分析(RTSP、WebRTC使用)

目錄

  • 1、介紹
  • 2、RTP
  • 3、格式
  • 4、RTP打包H264
    • 4.1、H264打包方式之Single NAL Unit
    • 4.2、H264打包方式之FU-A
      • 4.2.1、FU indication
      • 4.2.2、FU header
      • 4.2.3、第一個IDR幀的NALU第一個切片
      • 4.2.4、第一個IDR幀的NALU第二個切片
      • 4.2.5、第一個IDR幀的NALU最后一個切片
  • 5、RTP打包AAC
    • 5.1、AU-headers-length
    • 5.2、AU-header
    • 5.3、AU
    • 5.4、RTSP/SDP中AAC相關配置
    • 5.5、AU-Header數據段的格式

1、介紹

實時流傳輸協議(RTSP:Real Time Streaming Protocol)是一種網絡傳輸協議,旨在發送低延遲流。
該協議由RealNetworks,Netscape和哥倫比亞大學的專家在1996年開發。它定義了應如何打包流中的數
據以進行傳輸。
在這里插入圖片描述

2、RTP

RTP協議原理,負責對流媒體數據進行封包并實現媒體流的實時傳輸,即它按照RTP數據包格式來封裝流媒體數據,并利用與它綁定的協議進行數據包的傳輸。

RTP可以基于UDP和TCP兩種方式傳輸,兩種方式大致是一樣的,下面主要都是基于UDP的分析:

RTP在端口號1025到65535之間選擇一個未使用的偶數UDP端口號,而在同一次會話中的RTCP則使用下一個基數UDP端口號。

3、格式

RTP報文由兩部分組成:報頭和有效載荷。RTP報頭格式如下圖所示,其中:V:RTP協議的版本號,占2位,當前協議版本號為2。P:填充標志,占1位,如果P=1,則在該報文的尾部填充一個或多個額外的八位組,它們不是有效載荷
的一部分。X:擴展標志,占1位,如果X=1,則在RTP報頭后跟有一個擴展報頭。
CC:CSRC計數器,占4位,指示CSRC 標識符的個數。M: 標記,占1位,不同的有效載荷有不同的含義,對于視頻,標記一幀的結束;對于音頻,標記幀的開
始。PT: 有效載荷類型,占7位,用于說明RTP報文中有效載荷的類型,如GSM音頻、JPEM圖像等。
序列號:占16位,用于標識發送者所發送的RTP報文的序列號,每發送一個報文,序列號增1。接收者
通過序列號來檢測報文丟失情況,重新排序報文,恢復數據。時戳(Timestamp):占32位,時戳反映了該RTP報文的第一個八位組的采樣時刻。接收者使用時戳來
計算延遲和延遲抖動,并進行同步控制。同步信源(SSRC)標識符:占32位,用于標識同步信源。該標識符是隨機選擇的,參加同一視頻會議的
兩個同步信源不能有相同的SSRC。特約信源(CSRC)標識符:每個CSRC標識符占32位,可以有015個。每個CSRC標識了包含在該RTP
報文有效載荷中的所有特約信源。

在這里插入圖片描述

1 typedef struct _rtp_header_t
2 {
3 uint32_t v:2; /* protocol version */
4 uint32_t p:1; /* padding flag */
5 uint32_t x:1; /* header extension flag */
6 uint32_t cc:4; /* CSRC count */
7 uint32_t m:1; /* marker bit */
8 uint32_t pt:7; /* payload type */
9 uint32_t seq:16; /* sequence number */
10 uint32_t timestamp; /* timestamp */
11 uint32_t ssrc; /* synchronization source */
12 } rtp_header_t;

同步信源:是指產生媒體流的信源,例如麥克風、攝像機、RTP混合器等。它通過RTP報頭中的一個32位數
字SSRC標識符來標識,而不依賴于網絡地址,接收者將根據SSRC標識符來區分不同的信源,進行RTP報
文的分組。

特約信源:是指當混合器接收到一個或多個同步信源的RTP報文后,經過混合處理產生一個新的組合RTP報
文,并把混合器作為組合RTP報文的SSRC,而將原來所有的SSRC都作為CSRC傳送給接收者,使接收者
知道組成組合報文的各個SSRC。
在這里插入圖片描述
例如:
有三個信號源各發出一路rtp流,RTP1攜帶的SSRC是SSRC1,RTP2攜帶的SSRC是SSRC2,
RTP3攜帶SSRC3,這三路RTP流到達混合器時,混合器會將這三路流混合成一路流發出去,它會把這三
路流的SSRC記錄下來,形成一個列表,叫CSRC表,在發送的混合RTP流中,SSRC域填充的字段是混合
器本身的SSRC4,而CSRC字段則會根據該包的負載的源來填入。

如當前的RTP包的負載是來自SSRC1的,那么在當前RTP包的CSRC字段填入SSRC1。
這樣接收者就可以根據CSRC來區分不同的信源。

4、RTP打包H264

RTP的特點不僅僅支持承載在UDP上,這樣利于低延遲音視頻數據的傳輸,另外一個特點是它允許
通過其它協議接收端和發送端協商音視頻數據的封裝和編解碼格式,這樣固定頭的playload type字
段就比較靈活。

H.264標準協議定義了兩種不同的類型:一種是VCL即Video Coding Layer , 一 種 是 NAL 即
Network Abstraction Layer。其中前者就是編碼器吐出來的原始編碼數據,沒有考慮傳輸和存儲
問題。后面這種就是為了展現H.264的網絡親和性,對VCL輸出的slice片數據進行了封裝為
NALUs(NAL Units),然后再封裝為RTP包進行傳輸。

NALU的基本格式是:NALU Header + NALU Data,其中NALU的頭由一個字節組成如下所示:
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
一、
1-11就是NALU的單個包類型,但是一個NALU的大小是不一樣的,如果是非視頻數據的
SPS PPS才十幾個字節,對于IDR幀,則有可能幾十KB。
這樣把NALU打包到RTP方式就很多,分為:
一個RTP包承載一個NALU;
多個NALU合并到一個RTP;
一個大的NALU切分成多個RTP。

二、
同時由于時間戳的問題,就有了24-29幾種類型。
但是對于發送端組RTP包的一方來說,盡可能找簡單的打包方式。對于接受端則需要適配各種發送
端的打包方式,因為無法決定輸入源的打包方式。
(打包的時候不要搞太復雜的模式)

  1. 我們對于NALU的長度<=1400(rtp payload size)的則采用的是單一NALU打包到單一的RTP
    包中;
  2. 我們對于NALU的長度>1400的則采用了FU-A的方式進行了打包,這種就是把一個大的NALU進
    行了切分,最后接收方則進行了合并,把多個RTP包合并成一個完整的NALU即可;
  3. 為什么NALU的長度大于1400字節就要進行FU-A切片,是因為底層MTU大小值一般為1500,從
    傳輸效率講,使用1400作為切分條件。
    RTP最大數據包(包含RTP頭部) = MTU - UDP首部 - IP 報文首部

4.1、H264打包方式之Single NAL Unit

一個RTP包打包一個單獨的NALU方式,其實最好理解,就是在RTP固定頭后直接填充NLAU
單元數據即可,即:
RTP Header + NALU Header + NALU Data; (不包括startcode)
文件中的SPS:
在這里插入圖片描述
RTP包中的SPS:
在這里插入圖片描述

4.2、H264打包方式之FU-A

需要了解兩個數據包頭即FU indicator和Fu header。

4.2.1、FU indication

在這里插入圖片描述
這里面的的F和NRI就是NALU頭的前面三個bit位,后面的
TYPE就是NALU的FU-A類型28,這樣在RTP固定頭后面第一字節的后面5bit提取出來就確認了該
RTP包承載的不是一個完整的NALU,是其一部分。

那么問題來了,一個NALU切分成多個RTP包傳輸,那么到底從哪里開始哪里結束呢?
可能有人說RTP包固定頭不是有mark標記么,注意區分那個是以幀圖像的結束標記,這里要確定是NALU結束
的標記,其次NALU的類型呢?那么就需要RTP固定12字節后面的Fu Header來進行區分。

4.2.2、FU header

在這里插入圖片描述

字段解釋:
S: 1 bit 當設置成1,開始位指示分片NAL單元的開始。當跟隨的FU荷載不是分片NAL單元荷載的開
始,開始位設為0。E: 1 bit 當設置成1, 結束位指示分片NAL單元的結束,即, 荷載的最后字節也是分片NAL單元的最后
一個字節,當跟隨的FU荷載不是分片NAL單元的最后分片,結束位設置為0。
也就是說一個NALU切片時,第一個切片的SE是10,然后中間的切片是00,最后一個切片時11。R: 1 bit
保留位必須設置為0,接收者必須忽略該位。Type: 5 bits
此處的Type就是NALU頭中的Type,1-23的那個值,表示 NAL單元荷載類型定義。

4.2.3、第一個IDR幀的NALU第一個切片

在這里插入圖片描述

FU indication:
十六機制:0x7C
二進制:0111 1100
FU header:
十六進制:0x85
二進制:1000 0101
這里的SE是10,則說明該RTP包承載的NALU的第一個切片。

4.2.4、第一個IDR幀的NALU第二個切片

在這里插入圖片描述

FU indication:
十六機制:0x7C
二進制:0111 1100
FU header:
十六進制:0x05
二進制:0000 0101
這里的SE是00,則說明該RTP包承載的NALU的中間切片。

4.2.5、第一個IDR幀的NALU最后一個切片

在這里插入圖片描述

FU indication:
十六機制:0x7C
二進制:0111 1100
FU header:
十六進制:0x45
二進制:0100 0101
這里的SE是01,則說明該RTP包承載的NALU的最后一個切片。

5、RTP打包AAC

過程:

  1. 需要將aac的前7個(或9個)字節的ADTS去掉,即是跳過adts header。
  2. 添加RTP Header。
  3. 添加AU_HEADER_LENGTH。
  4. 添加AU_HEADER。
  5. 添加AU(去掉ADTS的aac數據)數據。

如:

注意:一個RTP包中可以有一個AU-headers-length 和 n個AU-header和 n個AU(AU每包實際音頻數據流)

5.1、AU-headers-length

頭兩個字節表示au-header的長度,單位是bit。 一個AU-header長度是兩個字節(16bit)因為可以有多
個au-header所以AU-headers-length的值是 16的倍數,一般音頻都是單個音頻數據流的發送,所以
AU-headers-length的值是16
//AU_HEADER_LENGTH
bytes[12] = 0x00; //高位
bytes[13] = 0x10; //低位 只有一個AU_HEADER
因為單位是bit, 除以8就是auHeader的字節長度;又因為單個auheader字節長度2字節,所以再除以2就
是auheader的個數。
(注意:AU-header長度并不是固定為2字節,具體要看SDP)

5.2、AU-header

au-header的高13個bits就是一個au 的字節長度:
//AU_HEADER
bytes[14] = (byte)((len & 0x1fe0) >> 5); //高位
bytes[15] = (byte)((len & 0x1f) << 3); //低位
(注意:AU-header長度并不是固定為2字節,具體要看SDP)

5.3、AU

音頻實際數據(去掉ADTS的aac數據)

5.4、RTSP/SDP中AAC相關配置

1 v=0
2 o=- 16128587303007558182 16128587303007558182 IN IP4 WINDOWS-75ID
U9Q
3 s=Unnamed
4 i=N/A
5 c=IN IP4 0.0.0.0
6 t=0 0
7 a=tool:vlc 3.0.5
8 a=recvonly
9 a=type:broadcast
10 a=charset:UTF-8
11 a=control:rtsp://192.168.2.195:8554/
12 m=audio 0 RTP/AVP 96
13 b=AS:128
14 b=RR:0
15 a=rtpmap:96 mpeg4-generic/22050
16 a=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC-hbr; config
=138856e500; sizeLength=13; indexLength=3; indexDeltaLength=3; Pr
ofile=1;
17 a=control:rtsp://192.168.2.195:8554/trackID=4
18 m=video 0 RTP/AVP 96
19 b=AS:800
20 b=RR:0
21 a=rtpmap:96 H264/90000
22 a=fmtp:96 packetization-mode=1;profile-level-id=42c01e;sprop-para
meter-sets=Z0LAHtoCQKeX/8CgAJ/EAAADAZAAAF2qPFi6gA==,aM43IA==;
23 a=control:rtsp://192.168.2.195:8554/trackID=5

streamtype對于AAC, 固定為5。
profile-level-id固定為1。
config, SizeLength, IndexLength, IndexDeltaLength作用:
config是16進制的, 前兩個字節 1388 , 表示采樣率為22050, 1個channel。
前兩個字節的為ios-14996-3中定義的AudioSpecificConfig, 前13個bits的格式為:
在這里插入圖片描述
samplingFrequencyIndex的取值:
在這里插入圖片描述
1388 轉換成2進制為 0001 0011 1000 1000
audioObjectType為 00010 , 即 2
samplingFrequencyIndex為 0111 , 即 7 , 對應的采樣頻率為 22050
channelConfiguration為 0001 , 表示channel數量為1。

sizeLength=13; indexLength=3; indexDeltaLength=3涉及到音頻的AU Header。

5.5、AU-Header數據段的格式

在這里插入圖片描述
在這里插入圖片描述

其它的值都是可選的, 如果sdp中沒有出現相關的參數(或者為0), 則表示它們不出現。
以最簡單的情況舉例, 假設aac數據長度為200字節, 只有一個au-header。
200 的二進制為 0000011001000。 (補足為13 bits)
AU-headers-length 值為16, 因為只有一個au-header, au-header中
只有AU-size和AU-Index, 共占用16bits。

整個au-header數據段的內容為

0000 0000 0000 1000 0000011001000 000

如果一個rtp中只有一個aac包, 不需要加AU-Header, 那么sdp中的aac參數可以簡化為

a=fmtp:96 streamtype=5; profile-level-id=1; mode=AAC-hbr; config=1
38856e500;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378871.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378871.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378871.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

對照片進行邊緣化處理,并將邊緣化處理后的結果保存

對照片進行邊緣化處理&#xff0c;并將邊緣化處理后的結果保存 import cv2 from matplotlib import pyplot as plt img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/water1.png,1)#第一個參數為選擇照片的路徑&#xff0c;注意照片路徑最后一個為正斜杠其他都為反斜杠&…

小皇帝,籃球,熱火

失敗&#xff0c;又一次&#xff0c;完全預料之中. 熱火的防守早已是千瘡百孔&#xff0c;熱火的攻擊也是亂無頭緒. 現在的熱火&#xff0c;需要詹姆斯無球的跑動&#xff0c;需要韋德的助攻。 轉載于:https://www.cnblogs.com/JeffChen/archive/2010/11/12/2600335.html

fastjson轉換時有大括號或者冒號或者有中括號_[Python Basic] 字符串處理以及類型轉換 1...

String Manipulation & Typecasting (1)1. 文本復制以及連接1.1 Multiply sign使用 multiply sigh/乘號* 來復制文本片段。乘號復制文本舉例&#xff1a; print("Hi" * 3) # output: HiHiHi print("*" * 10)# output:**********1.2 連接1.2.1 使用 plu…

Java IdentityHashMap size()方法與示例

IdentityHashMap類的size()方法 (IdentityHashMap Class size() method) size() method is available in java.util package. size()方法在java.util包中可用。 size() method is used to return the size (i.e. How many key-value pair exists) of this IdentityHashMap. siz…

讀《深入分析Java Web技術內幕》

這里這本書的預讀章節&#xff0c;看完預讀部分&#xff0c;解答了一些疑惑&#xff0c;也相信這是一本夯實Java Web架構體系的好書。 HTTP協議解析 開發一般使用firefox的firebug調試&#xff0c;這的確是一個利器&#xff0c;HTTP的請求頭響應頭一目了然。 瀏覽器緩存機制 當…

windows mobile多國語言實現[轉]

介紹一種多國語言的實現辦法&#xff0c;這也是微軟推薦的方式&#xff0c;打開windows mobile下的windows目錄可以看到有很多以MUI為后綴名的文件&#xff0c;例如shellres.dll.0804.mui、shell.dll.0804.mui。。。。。。我們可以用eXeScope.exe或者resources hacker這樣的文件…

RTSP協議基本分析

目錄一、介紹二、RTSP與HTTP三、RTSP推流基本過程1、OPTION 查詢服務器端可用方法1.1、Client 請求1.2、Server 回復2、ANNOUNCE 發送媒體描述信息2.1、Client 請求2.2、Server 回復3、SETUP建立RTSP會話3.1、Client 請求&#xff08;視頻流&#xff09;3.2、Server 回復&#…

找取照片上的25個特征點,并保存結果

找取照片上的25個特征點&#xff0c;并保存結果 import numpy as np import cv2 from matplotlib import pyplot as plt img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/water1.png,1)#第一個參數為選擇照片的路徑&#xff0c;注意照片路徑最后一個為正斜杠其他都為反斜杠…

nutsdb與mysql_分享下 nutsdb 單機 1 億、10 億數據實測

大家好&#xff0c; 想給大家分享下我最近為 nutsdb 做的數據測試。測試項目起因事情起因是這個 issue &#xff0c;簡單說就是內存高了&#xff0c;不夠用了。可能很多人不知道 NutsDB。簡單介紹下&#xff0c;NutsDB 是我幾個月以前開源的一個 Go 語言編寫的內嵌型 KV 數據庫…

java 方法 示例_帶有示例的Java EnumSetSupplementOf()方法

java 方法 示例EnumSet類complementOf()方法 (EnumSet Class complementOf() method) complementOf() method is available in java.util package. clipartOf()方法在java.util包中可用。 complementOf() method is used to contain all the elements of this EnumSet that are…

在需要時開啟Perl新特性

從5.10開始&#xff0c;新特性必須開啟才能使用。Perl默認不啟用新特性保持向后兼容。 如果想啟用新特性&#xff0c;可以使用新的-E開關。打開所有的新特性。 % perl5.10.1 -E say.pl #開啟5.10.1 版本的所有新特性 在源代碼中使用 use 指令之后指定perl版本號就可以了。 use …

P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介

目錄1. IPv4協議和NAT的由來2. NAT的工作模型和特點2.1、NAT的概念模型2.2、一對一的NAT2.3、一對多的NAT2.4、按照NAT端口映射方式分類2.4.1全錐形NAT2.4.2限制錐形NAT2.4.3端口限制錐形NAT2.4.4對稱型NAT3. NAT的限制與解決方案3.1、IP端到端服務模型3.2、NAT的弊端3.3、NAT穿…

決定孩子命運的八大關鍵問題

你可以不是天才&#xff0c;但你可以是天才的父母&#xff01;樹立做父母正確的家庭教育觀念&#xff0c;為孩子建造一個良好的人生平臺&#xff0c;讓孩子有很好的人格修養&#xff0c;懂得做人&#xff0c;懂得成功的真正含義。簡單方便&#xff0c;容易操作&#xff0c;適合…

java calendar_Java Calendar internalGet()方法與示例

java calendar日歷類internalGet()方法 (Calendar Class internalGet() method) internalGet() method is available in java.util package. internalGet()方法在java.util包中可用。 internalGet() method is used to get the value of the given field(fi) of this Calendar …

顯示照片的二維直方圖

顯示照片的二維直方圖 import cv2 from matplotlib import pyplot as plt img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/water1.png,1)#第一個參數為選擇照片的路徑&#xff0c;注意照片路徑最后一個為正斜杠其他都為反斜杠&#xff1b;第二個參數&#xff0c;其中1表示…

周五怎么表示 mysql_完美起航-MySQL找每個月最后一個星期五--函數定義與使用

數據庫作業有一道題是這樣子的&#xff1a;有一張名叫emp的表記錄員工信息&#xff0c;其中有如下字段 HIREDATE 表示員工被雇用的日期&#xff1a;然后問題是這樣的&#xff1a;q7.Show details of employee hiredates and the date of their first payday.(Paydays occur on…

要想能安心,必須先死心。

其實&#xff0c;不論是感情&#xff0c;還是學習、工作還是生活&#xff0c;不都是如此&#xff1f;曾經年少懷抱一個名校夢&#xff0c;如果高考不成功&#xff0c;那么你一定會選擇考研讓自己死一次心&#xff1b;小時候特別喜歡 某個職業&#xff0c;長大了你拋棄所有機會追…

silverlight學習總結【完】

以下內容是個人理解&#xff0c;不保證正確性。且假設使用C#&#xff0c;并且有一定的相關知識和XML基礎。 silverlight是什么&#xff0c;能做什么 silverlight用XAML來做前端界面&#xff0c;用.NET或者JS作為程序腳本支持&#xff0c;在瀏覽器內外運行的應用。可以認為和FLA…

P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解

目錄1、內容概述2、反向鏈接技術&#xff1a;一種特殊的P2P場景&#xff08;通信雙方中只有一方位于NAT設備之后&#xff09;3、基于UDP協議的P2P打洞技術詳解3.1、原理概述3.2、典型P2P情景1&#xff1a; 兩客戶端位于同一NAT設備后面&#xff08;即相同內網中&#xff09;3.3…

Java Byte類的compareTo()方法和示例

簡短的類compareTo()方法 (Short class compareTo() method) compareTo() method is available in java.lang package. compareTo()方法在java.lang包中可用。 compareTo() method is used to check equality or inequality for this Byte object against the given Byte objec…