1/*
2*  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*/
10
11#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_
12#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_
13
14#include <stddef.h> // size_t, ptrdiff_t
15
16#include "webrtc/base/scoped_ptr.h"
17#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
18#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h"
19#include "webrtc/typedefs.h"
20
21namespace webrtc {
22namespace rtcp {
23class RtcpPacket;
24}
25namespace RTCPUtility {
26
27class NackStats {
28 public:
29  NackStats();
30  ~NackStats();
31
32  // Updates stats with requested sequence number.
33  // This function should be called for each NACK request to calculate the
34  // number of unique NACKed RTP packets.
35  void ReportRequest(uint16_t sequence_number);
36
37  // Gets the number of NACKed RTP packets.
38  uint32_t requests() const { return requests_; }
39
40  // Gets the number of unique NACKed RTP packets.
41  uint32_t unique_requests() const { return unique_requests_; }
42
43 private:
44  uint16_t max_sequence_number_;
45  uint32_t requests_;
46  uint32_t unique_requests_;
47};
48
49uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac);
50
51// CNAME
52struct RTCPCnameInformation {
53  char name[RTCP_CNAME_SIZE];
54};
55struct RTCPPacketRR {
56  uint32_t SenderSSRC;
57  uint8_t NumberOfReportBlocks;
58};
59struct RTCPPacketSR {
60  uint32_t SenderSSRC;
61  uint8_t NumberOfReportBlocks;
62
63  // sender info
64  uint32_t NTPMostSignificant;
65  uint32_t NTPLeastSignificant;
66  uint32_t RTPTimestamp;
67  uint32_t SenderPacketCount;
68  uint32_t SenderOctetCount;
69};
70struct RTCPPacketReportBlockItem {
71  // report block
72  uint32_t SSRC;
73  uint8_t FractionLost;
74  uint32_t CumulativeNumOfPacketsLost;
75  uint32_t ExtendedHighestSequenceNumber;
76  uint32_t Jitter;
77  uint32_t LastSR;
78  uint32_t DelayLastSR;
79};
80struct RTCPPacketSDESCName {
81  // RFC3550
82  uint32_t SenderSSRC;
83  char CName[RTCP_CNAME_SIZE];
84};
85
86struct RTCPPacketExtendedJitterReportItem {
87  // RFC 5450
88  uint32_t Jitter;
89};
90
91struct RTCPPacketBYE {
92  uint32_t SenderSSRC;
93};
94struct RTCPPacketXR {
95  // RFC 3611
96  uint32_t OriginatorSSRC;
97};
98struct RTCPPacketXRReceiverReferenceTimeItem {
99  // RFC 3611 4.4
100  uint32_t NTPMostSignificant;
101  uint32_t NTPLeastSignificant;
102};
103struct RTCPPacketXRDLRRReportBlockItem {
104  // RFC 3611 4.5
105  uint32_t SSRC;
106  uint32_t LastRR;
107  uint32_t DelayLastRR;
108};
109struct RTCPPacketXRVOIPMetricItem {
110  // RFC 3611 4.7
111  uint32_t SSRC;
112  uint8_t lossRate;
113  uint8_t discardRate;
114  uint8_t burstDensity;
115  uint8_t gapDensity;
116  uint16_t burstDuration;
117  uint16_t gapDuration;
118  uint16_t roundTripDelay;
119  uint16_t endSystemDelay;
120  uint8_t signalLevel;
121  uint8_t noiseLevel;
122  uint8_t RERL;
123  uint8_t Gmin;
124  uint8_t Rfactor;
125  uint8_t extRfactor;
126  uint8_t MOSLQ;
127  uint8_t MOSCQ;
128  uint8_t RXconfig;
129  uint16_t JBnominal;
130  uint16_t JBmax;
131  uint16_t JBabsMax;
132};
133
134struct RTCPPacketRTPFBNACK {
135  uint32_t SenderSSRC;
136  uint32_t MediaSSRC;
137};
138struct RTCPPacketRTPFBNACKItem {
139  // RFC4585
140  uint16_t PacketID;
141  uint16_t BitMask;
142};
143
144struct RTCPPacketRTPFBTMMBR {
145  uint32_t SenderSSRC;
146  uint32_t MediaSSRC;  // zero!
147};
148struct RTCPPacketRTPFBTMMBRItem {
149  // RFC5104
150  uint32_t SSRC;
151  uint32_t MaxTotalMediaBitRate;  // In Kbit/s
152  uint32_t MeasuredOverhead;
153};
154
155struct RTCPPacketRTPFBTMMBN {
156  uint32_t SenderSSRC;
157  uint32_t MediaSSRC;  // zero!
158};
159struct RTCPPacketRTPFBTMMBNItem {
160  // RFC5104
161  uint32_t SSRC;  // "Owner"
162  uint32_t MaxTotalMediaBitRate;
163  uint32_t MeasuredOverhead;
164};
165
166struct RTCPPacketPSFBFIR {
167  uint32_t SenderSSRC;
168  uint32_t MediaSSRC;  // zero!
169};
170struct RTCPPacketPSFBFIRItem {
171  // RFC5104
172  uint32_t SSRC;
173  uint8_t CommandSequenceNumber;
174};
175
176struct RTCPPacketPSFBPLI {
177  // RFC4585
178  uint32_t SenderSSRC;
179  uint32_t MediaSSRC;
180};
181
182struct RTCPPacketPSFBSLI {
183  // RFC4585
184  uint32_t SenderSSRC;
185  uint32_t MediaSSRC;
186};
187struct RTCPPacketPSFBSLIItem {
188  // RFC4585
189  uint16_t FirstMB;
190  uint16_t NumberOfMB;
191  uint8_t PictureId;
192};
193struct RTCPPacketPSFBRPSI {
194  // RFC4585
195  uint32_t SenderSSRC;
196  uint32_t MediaSSRC;
197  uint8_t PayloadType;
198  uint16_t NumberOfValidBits;
199  uint8_t NativeBitString[RTCP_RPSI_DATA_SIZE];
200};
201struct RTCPPacketPSFBAPP {
202  uint32_t SenderSSRC;
203  uint32_t MediaSSRC;
204};
205struct RTCPPacketPSFBREMBItem {
206  uint32_t BitRate;
207  uint8_t NumberOfSSRCs;
208  uint32_t SSRCs[MAX_NUMBER_OF_REMB_FEEDBACK_SSRCS];
209};
210// generic name APP
211struct RTCPPacketAPP {
212  uint8_t SubType;
213  uint32_t Name;
214  uint8_t Data[kRtcpAppCode_DATA_SIZE];
215  uint16_t Size;
216};
217
218union RTCPPacket {
219  RTCPPacketRR RR;
220  RTCPPacketSR SR;
221  RTCPPacketReportBlockItem ReportBlockItem;
222
223  RTCPPacketSDESCName CName;
224  RTCPPacketBYE BYE;
225
226  RTCPPacketExtendedJitterReportItem ExtendedJitterReportItem;
227
228  RTCPPacketRTPFBNACK NACK;
229  RTCPPacketRTPFBNACKItem NACKItem;
230
231  RTCPPacketPSFBPLI PLI;
232  RTCPPacketPSFBSLI SLI;
233  RTCPPacketPSFBSLIItem SLIItem;
234  RTCPPacketPSFBRPSI RPSI;
235  RTCPPacketPSFBAPP PSFBAPP;
236  RTCPPacketPSFBREMBItem REMBItem;
237
238  RTCPPacketRTPFBTMMBR TMMBR;
239  RTCPPacketRTPFBTMMBRItem TMMBRItem;
240  RTCPPacketRTPFBTMMBN TMMBN;
241  RTCPPacketRTPFBTMMBNItem TMMBNItem;
242  RTCPPacketPSFBFIR FIR;
243  RTCPPacketPSFBFIRItem FIRItem;
244
245  RTCPPacketXR XR;
246  RTCPPacketXRReceiverReferenceTimeItem XRReceiverReferenceTimeItem;
247  RTCPPacketXRDLRRReportBlockItem XRDLRRReportBlockItem;
248  RTCPPacketXRVOIPMetricItem XRVOIPMetricItem;
249
250  RTCPPacketAPP APP;
251};
252
253enum class RTCPPacketTypes {
254  kInvalid,
255
256  // RFC3550
257  kRr,
258  kSr,
259  kReportBlockItem,
260
261  kSdes,
262  kSdesChunk,
263  kBye,
264
265  // RFC5450
266  kExtendedIj,
267  kExtendedIjItem,
268
269  // RFC4585
270  kRtpfbNack,
271  kRtpfbNackItem,
272
273  kPsfbPli,
274  kPsfbRpsi,
275  kPsfbSli,
276  kPsfbSliItem,
277  kPsfbApp,
278  kPsfbRemb,
279  kPsfbRembItem,
280
281  // RFC5104
282  kRtpfbTmmbr,
283  kRtpfbTmmbrItem,
284  kRtpfbTmmbn,
285  kRtpfbTmmbnItem,
286  kPsfbFir,
287  kPsfbFirItem,
288
289  // draft-perkins-avt-rapid-rtp-sync
290  kRtpfbSrReq,
291
292  // RFC 3611
293  kXrHeader,
294  kXrReceiverReferenceTime,
295  kXrDlrrReportBlock,
296  kXrDlrrReportBlockItem,
297  kXrVoipMetric,
298
299  kApp,
300  kAppItem,
301
302  // draft-holmer-rmcat-transport-wide-cc-extensions
303  kTransportFeedback,
304};
305
306struct RTCPRawPacket {
307  const uint8_t* _ptrPacketBegin;
308  const uint8_t* _ptrPacketEnd;
309};
310
311struct RTCPModRawPacket {
312  uint8_t* _ptrPacketBegin;
313  uint8_t* _ptrPacketEnd;
314};
315
316struct RtcpCommonHeader {
317  static const uint8_t kHeaderSizeBytes = 4;
318  RtcpCommonHeader()
319      : version(2),
320        count_or_format(0),
321        packet_type(0),
322        payload_size_bytes(0),
323        padding_bytes(0) {}
324
325  uint32_t BlockSize() const {
326    return kHeaderSizeBytes + payload_size_bytes + padding_bytes;
327  }
328
329  uint8_t version;
330  uint8_t count_or_format;
331  uint8_t packet_type;
332  uint32_t payload_size_bytes;
333  uint8_t padding_bytes;
334};
335
336enum RTCPPT : uint8_t {
337  PT_IJ = 195,
338  PT_SR = 200,
339  PT_RR = 201,
340  PT_SDES = 202,
341  PT_BYE = 203,
342  PT_APP = 204,
343  PT_RTPFB = 205,
344  PT_PSFB = 206,
345  PT_XR = 207
346};
347
348// Extended report blocks, RFC 3611.
349enum RtcpXrBlockType : uint8_t {
350  kBtReceiverReferenceTime = 4,
351  kBtDlrr = 5,
352  kBtVoipMetric = 7
353};
354
355bool RtcpParseCommonHeader(const uint8_t* buffer,
356                           size_t size_bytes,
357                           RtcpCommonHeader* parsed_header);
358
359class RTCPParserV2 {
360 public:
361  RTCPParserV2(
362      const uint8_t* rtcpData,
363      size_t rtcpDataLength,
364      bool rtcpReducedSizeEnable);  // Set to true, to allow non-compound RTCP!
365  ~RTCPParserV2();
366
367  RTCPPacketTypes PacketType() const;
368  const RTCPPacket& Packet() const;
369  rtcp::RtcpPacket* ReleaseRtcpPacket();
370  const RTCPRawPacket& RawPacket() const;
371  ptrdiff_t LengthLeft() const;
372
373  bool IsValid() const;
374  size_t NumSkippedBlocks() const;
375
376  RTCPPacketTypes Begin();
377  RTCPPacketTypes Iterate();
378
379 private:
380  enum class ParseState {
381    State_TopLevel,            // Top level packet
382    State_ReportBlockItem,     // SR/RR report block
383    State_SDESChunk,           // SDES chunk
384    State_BYEItem,             // BYE item
385    State_ExtendedJitterItem,  // Extended jitter report item
386    State_RTPFB_NACKItem,      // NACK FCI item
387    State_RTPFB_TMMBRItem,     // TMMBR FCI item
388    State_RTPFB_TMMBNItem,     // TMMBN FCI item
389    State_PSFB_SLIItem,        // SLI FCI item
390    State_PSFB_RPSIItem,       // RPSI FCI item
391    State_PSFB_FIRItem,        // FIR FCI item
392    State_PSFB_AppItem,        // Application specific FCI item
393    State_PSFB_REMBItem,       // Application specific REMB item
394    State_XRItem,
395    State_XR_DLLRItem,
396    State_AppItem
397  };
398
399 private:
400  void IterateTopLevel();
401  void IterateReportBlockItem();
402  void IterateSDESChunk();
403  void IterateBYEItem();
404  void IterateExtendedJitterItem();
405  void IterateNACKItem();
406  void IterateTMMBRItem();
407  void IterateTMMBNItem();
408  void IterateSLIItem();
409  void IterateRPSIItem();
410  void IterateFIRItem();
411  void IteratePsfbAppItem();
412  void IteratePsfbREMBItem();
413  void IterateAppItem();
414  void IterateXrItem();
415  void IterateXrDlrrItem();
416
417  void Validate();
418  void EndCurrentBlock();
419
420  bool ParseRR();
421  bool ParseSR();
422  bool ParseReportBlockItem();
423
424  bool ParseSDES();
425  bool ParseSDESChunk();
426  bool ParseSDESItem();
427
428  bool ParseBYE();
429  bool ParseBYEItem();
430
431  bool ParseIJ();
432  bool ParseIJItem();
433
434  bool ParseXr();
435  bool ParseXrItem();
436  bool ParseXrReceiverReferenceTimeItem(int block_length_4bytes);
437  bool ParseXrDlrr(int block_length_4bytes);
438  bool ParseXrDlrrItem();
439  bool ParseXrVoipMetricItem(int block_length_4bytes);
440  bool ParseXrUnsupportedBlockType(int block_length_4bytes);
441
442  bool ParseFBCommon(const RtcpCommonHeader& header);
443  bool ParseNACKItem();
444  bool ParseTMMBRItem();
445  bool ParseTMMBNItem();
446  bool ParseSLIItem();
447  bool ParseRPSIItem();
448  bool ParseFIRItem();
449  bool ParsePsfbAppItem();
450  bool ParsePsfbREMBItem();
451
452  bool ParseAPP(const RtcpCommonHeader& header);
453  bool ParseAPPItem();
454
455 private:
456  const uint8_t* const _ptrRTCPDataBegin;
457  const bool _RTCPReducedSizeEnable;
458  const uint8_t* const _ptrRTCPDataEnd;
459
460  bool _validPacket;
461  const uint8_t* _ptrRTCPData;
462  const uint8_t* _ptrRTCPBlockEnd;
463
464  ParseState _state;
465  uint8_t _numberOfBlocks;
466  size_t num_skipped_blocks_;
467
468  RTCPPacketTypes _packetType;
469  RTCPPacket _packet;
470  rtc::scoped_ptr<webrtc::rtcp::RtcpPacket> rtcp_packet_;
471};
472
473class RTCPPacketIterator {
474 public:
475  RTCPPacketIterator(uint8_t* rtcpData, size_t rtcpDataLength);
476  ~RTCPPacketIterator();
477
478  const RtcpCommonHeader* Begin();
479  const RtcpCommonHeader* Iterate();
480  const RtcpCommonHeader* Current();
481
482 private:
483  uint8_t* const _ptrBegin;
484  uint8_t* const _ptrEnd;
485
486  uint8_t* _ptrBlock;
487
488  RtcpCommonHeader _header;
489};
490}  // namespace RTCPUtility
491}  // namespace webrtc
492#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_
493