WEBRTC 接收H264 RTP資料流小結
WEBRTC 接收H264 RTP資料流小結
這篇文章是對webrtc 中,接收H264 RTP包的一個總結,主要分為兩個部分:
第一部分,介紹H264打包成RTP包的規範,以及WEBRTC中目前正在使用的幾種格式。
第二部分,介紹WEBRTC的資料流,從接收RTP包,到拼裝成H264 Frame,最終送入Decoder,獲取YUV資料。
第一部分:RTP Payload Format for H.264 Video閱讀筆記
參考連結:
RTP Payload Format
具體RTP 的協議格式,可以參考。
1.RTP Header
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 | | .... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 1. RTP header according to RFC 3550
2.Payload Structures
定義了三種不同的Playload結構型別
-
Single NAL Unit Packet
在一個RTP Playload中,只包含一個Nal Unit 。
-
Single NAL Unit Packet
在一個RTP Playload中,聚合了多個Nal Unit。大致包含以下幾種:
STAP-A:
STAP-B
MTAP-16
MTAP-24
-
Fragmentation Unit
把一個Nal Unit 進行拆分,打包到多個RTP 包中。
FU-A
FU-B
Table 1. Summary of NAL unit types and the corresponding packet types NAL Unit Packet Packet Type Name Section Type Type ------------------------------------------------------------- 0 reserved - 1-23 NAL unit Single NAL unit packet 5.6 24 STAP-A Single-time aggregation packet 5.7.1 25 STAP-B Single-time aggregation packet 5.7.1 26 MTAP16 Multi-time aggregation packet 5.7.2 27 MTAP24 Multi-time aggregation packet 5.7.2 28 FU-A Fragmentation unit 5.8 29 FU-B Fragmentation unit 5.8 30-31 reserved -
2.1 NAL Unit Header
--
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
F:0表示payload 內容沒有錯誤,1表示payload中的內容可能有錯誤內容或語法錯誤。
NRI:00表示沒有參考幀。
Type:1-23
2.1.1 Packetization Modes
Single Nal unit mode:
Non-interleaved mode:
Interleaved mode:
--
Table 3. Summary of allowed NAL unit types for each packetization mode (yes = allowed, no = disallowed, ig = ignore) Payload Packet Single NAL Non-Interleaved Interleaved Type Type Unit Mode Mode Mode ------------------------------------------------------------- 0 reserved ig ig ig 1-23 NAL unit yes yes no 24 STAP-A no yes no 25 STAP-B no no yes 26 MTAP16 no no yes 27 MTAP24 no no yes 28 FU-A no yes yes 29 FU-B no no yes 30-31 reserved ig ig ig
2.2 Single NAL Unit Packet
在一個rtp'包中,只包含有一個完整的Nal Unit(影片幀)。
例: 如有一個 H.264 的 NALU 是這樣的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]
這是一個序列引數集 NAL 單元. [00 00 00 01] 是四個位元組的開始碼, 67 是 NALU 頭, 42 開始的資料是 NALU 內容.
封裝成 RTP 包將如下:
[ F|NRI| Type ] [ 67 42 A0 1E 23 56 0E 2F ]
a single NAL unit :[ 67 42 A0 1E 23 56 0E 2F ], 即只要去掉 4 個位元組的開始碼就可以了.
--
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|NRI| Type | |
+-+-+-+-+-+-+-+-+ |
| |
| Bytes 2..n of a single NAL unit |
| |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :...OPTIONAL RTP padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 2. RTP payload format for single NAL unit packet
2.3 Aggregation Packets
在一個rtp包中,會有多個Nul Unit(一個rtp包帶多個影片幀)。這種情況會在影片幀比較小的時候採用。
Single-time aggregation packet (STAP):
STAP-A: without DON
例:
如有一個 H.264 的 NALU 是這樣的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ] [00 00 00 01 68 42 B0 12 58 6A D4 FF ... ]
封裝成 RTP 包將如下:
[ STAP-A NAL HDR ] [78 (STAP-A頭,佔用1個位元組)] [第一個NALU長度 (佔用兩個位元組)] [ 67 42 A0 1E 23 56 0E 2F ] [第二個NALU長度 (佔用兩個位元組)] [68 42 B0 12 58 6A D4 FF ... ]
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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | RTP Header | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |STAP-A NAL HDR | NALU 1 Size | NALU 1 HDR | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 1 Data | : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | NALU 2 Size | NALU 2 HDR | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 2 Data | : : | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | :...OPTIONAL RTP padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 7. An example of an RTP packet including an STAP-A containing two single-time aggregation units <!----> * STAP-B: including DON <!----> 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | RTP Header | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |STAP-B NAL HDR | DON | NALU 1 Size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 1 Size | NALU 1 HDR | NALU 1 Data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | NALU 2 Size | NALU 2 HDR | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 2 Data | : : | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | :...OPTIONAL RTP padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 8. An example of an RTP packet including an STAP-B containing two single-time aggregation units<!---->
-
Multi-time aggregation packet (MTAP):
這兩種MAPS的區別在於 timestamp offset 的長度不同。
MTAP16:
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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | RTP Header | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |MTAP16 NAL HDR | decoding order number base | NALU 1 Size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 1 Size | NALU 1 DOND | NALU 1 TS offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 1 HDR | NALU 1 DATA | +-+-+-+-+-+-+-+-+ + : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | NALU 2 SIZE | NALU 2 DOND | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 2 TS offset | NALU 2 HDR | NALU 2 DATA | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | : : | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | :...OPTIONAL RTP padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 12. An RTP packet including a multi-time aggregation packet of type MTAP16 containing two multi-time aggregation units * MTAP24: 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | RTP Header | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |MTAP24 NAL HDR | decoding order number base | NALU 1 Size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 1 Size | NALU 1 DOND | NALU 1 TS offs | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |NALU 1 TS offs | NALU 1 HDR | NALU 1 DATA | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | NALU 2 SIZE | NALU 2 DOND | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 2 TS offset | NALU 2 HDR | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NALU 2 DATA | : : | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | :...OPTIONAL RTP padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 13. An RTP packet including a multi-time aggregation packet of type MTAP24 containing two multi-time aggregation units
--
2.4 Fragmentation Units
一個Nal Unit會被分割成,透過多個rtp包進行傳送,這樣便於傳輸和以後做fec處理。
FU-A:
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+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| FU indicator | FU header | |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | FU payload | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| :...OPTIONAL RTP padding |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 14. RTP payload format for FU-A
FU-B:
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+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| FU indicator | FU header | DON |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| | | | FU payload | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| :...OPTIONAL RTP padding |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 15. RTP payload format for FU-B
The FU indicator octet has the following format:
+---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +---------------+
The FU header has the following format:
S:1表示第一包
E:1表示是最後一個包
R:1表示中間
Type:型別
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|S|E|R| Type |
+---------------+
目前webrtc中使用的打包程式碼如下:
void RtpPacketizerH264::GeneratePackets() { LOG(LS_VERBOSE) << "RtpPacketizerH264::GeneratePackets packetization_mode " << (int)packetization_mode_ << " max_payload_len " << max_payload_len_ ; for (size_t i = 0; i < input_fragments_.size();) { switch (packetization_mode_) { case H264PacketizationMode::SingleNalUnit: PacketizeSingleNalu(i); ++i; break; case H264PacketizationMode::NonInterleaved: size_t fragment_len = input_fragments_[i].length; if (i + 1 == input_fragments_.size()) { // Pretend that last fragment is larger instead of making last packet // smaller. fragment_len += last_packet_reduction_len_; } if (fragment_len > max_payload_len_) { PacketizeFuA(i); ++i; } else { i = PacketizeStapA(i); } break; } } }
第二部分:接收端的資料流處理
先看一下整理的類圖
video_receive_stream.jpg
處理流程如下
首先在cricket::WebRtcVideoChannel中的OnPacketReceived函式中,我們會收到RTP包。這個是透過ICE 建立的UDP連結傳來的資料。
RTP資料包一直走到webrtc::RtpVideoStreamReceiver的OnPacketReceived函式中,呼叫webrtc::RtpReceiverImpl的IncomingRtpPacket進行rtp 包解析。
解析完之後的資料,會透過OnReceivedPayloadData回撥上來,webrtc::RtpVideoStreamReceiver會將接收到的rtp包資料,打包成VCMPacket的形式,插入到PacketBuffer中。
PacketBuffer的主要工作就是收集rtp包,並且判斷這些rtp包能否組裝成一個完整的H264的Frame。主要的實現邏輯就是每次在InsertPacket的最後,都呼叫FindFrames函式去查是否有合適的幀組成。
如果發現一個完整的幀,PacketBuffer會透過OnReceivedFrame把frame資料回撥給webrtc::RtpVideoStreamReceiver。然後再透過video_coding::RtpFrameReferenceFinder的ManageFrame來查詢,是否有合適的幀可以送給Decoder解碼。這裡的合適主要分一下幾點:
判斷幀是否連續
判斷參考幀是有沒有丟失
是否是IFRAME
找到decodeble的幀後,video_coding::RtpFrameReferenceFinder透過OnCompleteFrame把frame交給internal::VideoReceiveStream,它會把frame插入到FrameBuffer中。
這裡的FrameBuffer,就是以前版本的jitter buffer。在新的webrtc中已經更名。
internal::VideoReceiveStream內部有一個decode 執行緒,這個執行緒會定期問是否有合適的Frame可以送給decode解碼。如果有,則把它送到vcm::VideoReceiver去解碼。
vcm::VideoReceiver中持有decode的外部類,VCMGenericDecoder。我們把資料送給他,如果有decode解碼完的YUV資料,他會把資料透過FrameToRender 回撥webrtc::VideoStreamDecoder。
最終,webrtc::VideoStreamDecoder把YUV資料透過OnFrame回撥給internal::VideoReceiveStream。在這裡,webrtc就會把YUV資料傳給之前註冊的Render。
總結
整體的資料流程在上面的已經做了一個簡單的描述,其中比較主要的是還標黃色的幾個類。由於時間有限,還是會有很多具體的細節沒有擴充套件,比如packet buffer的拼frame的邏輯,FrameBuffer找decodable frame的邏輯。這些可以在下次的文章中再和大家分享。
作者:木韋雜貨店
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/151/viewspace-2821343/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 將H264碼流打包成RTP包
- 視訊會議中或者錄播中使用RTP協議接收h264視訊協議
- servlet接收xml資料流[java]ServletXMLJava
- WebRTC 資料Web
- 流媒體傳輸協議之 RTP (上篇)協議
- 流媒體傳輸協議之 RTP(下篇)協議
- RTSP H264/HEVC 流 Wasm 播放ASM
- RTP協議的報文結構協議
- ffmpeg提取H264影片資料
- curl資料小結
- 5┃音視訊直播系統之 WebRTC 中的協議UDP、TCP、RTP、RTCP詳解Web協議UDPTCP
- 前端三大框架:資料繫結與資料流前端框架
- 如何在 Janus 中獲取 WebRTC 的流Web
- WebRTC學習總結Web
- MySQL常用資料庫小結MySql資料庫
- oracle資料塊格式小結Oracle
- mysql資料型別小結MySql資料型別
- 小結java與資料庫Java資料庫
- python使用flask接收前端資料,處理後返回結果PythonFlask前端
- 如何使用 jq 接收 blob 資料
- Qml接收QList<QVariantMap> 資料
- 大資料相關資料論文小結大資料
- iOS 儲存攝像頭H264視訊流iOS
- 當微信小程式遇上TensorFlow:接收base64編碼影象資料微信小程式
- 1小時學會:最簡單的iOS直播推流(八)h264 aac 軟編碼iOS
- 1小時學會:最簡單的iOS直播推流(七)h264/aac 硬編碼iOS
- Google的uProxy使用了WebRTC資料通道GoWeb
- FHQ Treap小結(神級資料結構!)資料結構
- 資料庫連結(database link)小結資料庫Database
- web技術分享| WebRTC記錄音影片流Web
- windows編譯ZLMediaKit流媒體服務webrtcWindows編譯Web
- 資料庫注入技術小結資料庫
- 資料庫期末複習小結資料庫
- C基本資料型別小結資料型別
- 微信小程式資料資料繫結顯示NaN微信小程式NaN
- 1小時學會:最簡單的iOS直播推流(六)h264、aac、flv介紹iOS
- 伺服系統電流取樣小結
- js對flv提取h264、aac音視訊流JS