翻譯自:https://www.kurento.org/blog/rtp-i-intro-rtp-and-sdp
一、The Real-time Transport Protocol -- RTP
FFmpeg and GStreamer 是兩個工具可操作rtp,也提供可編程。
rtp已經成為事實的標准用於webRTC或者其他工具傳輸音視頻。原理是一個rtp會話包含一堆參與者,即peer。發送peer吧媒體拆開成chunks,即rtp packets,用udp發送給接收者peer。反之,接收者重新組合。
rtp packet包括固定長的頭,可為空的源列表,負載數據payload。
(Bitmap) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |V=2|P|X| CC |M| PT | sequence number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | synchronization source (SSRC) identifier | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | contributing source (CSRC) identifiers | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | payload ... | | +-------------------------------+ | | RTP padding | RTP pad count | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
rtp幾十年前制定,現在很多屬性已經不用。挑重點:
PT
(Payload Type)
除了以前標准定義的,現在一般用自己動態定義的,范圍為 [96-127]。比如chrome 96是video VP8, pt 98是vp9,102是h264.
sequence number
隨機數開頭,然后遞增,來確定包的順序。
timestamp
也是隨機數開頭,按時鍾類型(clock rate)增長,通過相對增量確定改播放的時刻。
SSRC
(Synchronization Source)
隨機串,每個視頻音頻在rtp會話中唯一。通過這個識別自己屬於哪個媒體。
二、RTP Control Protocol -- RTCP
由於缺失了tcp的保障,rtp的udp傳輸需要rtcp去控制。發送方提供RTP和RTCP Sender Reports,接收方接收。rtcp發送比rtp少,基本1秒;而rtp更快。
- SSRCs used by each media.
- CNAME, an identifier that can be used to group several medias together.
- Different timestamps, packet counts, and jitter estimations, from senders and receivers. These statistics can then be used by each peer to detect bad conditions such as packet loss.
另外還提供 RTCP Feedback (RTCP-FB)
- Google REMB is part of an algorithm that aims to adapt the sender video bitrate in order to avoid issues caused by network congestion. See Kurento | Congestion Control for a quick summary on this topic.
- NACK is used by the receiver of a stream to inform the sender about packet loss. Upon receiving an RTCP NACK packet, the sender knows that it should re-send some of the RTP packets that were already sent before.
- NACK PLI (Picture Loss Indication), a way that the receiver has to tell the sender about the loss of some part of video data. Upon receiving this message, the sender should assume that the receiver will not be able to decode further intermediate frames, and a new refresh frame should be sent instead. More information in RFC 4585.
- CCM FIR (Full Intra Request), another method that the receiver has to let the sender know when a new full video frame is needed. FIR is very similar to PLI, but it's a lot more specific in requesting a full frame (also known as keyframe). More information in RFC 5104.
這些RTP的功能有沒有實現,需要看下面的描述協議sdp。
三、Session Description Protocol -- SDP RFC 4566
在會話前需要確定網絡相關和媒體相關信息。sdp是文本型松散格式結構。偏向介紹WebRTC的SDP Offer/Answer 模型。
sdp對於發送方描述了想要什么類型接收者;接收者回應了想讓發送者以什么格式發送。
a=行用了添加屬性。
示例1:
v=0 o=- 0 0 IN IP4 127.0.0.1 s=- c=IN IP4 127.0.0.1 t=0 0 m=video 5004 RTP/AVP 96 a=rtpmap:96 VP8/90000
兩部分,前5行"session-level description":
v=0 o=- 0 0 IN IP4 127.0.0.1 s=- c=IN IP4 127.0.0.1 t=0 0
It describes things such as the peer's host IP address, time bases, and summary description. 大部分可省略,0或 (-
).
下面是 "media-level description", m=
和 (a=
) :
m=video 5004 RTP/AVP 96 a=rtpmap:96 VP8/90000
- There is a single video track.
5004
is the local port where other peers should send RTP packets.5005
本地udp端口 RTCP packets. 總是 RTP port + 1.RTP/AVP
媒體定義 RTP/AVP, as defined in RFC 3551.96
Payload Type在接下來的 RTP packets.VP8/90000
視頻編碼和時鍾頻率 RTP packets.
示例二,帶注釋:
# Protocol version; always 0 v=0 # Originator and session identifier o=jdoe 2890844526 2890842807 IN IP4 224.2.17.12 # Session description s=SDP Example # Connection information (network type and host address, like in 'o=') c=IN IP4 224.2.17.12 # NTP timestamps for start and end of the session; can be 0 t=2873397496 2873404696 # First media: a video stream with these parameters: # * The RTP port is 5004 # * The RTCP port is 5005 (implicitly by using RTP+1) # * Adheres to the "RTP Profile for Audio and Video" (RTP/AVP) # * Payload Type can be 96 or 97 m=video 5004 RTP/AVP 96 97 # Payload Type 96 encoding corresponds to VP8 codec a=rtpmap:96 VP8/90000 # Payload Type 97 encoding corresponds to H.264 codec a=rtpmap:97 H264/90000
rtp map定義了Payload type和值:比如 97是H264,時鍾頻率是9000.
示例三,
定義多個媒體用 m= 分割
v=0 o=- 0 0 IN IP4 127.0.0.1 s=- c=IN IP4 127.0.0.1 t=0 0 m=audio 5006 RTP/AVP 111 a=rtpmap:111 opus/48000/2 a=fmtp:111 minptime=10;useinbandfec=1 m=video 5004 RTP/AVP 96 98 102 a=rtcp:54321 a=rtpmap:96 VP8/90000 a=rtpmap:98 VP9/90000 a=rtpmap:102 H264/90000 a=fmtp:102 profile-level-id=42001f
兩個媒體。第一個是音頻:
m=audio 5006 RTP/AVP 111 a=rtpmap:111 opus/48000/2 a=fmtp:111 minptime=10;useinbandfec=1
PT是111,Opus,48000Hz,2聲道。fmtp
("format parameters")是附加的opus參數。
第二部分是視頻:96
,98
, or102
; 優選96。 102是h264,帶編解碼參數是profile-level-id為42001f。
其他附加屬性:
a=rtcp:53020 自指定了rtcp端口。而不是默認的+1
a=rtcp-mux 指rtp和rtcp用同一端口
a=rtcp-rsize 優化傳輸,在RTP/AVPF時才能用。
a=recvonly 接收方只接收,不發送rtp。當然rtcp還是會發送。
a=sendonly 發送方只發送。rtcp包括。
a=sendrecv 隱含值。
四、SDP Offer/Answer Model (RFC 3264)
初始化sdp會話時的協商。這個模型在SIP或者WebRTC使用。
rtp會話的發起者發起叫sdp offer。接收者根據發來信息,生成新的一個sdp返回,叫sdp answer。RFC 3264 建立規則。
- 回應放自己的ip地址在
o=
andc=
行. - All media-level descriptions should be copied from the SDP Offer to the SDP Answer.
- 不接收某個媒體,通過設置 RTP port to
0
. - 不期望的 Payload Types, 從媒體描述中移除. a= 這類屬性也一樣。
- 想使用媒體,需要設置新的端口. Same for the RTCP port, if
a=rtcp
is in use. a=recvonly
對於對方是a=sendonly 反之亦然
vice versa.
示例:
sdp offer:
v=0 o=- 0 0 IN IP4 127.0.0.1 s=Sample SDP Offer c=IN IP4 127.0.0.1 t=0 0 m=audio 5006 RTP/AVP 111 a=rtpmap:111 opus/48000/2 a=sendonly m=video 5004 RTP/AVP 96 98 102 a=rtcp:5554 a=rtpmap:96 VP8/90000 a=rtpmap:98 VP9/90000 a=rtpmap:102 H264/90000 a=sendonly m=video 9004 RTP/AVP 96 a=rtpmap:96 VP8/90000 a=sendonly
3路輸入,比如可能是1路麥克風,1個攝像頭,1個桌面捕獲。
sdp answer:選中h264,a=rtcp:
v=0 o=- 3787580028 3787580028 IN IP4 172.17.0.1 s=Sample SDP Answer c=IN IP4 127.0.0.1 t=0 0 m=audio 28668 RTP/AVP 111 a=rtpmap:111 opus/48000/2 a=recvonly m=video 35585 RTP/AVP 102 a=rtpmap:102 H264/90000 a=recvonly m=video 0 RTP/AVP 96
- 設置了timing values 在
o=
. - The RTP port for audio is specified, so the offerer will know where to send its RTP audio (and the corresponding RTCP packets).
- 視頻選擇了
102
, 對應 H.264 codec. 不支持的屬性扔掉。 - answerer不支持standalone RTCP, 移除了
a=rtcp
屬性.offer方應該注意到,並發送到35586
(RTP + 1). - 接收方只支持一路,設置 RTP port =
0。
- 不支持的屬性都被拋掉。
五、signaling of the session
sdp的交換方式並沒有規定。各種方法可用,如最簡單的粘貼賦值過去;數據庫共享,tcp的websocket,消息服務器MQTT,RabbitMQ,Redis等等都行。
六、附錄:
6.1 Real Time Streaming Protocol -- RTSP
rtsp協議類似HTTP協議。http協議有個http服務提供GET
, POST
, DELETE
, CONNECT
等,RTSP協議也有個rtsp服務提供DESCRIBE
, SETUP
, ANNOUNCE
, TEARDOWN
, PLAY
, PAUSE
, RECORD
, etc.
rtsp包括了signaling。如果簡單的rtp和sdp,只是peer交換sdp。而rtsp的客戶端可傳輸所有命令和sdp通過tcp。
6.2 Secure Real-time Transport Protocol -- SRTP
rtp任何人可接入rtp會話。安全rtp提供以下保護:
- 只有負載保護。RTP headers還可查看調試時。在分發或者靜態集群distribution or statistics aggregation時有用頭信息.
- Asserts that all RTP and RTCP packets are authenticated and come from the source where they purport to be coming.
- Ensures the integrity of the entire RTP and RTCP packets, i.e. protecting against arbitrary modifications of the packet contents.
- Prevents replay attacks, a form of "man-in-the-middle" attacks.
RTP/RTCP協議簡介
實時傳輸協議RTP(RealtimeTransport Protocol):是針對Internet上多媒體數據流的一個傳輸協議, 由IETF(Internet工程任務組)作為RFC1889發布。RTP被定義為在一對一或一對多的傳輸情況下工作,其目的是提供時間信息和實現流同步。RTP的典型應用建立在UDP上,但也可以在TCP或ATM等其他協議之上工作。RTP本身只保證實時數據的傳輸,並不能為按順序傳送數據包提供可靠的傳送機制,也不提供流量控制或擁塞控制,它依靠RTCP提供這些服務。
實時傳輸控制協議RTCP(RealtimeTransportControl Protocol):負責管理傳輸質量在當前應用進程之間交換控制信息。在RTP會話期間,各參與者周期性地傳送RTCP包,包中含有已發送的數據包的數量、丟失的數據包的數量等統計資料,因此,服務器可以利用這些信息動態地改變傳輸速率,甚至改變有效載荷類型。RTP和RTCP配合使用,能以有效的反饋和最小的開銷使傳輸效率最佳化,故特別適合傳送網上的實時數據。
RTCP主要有4個功能:
(1)用反饋信息的方法來提供分配數據的傳送質量,這種反饋可以用來進行流量的擁塞控制,也可以用來監視網絡和用來診斷網絡中的問題;
(2)為RTP源提供一個永久性的CNAME(規范性名字)的傳送層標志,因為在發現沖突或者程序更新重啟時SSRC(同步源標識)會變,需要一個運作痕跡,在一組相關的會話中接收方也要用CNAME來從一個指定的與會者得到相聯系的數據流(如音頻和視頻);
(3)根據與會者的數量來調整RTCP包的發送率;
(4)傳送會話控制信息,如可在用戶接口顯示與會者的標識,這是可選功能。
RTP/RTCP工作過程
工作時,RTP協議從上層接收流媒體信息碼流(如H.263),裝配成RTP數據包發送給下層,下層協議提供RTP和RTCP的分流。如在UDP中,RTP使用一個偶數號端口,則相應的RTCP使用其后的奇數號端口。RTP數據包沒有長度限制,它的最大包長只受下層協議的限制。
RTP會話和流的兩級分用
一個RTP會話(Session)包括傳給某個指定目的地對(Destination Pair)的所有通信量,發送方可能包括多個。而從同一個同步源發出的RTP分組序列稱為流(Stream),一個RTP會話可能包含多個RTP流。一個RTP分組在服務器端發送出去的時候總是要指定屬於哪個會話和流,在接收時也需要進行兩級分用,即會話分用和流分用。只有當RTP使用同步源標識(SSRC)和分組類型(PTYPE)把同一個流中的分組組合起來,才能夠使用序列號(SequenceNumber)和時間戳(Timestamp)對分組進行排序和正確回放。
由於實時數據的獨有性,不同實時客戶可以共用一個RTP實時服務線程和一個RTCP實時服務線程,這樣可以大大減小服務器的負擔,而每個文件客戶由於請求的文件不同,相應地對速度和開始時間的要求都可能不同,所以需要有自己獨有的RTP文件服務線程和RTCP文件服務線程。
RTP服務線程負責把實時數據流發送給客戶,RTCP服務線程根據RTP線程的統計數據,產生發送方報告給客戶。RTP線程和RTCP線程之間通過一段共享內存交互統計數據,對共享內存必須設置互斥體進行保護,防止出現錯誤讀寫。在這種方式下,服務器可以根據每個用戶的不同請求和具體情況方便地提供不同的服務。
RTP 時間戳的處理
時間戳字段是RTP首部中說明數據包時間的同步信息,是數據能以正確的時間順序恢復的關鍵。時間戳的值給出了分組中數據的第一個字節的采樣時間(Sampling Instant),要求發送方時間戳的時鍾是連續、單調增長的,即使在沒有數據輸入或發送數據時也是如此。在靜默時,發送方不必發送數據,保持時間戳的增長,在接收端,由於接收到的數據分組的序號沒有丟失,就知道沒有發生數據丟失,而且只要比較前后分組的時間戳的差異,就可以確定輸出的時間間隔。
RTP規定一次會話的初始時間戳必須隨機選擇,但協議沒有規定時間戳的單位,也沒有規定該值的精確解釋,而是由負載類型來確定時鍾的顆粒,這樣各種應用類型可以根據需要選擇合適的輸出計時精度。
在RTP傳輸音頻數據時,一般選定邏輯時間戳速率與采樣速率相同,但是在傳輸視頻數據時,必須使時間戳速率大於每幀的一個滴答。如果數據是在同一時刻采樣的,協議標准還允許多個分組具有相同的時間戳值。
RTP協議沒有規定RTP分組的長度和發送數據的速度,因而需要根據具體情況調整服務器端發送媒體數據的速度。對來自設備的實時數據可以采取等時間間隔訪問設備緩沖區,在有新數據輸入時發送數據的方式,時間戳的設置相對容易。對已經錄制好的本地硬盤上的媒體文件,以H.263格式的文件為例,由於文件本身不包含幀率信息,所以需要知道錄制時的幀率或者設置一個初始值,在發送數據的時候找出發送數據中的幀數目,根據幀率和預置值來計算時延,以適當的速度發送數據並設置時間戳信息。
RTCP的一個關鍵作用就是能讓接收方同步多個RTP流,例如:當音頻與視頻一起傳輸的時候,由於編碼的不同,RTP使用兩個流分別進行傳輸,這樣兩個流的時間戳以不同的速率運行,接收方必須同步兩個流,以保證聲音與影像的一致。為能進行流同步,RTCP要求發送方給每個傳送一個唯一的標識數據源的規范名(Canonical Name),盡管由一個數據源發出的不同的流具有不同的同步源標識(SSRC),但具有相同的規范名,這樣接收方就知道哪些流是有關聯的。而發送方報告報文所包含的信息可被接收方用於協調兩個流中的時間戳值。發送方報告中含有一個以網絡時間協議NTP(Network Time Protocol)格式表示的絕對時間值,接着RTCP報告中給出一個RTP時間戳值,產生該值的時鍾就是產生RTP分組中的TimeStamp字段的那個時鍾。由於發送方發出的所有流和發送方報告都使用同一個絕對時鍾,接收方就可以比較來自同一數據源的兩個流的絕對時間,從而確定如何將一個流中的時間戳值映射為另一個流中的時間戳值。
參考: