blob: fcafe5960ee883fa04c4d17164fd1ed89b43ea81 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
Erik Språng242e22b2015-05-11 10:17:43 +02002* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3*
4* Use of this source code is governed by a BSD-style license
5* that can be found in the LICENSE file in the root of the source
6* tree. An additional intellectual property rights grant can be found
7* in the file PATENTS. All contributing project authors may
8* be found in the AUTHORS file in the root of the source tree.
9*/
niklase@google.com470e71d2011-07-07 08:21:25 +000010
11#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_
12#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_
13
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000014#include <stddef.h> // size_t, ptrdiff_t
niklase@google.com470e71d2011-07-07 08:21:25 +000015
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000016#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
17#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h"
18#include "webrtc/typedefs.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000019
20namespace webrtc {
21namespace RTCPUtility {
asapersson@webrtc.org2dd31342014-10-29 12:42:30 +000022
23class NackStats {
24 public:
25 NackStats();
26 ~NackStats();
27
28 // Updates stats with requested sequence number.
29 // This function should be called for each NACK request to calculate the
30 // number of unique NACKed RTP packets.
31 void ReportRequest(uint16_t sequence_number);
32
33 // Gets the number of NACKed RTP packets.
34 uint32_t requests() const { return requests_; }
35
36 // Gets the number of unique NACKed RTP packets.
37 uint32_t unique_requests() const { return unique_requests_; }
38
39 private:
40 uint16_t max_sequence_number_;
41 uint32_t requests_;
42 uint32_t unique_requests_;
43};
44
Erik Språng242e22b2015-05-11 10:17:43 +020045uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000046
Erik Språng242e22b2015-05-11 10:17:43 +020047// CNAME
48struct RTCPCnameInformation {
49 char name[RTCP_CNAME_SIZE];
50};
51struct RTCPPacketRR {
52 uint32_t SenderSSRC;
53 uint8_t NumberOfReportBlocks;
54};
55struct RTCPPacketSR {
56 uint32_t SenderSSRC;
57 uint8_t NumberOfReportBlocks;
niklase@google.com470e71d2011-07-07 08:21:25 +000058
Erik Språng242e22b2015-05-11 10:17:43 +020059 // sender info
60 uint32_t NTPMostSignificant;
61 uint32_t NTPLeastSignificant;
62 uint32_t RTPTimestamp;
63 uint32_t SenderPacketCount;
64 uint32_t SenderOctetCount;
65};
66struct RTCPPacketReportBlockItem {
67 // report block
68 uint32_t SSRC;
69 uint8_t FractionLost;
70 uint32_t CumulativeNumOfPacketsLost;
71 uint32_t ExtendedHighestSequenceNumber;
72 uint32_t Jitter;
73 uint32_t LastSR;
74 uint32_t DelayLastSR;
75};
76struct RTCPPacketSDESCName {
77 // RFC3550
78 uint32_t SenderSSRC;
79 char CName[RTCP_CNAME_SIZE];
80};
niklase@google.com470e71d2011-07-07 08:21:25 +000081
Erik Språng242e22b2015-05-11 10:17:43 +020082struct RTCPPacketExtendedJitterReportItem {
83 // RFC 5450
84 uint32_t Jitter;
85};
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000086
Erik Språng242e22b2015-05-11 10:17:43 +020087struct RTCPPacketBYE {
88 uint32_t SenderSSRC;
89};
90struct RTCPPacketXR {
91 // RFC 3611
92 uint32_t OriginatorSSRC;
93};
94struct RTCPPacketXRReceiverReferenceTimeItem {
95 // RFC 3611 4.4
96 uint32_t NTPMostSignificant;
97 uint32_t NTPLeastSignificant;
98};
99struct RTCPPacketXRDLRRReportBlockItem {
100 // RFC 3611 4.5
101 uint32_t SSRC;
102 uint32_t LastRR;
103 uint32_t DelayLastRR;
104};
105struct RTCPPacketXRVOIPMetricItem {
106 // RFC 3611 4.7
107 uint32_t SSRC;
108 uint8_t lossRate;
109 uint8_t discardRate;
110 uint8_t burstDensity;
111 uint8_t gapDensity;
112 uint16_t burstDuration;
113 uint16_t gapDuration;
114 uint16_t roundTripDelay;
115 uint16_t endSystemDelay;
116 uint8_t signalLevel;
117 uint8_t noiseLevel;
118 uint8_t RERL;
119 uint8_t Gmin;
120 uint8_t Rfactor;
121 uint8_t extRfactor;
122 uint8_t MOSLQ;
123 uint8_t MOSCQ;
124 uint8_t RXconfig;
125 uint16_t JBnominal;
126 uint16_t JBmax;
127 uint16_t JBabsMax;
128};
niklase@google.com470e71d2011-07-07 08:21:25 +0000129
Erik Språng242e22b2015-05-11 10:17:43 +0200130struct RTCPPacketRTPFBNACK {
131 uint32_t SenderSSRC;
132 uint32_t MediaSSRC;
133};
134struct RTCPPacketRTPFBNACKItem {
135 // RFC4585
136 uint16_t PacketID;
137 uint16_t BitMask;
138};
niklase@google.com470e71d2011-07-07 08:21:25 +0000139
Erik Språng242e22b2015-05-11 10:17:43 +0200140struct RTCPPacketRTPFBTMMBR {
141 uint32_t SenderSSRC;
142 uint32_t MediaSSRC; // zero!
143};
144struct RTCPPacketRTPFBTMMBRItem {
145 // RFC5104
146 uint32_t SSRC;
147 uint32_t MaxTotalMediaBitRate; // In Kbit/s
148 uint32_t MeasuredOverhead;
149};
niklase@google.com470e71d2011-07-07 08:21:25 +0000150
Erik Språng242e22b2015-05-11 10:17:43 +0200151struct RTCPPacketRTPFBTMMBN {
152 uint32_t SenderSSRC;
153 uint32_t MediaSSRC; // zero!
154};
155struct RTCPPacketRTPFBTMMBNItem {
156 // RFC5104
157 uint32_t SSRC; // "Owner"
158 uint32_t MaxTotalMediaBitRate;
159 uint32_t MeasuredOverhead;
160};
niklase@google.com470e71d2011-07-07 08:21:25 +0000161
Erik Språng242e22b2015-05-11 10:17:43 +0200162struct RTCPPacketPSFBFIR {
163 uint32_t SenderSSRC;
164 uint32_t MediaSSRC; // zero!
165};
166struct RTCPPacketPSFBFIRItem {
167 // RFC5104
168 uint32_t SSRC;
169 uint8_t CommandSequenceNumber;
170};
niklase@google.com470e71d2011-07-07 08:21:25 +0000171
Erik Språng242e22b2015-05-11 10:17:43 +0200172struct RTCPPacketPSFBPLI {
173 // RFC4585
174 uint32_t SenderSSRC;
175 uint32_t MediaSSRC;
176};
niklase@google.com470e71d2011-07-07 08:21:25 +0000177
Erik Språng242e22b2015-05-11 10:17:43 +0200178struct RTCPPacketPSFBSLI {
179 // RFC4585
180 uint32_t SenderSSRC;
181 uint32_t MediaSSRC;
182};
183struct RTCPPacketPSFBSLIItem {
184 // RFC4585
185 uint16_t FirstMB;
186 uint16_t NumberOfMB;
187 uint8_t PictureId;
188};
189struct RTCPPacketPSFBRPSI {
190 // RFC4585
191 uint32_t SenderSSRC;
192 uint32_t MediaSSRC;
193 uint8_t PayloadType;
194 uint16_t NumberOfValidBits;
195 uint8_t NativeBitString[RTCP_RPSI_DATA_SIZE];
196};
197struct RTCPPacketPSFBAPP {
198 uint32_t SenderSSRC;
199 uint32_t MediaSSRC;
200};
201struct RTCPPacketPSFBREMBItem {
202 uint32_t BitRate;
203 uint8_t NumberOfSSRCs;
204 uint32_t SSRCs[MAX_NUMBER_OF_REMB_FEEDBACK_SSRCS];
205};
206// generic name APP
207struct RTCPPacketAPP {
208 uint8_t SubType;
209 uint32_t Name;
210 uint8_t Data[kRtcpAppCode_DATA_SIZE];
211 uint16_t Size;
212};
niklase@google.com470e71d2011-07-07 08:21:25 +0000213
Erik Språng242e22b2015-05-11 10:17:43 +0200214union RTCPPacket {
215 RTCPPacketRR RR;
216 RTCPPacketSR SR;
217 RTCPPacketReportBlockItem ReportBlockItem;
niklase@google.com470e71d2011-07-07 08:21:25 +0000218
Erik Språng242e22b2015-05-11 10:17:43 +0200219 RTCPPacketSDESCName CName;
220 RTCPPacketBYE BYE;
niklase@google.com470e71d2011-07-07 08:21:25 +0000221
Erik Språng242e22b2015-05-11 10:17:43 +0200222 RTCPPacketExtendedJitterReportItem ExtendedJitterReportItem;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000223
Erik Språng242e22b2015-05-11 10:17:43 +0200224 RTCPPacketRTPFBNACK NACK;
225 RTCPPacketRTPFBNACKItem NACKItem;
niklase@google.com470e71d2011-07-07 08:21:25 +0000226
Erik Språng242e22b2015-05-11 10:17:43 +0200227 RTCPPacketPSFBPLI PLI;
228 RTCPPacketPSFBSLI SLI;
229 RTCPPacketPSFBSLIItem SLIItem;
230 RTCPPacketPSFBRPSI RPSI;
231 RTCPPacketPSFBAPP PSFBAPP;
232 RTCPPacketPSFBREMBItem REMBItem;
niklase@google.com470e71d2011-07-07 08:21:25 +0000233
Erik Språng242e22b2015-05-11 10:17:43 +0200234 RTCPPacketRTPFBTMMBR TMMBR;
235 RTCPPacketRTPFBTMMBRItem TMMBRItem;
236 RTCPPacketRTPFBTMMBN TMMBN;
237 RTCPPacketRTPFBTMMBNItem TMMBNItem;
238 RTCPPacketPSFBFIR FIR;
239 RTCPPacketPSFBFIRItem FIRItem;
niklase@google.com470e71d2011-07-07 08:21:25 +0000240
Erik Språng242e22b2015-05-11 10:17:43 +0200241 RTCPPacketXR XR;
242 RTCPPacketXRReceiverReferenceTimeItem XRReceiverReferenceTimeItem;
243 RTCPPacketXRDLRRReportBlockItem XRDLRRReportBlockItem;
244 RTCPPacketXRVOIPMetricItem XRVOIPMetricItem;
niklase@google.com470e71d2011-07-07 08:21:25 +0000245
Erik Språng242e22b2015-05-11 10:17:43 +0200246 RTCPPacketAPP APP;
247};
niklase@google.com470e71d2011-07-07 08:21:25 +0000248
Erik Språng242e22b2015-05-11 10:17:43 +0200249enum class RTCPPacketTypes {
250 kInvalid,
niklase@google.com470e71d2011-07-07 08:21:25 +0000251
Erik Språng242e22b2015-05-11 10:17:43 +0200252 // RFC3550
253 kRr,
254 kSr,
255 kReportBlockItem,
niklase@google.com470e71d2011-07-07 08:21:25 +0000256
Erik Språng242e22b2015-05-11 10:17:43 +0200257 kSdes,
258 kSdesChunk,
259 kBye,
niklase@google.com470e71d2011-07-07 08:21:25 +0000260
Erik Språng242e22b2015-05-11 10:17:43 +0200261 // RFC5450
262 kExtendedIj,
263 kExtendedIjItem,
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000264
Erik Språng242e22b2015-05-11 10:17:43 +0200265 // RFC4585
266 kRtpfbNack,
267 kRtpfbNackItem,
niklase@google.com470e71d2011-07-07 08:21:25 +0000268
Erik Språng242e22b2015-05-11 10:17:43 +0200269 kPsfbPli,
270 kPsfbRpsi,
271 kPsfbSli,
272 kPsfbSliItem,
273 kPsfbApp,
274 kPsfbRemb,
275 kPsfbRembItem,
niklase@google.com470e71d2011-07-07 08:21:25 +0000276
Erik Språng242e22b2015-05-11 10:17:43 +0200277 // RFC5104
278 kRtpfbTmmbr,
279 kRtpfbTmmbrItem,
280 kRtpfbTmmbn,
281 kRtpfbTmmbnItem,
282 kPsfbFir,
283 kPsfbFirItem,
niklase@google.com470e71d2011-07-07 08:21:25 +0000284
Erik Språng242e22b2015-05-11 10:17:43 +0200285 // draft-perkins-avt-rapid-rtp-sync
286 kRtpfbSrReq,
niklase@google.com470e71d2011-07-07 08:21:25 +0000287
Erik Språng242e22b2015-05-11 10:17:43 +0200288 // RFC 3611
289 kXrHeader,
290 kXrReceiverReferenceTime,
291 kXrDlrrReportBlock,
292 kXrDlrrReportBlockItem,
293 kXrVoipMetric,
niklase@google.com470e71d2011-07-07 08:21:25 +0000294
Erik Språng242e22b2015-05-11 10:17:43 +0200295 kApp,
296 kAppItem,
297};
niklase@google.com470e71d2011-07-07 08:21:25 +0000298
Erik Språng242e22b2015-05-11 10:17:43 +0200299struct RTCPRawPacket {
300 const uint8_t* _ptrPacketBegin;
301 const uint8_t* _ptrPacketEnd;
302};
niklase@google.com470e71d2011-07-07 08:21:25 +0000303
Erik Språng242e22b2015-05-11 10:17:43 +0200304struct RTCPModRawPacket {
305 uint8_t* _ptrPacketBegin;
306 uint8_t* _ptrPacketEnd;
307};
niklase@google.com470e71d2011-07-07 08:21:25 +0000308
Erik Språng242e22b2015-05-11 10:17:43 +0200309struct RTCPCommonHeader {
310 uint8_t V; // Version
311 bool P; // Padding
312 uint8_t IC; // Item count/subtype
313 uint8_t PT; // Packet Type
314 uint16_t LengthInOctets;
315};
niklase@google.com470e71d2011-07-07 08:21:25 +0000316
Erik Språng242e22b2015-05-11 10:17:43 +0200317enum RTCPPT : uint8_t {
318 PT_IJ = 195,
319 PT_SR = 200,
320 PT_RR = 201,
321 PT_SDES = 202,
322 PT_BYE = 203,
323 PT_APP = 204,
324 PT_RTPFB = 205,
325 PT_PSFB = 206,
326 PT_XR = 207
327};
niklase@google.com470e71d2011-07-07 08:21:25 +0000328
Erik Språng242e22b2015-05-11 10:17:43 +0200329// Extended report blocks, RFC 3611.
330enum RtcpXrBlockType : uint8_t {
331 kBtReceiverReferenceTime = 4,
332 kBtDlrr = 5,
333 kBtVoipMetric = 7
334};
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000335
Erik Språng242e22b2015-05-11 10:17:43 +0200336bool RTCPParseCommonHeader(const uint8_t* ptrDataBegin,
337 const uint8_t* ptrDataEnd,
338 RTCPCommonHeader& parsedHeader);
niklase@google.com470e71d2011-07-07 08:21:25 +0000339
Erik Språng242e22b2015-05-11 10:17:43 +0200340class RTCPParserV2 {
341 public:
342 RTCPParserV2(
343 const uint8_t* rtcpData,
344 size_t rtcpDataLength,
345 bool rtcpReducedSizeEnable); // Set to true, to allow non-compound RTCP!
346 ~RTCPParserV2();
niklase@google.com470e71d2011-07-07 08:21:25 +0000347
Erik Språng242e22b2015-05-11 10:17:43 +0200348 RTCPPacketTypes PacketType() const;
349 const RTCPPacket& Packet() const;
350 const RTCPRawPacket& RawPacket() const;
351 ptrdiff_t LengthLeft() const;
niklase@google.com470e71d2011-07-07 08:21:25 +0000352
Erik Språng242e22b2015-05-11 10:17:43 +0200353 bool IsValid() const;
niklase@google.com470e71d2011-07-07 08:21:25 +0000354
Erik Språng242e22b2015-05-11 10:17:43 +0200355 RTCPPacketTypes Begin();
356 RTCPPacketTypes Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000357
Erik Språng242e22b2015-05-11 10:17:43 +0200358 private:
359 enum class ParseState {
360 State_TopLevel, // Top level packet
361 State_ReportBlockItem, // SR/RR report block
362 State_SDESChunk, // SDES chunk
363 State_BYEItem, // BYE item
364 State_ExtendedJitterItem, // Extended jitter report item
365 State_RTPFB_NACKItem, // NACK FCI item
366 State_RTPFB_TMMBRItem, // TMMBR FCI item
367 State_RTPFB_TMMBNItem, // TMMBN FCI item
368 State_PSFB_SLIItem, // SLI FCI item
369 State_PSFB_RPSIItem, // RPSI FCI item
370 State_PSFB_FIRItem, // FIR FCI item
371 State_PSFB_AppItem, // Application specific FCI item
372 State_PSFB_REMBItem, // Application specific REMB item
373 State_XRItem,
374 State_XR_DLLRItem,
375 State_AppItem
376 };
niklase@google.com470e71d2011-07-07 08:21:25 +0000377
Erik Språng242e22b2015-05-11 10:17:43 +0200378 private:
379 void IterateTopLevel();
380 void IterateReportBlockItem();
381 void IterateSDESChunk();
382 void IterateBYEItem();
383 void IterateExtendedJitterItem();
384 void IterateNACKItem();
385 void IterateTMMBRItem();
386 void IterateTMMBNItem();
387 void IterateSLIItem();
388 void IterateRPSIItem();
389 void IterateFIRItem();
390 void IteratePsfbAppItem();
391 void IteratePsfbREMBItem();
392 void IterateAppItem();
393 void IterateXrItem();
394 void IterateXrDlrrItem();
niklase@google.com470e71d2011-07-07 08:21:25 +0000395
Erik Språng242e22b2015-05-11 10:17:43 +0200396 void Validate();
397 void EndCurrentBlock();
niklase@google.com470e71d2011-07-07 08:21:25 +0000398
Erik Språng242e22b2015-05-11 10:17:43 +0200399 bool ParseRR();
400 bool ParseSR();
401 bool ParseReportBlockItem();
niklase@google.com470e71d2011-07-07 08:21:25 +0000402
Erik Språng242e22b2015-05-11 10:17:43 +0200403 bool ParseSDES();
404 bool ParseSDESChunk();
405 bool ParseSDESItem();
niklase@google.com470e71d2011-07-07 08:21:25 +0000406
Erik Språng242e22b2015-05-11 10:17:43 +0200407 bool ParseBYE();
408 bool ParseBYEItem();
niklase@google.com470e71d2011-07-07 08:21:25 +0000409
Erik Språng242e22b2015-05-11 10:17:43 +0200410 bool ParseIJ();
411 bool ParseIJItem();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000412
Erik Språng242e22b2015-05-11 10:17:43 +0200413 bool ParseXr();
414 bool ParseXrItem();
415 bool ParseXrReceiverReferenceTimeItem(int block_length_4bytes);
416 bool ParseXrDlrr(int block_length_4bytes);
417 bool ParseXrDlrrItem();
418 bool ParseXrVoipMetricItem(int block_length_4bytes);
419 bool ParseXrUnsupportedBlockType(int block_length_4bytes);
niklase@google.com470e71d2011-07-07 08:21:25 +0000420
Erik Språng242e22b2015-05-11 10:17:43 +0200421 bool ParseFBCommon(const RTCPCommonHeader& header);
422 bool ParseNACKItem();
423 bool ParseTMMBRItem();
424 bool ParseTMMBNItem();
425 bool ParseSLIItem();
426 bool ParseRPSIItem();
427 bool ParseFIRItem();
428 bool ParsePsfbAppItem();
429 bool ParsePsfbREMBItem();
niklase@google.com470e71d2011-07-07 08:21:25 +0000430
Erik Språng242e22b2015-05-11 10:17:43 +0200431 bool ParseAPP(const RTCPCommonHeader& header);
432 bool ParseAPPItem();
niklase@google.com470e71d2011-07-07 08:21:25 +0000433
Erik Språng242e22b2015-05-11 10:17:43 +0200434 private:
435 const uint8_t* const _ptrRTCPDataBegin;
436 const bool _RTCPReducedSizeEnable;
437 const uint8_t* const _ptrRTCPDataEnd;
niklase@google.com470e71d2011-07-07 08:21:25 +0000438
Erik Språng242e22b2015-05-11 10:17:43 +0200439 bool _validPacket;
440 const uint8_t* _ptrRTCPData;
441 const uint8_t* _ptrRTCPBlockEnd;
niklase@google.com470e71d2011-07-07 08:21:25 +0000442
Erik Språng242e22b2015-05-11 10:17:43 +0200443 ParseState _state;
444 uint8_t _numberOfBlocks;
niklase@google.com470e71d2011-07-07 08:21:25 +0000445
Erik Språng242e22b2015-05-11 10:17:43 +0200446 RTCPPacketTypes _packetType;
447 RTCPPacket _packet;
448};
niklase@google.com470e71d2011-07-07 08:21:25 +0000449
Erik Språng242e22b2015-05-11 10:17:43 +0200450class RTCPPacketIterator {
451 public:
452 RTCPPacketIterator(uint8_t* rtcpData, size_t rtcpDataLength);
453 ~RTCPPacketIterator();
niklase@google.com470e71d2011-07-07 08:21:25 +0000454
Erik Språng242e22b2015-05-11 10:17:43 +0200455 const RTCPCommonHeader* Begin();
456 const RTCPCommonHeader* Iterate();
457 const RTCPCommonHeader* Current();
niklase@google.com470e71d2011-07-07 08:21:25 +0000458
Erik Språng242e22b2015-05-11 10:17:43 +0200459 private:
460 uint8_t* const _ptrBegin;
461 uint8_t* const _ptrEnd;
niklase@google.com470e71d2011-07-07 08:21:25 +0000462
Erik Språng242e22b2015-05-11 10:17:43 +0200463 uint8_t* _ptrBlock;
niklase@google.com470e71d2011-07-07 08:21:25 +0000464
Erik Språng242e22b2015-05-11 10:17:43 +0200465 RTCPCommonHeader _header;
466};
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000467} // RTCPUtility
468} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +0000469#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_