• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2014 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 
12 #ifndef WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_
13 #define WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_
14 
15 #include <map>
16 #include <string>
17 #include <vector>
18 
19 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
20 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
21 #include "webrtc/typedefs.h"
22 
23 namespace webrtc {
24 namespace rtcp {
25 
26 enum { kCommonFbFmtLength = 12 };
27 enum { kReportBlockLength = 24 };
28 
29 class Dlrr;
30 class RawPacket;
31 class Rrtr;
32 class VoipMetric;
33 
34 // Class for building RTCP packets.
35 //
36 //  Example:
37 //  ReportBlock report_block;
38 //  report_block.To(234)
39 //  report_block.FractionLost(10);
40 //
41 //  ReceiverReport rr;
42 //  rr.From(123);
43 //  rr.WithReportBlock(&report_block)
44 //
45 //  Fir fir;
46 //  fir.From(123);
47 //  fir.To(234)
48 //  fir.WithCommandSeqNum(123);
49 //
50 //  size_t length = 0;                     // Builds an intra frame request
51 //  uint8_t packet[kPacketSize];           // with sequence number 123.
52 //  fir.Build(packet, &length, kPacketSize);
53 //
54 //  RawPacket packet = fir.Build();        // Returns a RawPacket holding
55 //                                         // the built rtcp packet.
56 //
57 //  rr.Append(&fir)                        // Builds a compound RTCP packet with
58 //  RawPacket packet = rr.Build();         // a receiver report, report block
59 //                                         // and fir message.
60 
61 class RtcpPacket {
62  public:
~RtcpPacket()63   virtual ~RtcpPacket() {}
64 
65   void Append(RtcpPacket* packet);
66 
67   RawPacket Build() const;
68 
69   void Build(uint8_t* packet, size_t* length, size_t max_length) const;
70 
71  protected:
RtcpPacket()72   RtcpPacket() : kHeaderLength(4) {}
73 
74   virtual void Create(
75       uint8_t* packet, size_t* length, size_t max_length) const = 0;
76 
77   const size_t kHeaderLength;
78 
79  private:
80   void CreateAndAddAppended(
81       uint8_t* packet, size_t* length, size_t max_length) const;
82 
83   std::vector<RtcpPacket*> appended_packets_;
84 };
85 
86 class Empty : public RtcpPacket {
87  public:
Empty()88   Empty() : RtcpPacket() {}
89 
~Empty()90   virtual ~Empty() {}
91 
92  protected:
93   virtual void Create(
94       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
95 
96  private:
97   DISALLOW_COPY_AND_ASSIGN(Empty);
98 };
99 
100 // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
101 //
102 // RTCP report block (RFC 3550).
103 //
104 //   0                   1                   2                   3
105 //   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
106 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
107 //  |                 SSRC_1 (SSRC of first source)                 |
108 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
109 //  | fraction lost |       cumulative number of packets lost       |
110 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111 //  |           extended highest sequence number received           |
112 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
113 //  |                      interarrival jitter                      |
114 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115 //  |                         last SR (LSR)                         |
116 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117 //  |                   delay since last SR (DLSR)                  |
118 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
119 
120 class ReportBlock {
121  public:
ReportBlock()122   ReportBlock() {
123     // TODO(asapersson): Consider adding a constructor to struct.
124     memset(&report_block_, 0, sizeof(report_block_));
125   }
126 
~ReportBlock()127   ~ReportBlock() {}
128 
To(uint32_t ssrc)129   void To(uint32_t ssrc) {
130     report_block_.SSRC = ssrc;
131   }
WithFractionLost(uint8_t fraction_lost)132   void WithFractionLost(uint8_t fraction_lost) {
133     report_block_.FractionLost = fraction_lost;
134   }
WithCumulativeLost(uint32_t cumulative_lost)135   void WithCumulativeLost(uint32_t cumulative_lost) {
136     report_block_.CumulativeNumOfPacketsLost = cumulative_lost;
137   }
WithExtHighestSeqNum(uint32_t ext_highest_seq_num)138   void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) {
139     report_block_.ExtendedHighestSequenceNumber = ext_highest_seq_num;
140   }
WithJitter(uint32_t jitter)141   void WithJitter(uint32_t jitter) {
142     report_block_.Jitter = jitter;
143   }
WithLastSr(uint32_t last_sr)144   void WithLastSr(uint32_t last_sr) {
145     report_block_.LastSR = last_sr;
146   }
WithDelayLastSr(uint32_t delay_last_sr)147   void WithDelayLastSr(uint32_t delay_last_sr) {
148     report_block_.DelayLastSR = delay_last_sr;
149   }
150 
151  private:
152   friend class SenderReport;
153   friend class ReceiverReport;
154   RTCPUtility::RTCPPacketReportBlockItem report_block_;
155 };
156 
157 // RTCP sender report (RFC 3550).
158 //
159 //   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
160 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161 //  |V=2|P|    RC   |   PT=SR=200   |             length            |
162 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163 //  |                         SSRC of sender                        |
164 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
165 //  |              NTP timestamp, most significant word             |
166 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167 //  |             NTP timestamp, least significant word             |
168 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
169 //  |                         RTP timestamp                         |
170 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
171 //  |                     sender's packet count                     |
172 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
173 //  |                      sender's octet count                     |
174 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
175 //  |                         report block(s)                       |
176 //  |                            ....                               |
177 
178 class SenderReport : public RtcpPacket {
179  public:
SenderReport()180   SenderReport() : RtcpPacket() {
181     memset(&sr_, 0, sizeof(sr_));
182   }
183 
~SenderReport()184   virtual ~SenderReport() {}
185 
From(uint32_t ssrc)186   void From(uint32_t ssrc) {
187     sr_.SenderSSRC = ssrc;
188   }
WithNtpSec(uint32_t sec)189   void WithNtpSec(uint32_t sec) {
190     sr_.NTPMostSignificant = sec;
191   }
WithNtpFrac(uint32_t frac)192   void WithNtpFrac(uint32_t frac) {
193     sr_.NTPLeastSignificant = frac;
194   }
WithRtpTimestamp(uint32_t rtp_timestamp)195   void WithRtpTimestamp(uint32_t rtp_timestamp) {
196     sr_.RTPTimestamp = rtp_timestamp;
197   }
WithPacketCount(uint32_t packet_count)198   void WithPacketCount(uint32_t packet_count) {
199     sr_.SenderPacketCount = packet_count;
200   }
WithOctetCount(uint32_t octet_count)201   void WithOctetCount(uint32_t octet_count) {
202     sr_.SenderOctetCount = octet_count;
203   }
204   void WithReportBlock(ReportBlock* block);
205 
206  protected:
207   virtual void Create(
208       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
209 
210  private:
211   enum { kMaxNumberOfReportBlocks = 0x1f };
212 
BlockLength()213   size_t BlockLength() const {
214     const size_t kSrHeaderLength = 8;
215     const size_t kSenderInfoLength = 20;
216     return kSrHeaderLength + kSenderInfoLength +
217            report_blocks_.size() * kReportBlockLength;
218   }
219 
220   RTCPUtility::RTCPPacketSR sr_;
221   std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
222 
223   DISALLOW_COPY_AND_ASSIGN(SenderReport);
224 };
225 
226 //
227 // RTCP receiver report (RFC 3550).
228 //
229 //   0                   1                   2                   3
230 //   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
231 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
232 //  |V=2|P|    RC   |   PT=RR=201   |             length            |
233 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
234 //  |                     SSRC of packet sender                     |
235 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
236 //  |                         report block(s)                       |
237 //  |                            ....                               |
238 
239 class ReceiverReport : public RtcpPacket {
240  public:
ReceiverReport()241   ReceiverReport() : RtcpPacket() {
242     memset(&rr_, 0, sizeof(rr_));
243   }
244 
~ReceiverReport()245   virtual ~ReceiverReport() {}
246 
From(uint32_t ssrc)247   void From(uint32_t ssrc) {
248     rr_.SenderSSRC = ssrc;
249   }
250   void WithReportBlock(ReportBlock* block);
251 
252  protected:
253   virtual void Create(
254       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
255 
256  private:
257   enum { kMaxNumberOfReportBlocks = 0x1f };
258 
BlockLength()259   size_t BlockLength() const {
260     const size_t kRrHeaderLength = 8;
261     return kRrHeaderLength + report_blocks_.size() * kReportBlockLength;
262   }
263 
264   RTCPUtility::RTCPPacketRR rr_;
265   std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
266 
267   DISALLOW_COPY_AND_ASSIGN(ReceiverReport);
268 };
269 
270 // Transmission Time Offsets in RTP Streams (RFC 5450).
271 //
272 //      0                   1                   2                   3
273 //      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
274 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
275 // hdr |V=2|P|    RC   |   PT=IJ=195   |             length            |
276 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
277 //     |                      inter-arrival jitter                     |
278 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
279 //     .                                                               .
280 //     .                                                               .
281 //     .                                                               .
282 //     |                      inter-arrival jitter                     |
283 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
284 //
285 //  If present, this RTCP packet must be placed after a receiver report
286 //  (inside a compound RTCP packet), and MUST have the same value for RC
287 //  (reception report count) as the receiver report.
288 
289 class Ij : public RtcpPacket {
290  public:
Ij()291   Ij() : RtcpPacket() {}
292 
~Ij()293   virtual ~Ij() {}
294 
295   void WithJitterItem(uint32_t jitter);
296 
297  protected:
298   virtual void Create(
299       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
300 
301  private:
302   enum { kMaxNumberOfIjItems = 0x1f };
303 
BlockLength()304   size_t BlockLength() const {
305     return kHeaderLength + 4 * ij_items_.size();
306   }
307 
308   std::vector<uint32_t> ij_items_;
309 
310   DISALLOW_COPY_AND_ASSIGN(Ij);
311 };
312 
313 // Source Description (SDES) (RFC 3550).
314 //
315 //         0                   1                   2                   3
316 //         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
317 //        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
318 // header |V=2|P|    SC   |  PT=SDES=202  |             length            |
319 //        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
320 // chunk  |                          SSRC/CSRC_1                          |
321 //   1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
322 //        |                           SDES items                          |
323 //        |                              ...                              |
324 //        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
325 // chunk  |                          SSRC/CSRC_2                          |
326 //   2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
327 //        |                           SDES items                          |
328 //        |                              ...                              |
329 //        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
330 //
331 // Canonical End-Point Identifier SDES Item (CNAME)
332 //
333 //    0                   1                   2                   3
334 //    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
335 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
336 //   |    CNAME=1    |     length    | user and domain name        ...
337 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
338 
339 class Sdes : public RtcpPacket {
340  public:
Sdes()341   Sdes() : RtcpPacket() {}
342 
~Sdes()343   virtual ~Sdes() {}
344 
345   void WithCName(uint32_t ssrc, std::string cname);
346 
347   struct Chunk {
348     uint32_t ssrc;
349     std::string name;
350     int null_octets;
351   };
352 
353  protected:
354   virtual void Create(
355       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
356 
357  private:
358   enum { kMaxNumberOfChunks = 0x1f };
359 
360   size_t BlockLength() const;
361 
362   std::vector<Chunk> chunks_;
363 
364   DISALLOW_COPY_AND_ASSIGN(Sdes);
365 };
366 
367 //
368 // Bye packet (BYE) (RFC 3550).
369 //
370 //        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
371 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
372 //       |V=2|P|    SC   |   PT=BYE=203  |             length            |
373 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
374 //       |                           SSRC/CSRC                           |
375 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
376 //       :                              ...                              :
377 //       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
378 // (opt) |     length    |               reason for leaving            ...
379 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
380 
381 class Bye : public RtcpPacket {
382  public:
Bye()383   Bye() : RtcpPacket() {
384     memset(&bye_, 0, sizeof(bye_));
385   }
386 
~Bye()387   virtual ~Bye() {}
388 
From(uint32_t ssrc)389   void From(uint32_t ssrc) {
390     bye_.SenderSSRC = ssrc;
391   }
392   void WithCsrc(uint32_t csrc);
393 
394  protected:
395   virtual void Create(
396       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
397 
398  private:
399   enum { kMaxNumberOfCsrcs = 0x1f - 1 };
400 
BlockLength()401   size_t BlockLength() const {
402     size_t source_count = 1 + csrcs_.size();
403     return kHeaderLength + 4 * source_count;
404   }
405 
406   RTCPUtility::RTCPPacketBYE bye_;
407   std::vector<uint32_t> csrcs_;
408 
409   DISALLOW_COPY_AND_ASSIGN(Bye);
410 };
411 
412 // Application-Defined packet (APP) (RFC 3550).
413 //
414 //   0                   1                   2                   3
415 //   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
416 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
417 //  |V=2|P| subtype |   PT=APP=204  |             length            |
418 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
419 //  |                           SSRC/CSRC                           |
420 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
421 //  |                          name (ASCII)                         |
422 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
423 //  |                   application-dependent data                ...
424 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
425 
426 class App : public RtcpPacket {
427  public:
App()428   App()
429       : RtcpPacket(),
430         ssrc_(0) {
431     memset(&app_, 0, sizeof(app_));
432   }
433 
~App()434   virtual ~App() {}
435 
From(uint32_t ssrc)436   void From(uint32_t ssrc) {
437     ssrc_ = ssrc;
438   }
WithSubType(uint8_t subtype)439   void WithSubType(uint8_t subtype) {
440     assert(subtype <= 0x1f);
441     app_.SubType = subtype;
442   }
WithName(uint32_t name)443   void WithName(uint32_t name) {
444     app_.Name = name;
445   }
WithData(const uint8_t * data,uint16_t data_length)446   void WithData(const uint8_t* data, uint16_t data_length) {
447     assert(data);
448     assert(data_length <= kRtcpAppCode_DATA_SIZE);
449     assert(data_length % 4 == 0);
450     memcpy(app_.Data, data, data_length);
451     app_.Size = data_length;
452   }
453 
454  protected:
455   virtual void Create(
456       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
457 
458  private:
BlockLength()459   size_t BlockLength() const {
460     return 12 + app_.Size;
461   }
462 
463   uint32_t ssrc_;
464   RTCPUtility::RTCPPacketAPP app_;
465 
466   DISALLOW_COPY_AND_ASSIGN(App);
467 };
468 
469 // RFC 4585: Feedback format.
470 //
471 // Common packet format:
472 //
473 //    0                   1                   2                   3
474 //    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
475 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
476 //   |V=2|P|   FMT   |       PT      |          length               |
477 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
478 //   |                  SSRC of packet sender                        |
479 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
480 //   |                  SSRC of media source                         |
481 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
482 //   :            Feedback Control Information (FCI)                 :
483 //   :
484 
485 // Picture loss indication (PLI) (RFC 4585).
486 //
487 // FCI: no feedback control information.
488 
489 class Pli : public RtcpPacket {
490  public:
Pli()491   Pli() : RtcpPacket() {
492     memset(&pli_, 0, sizeof(pli_));
493   }
494 
~Pli()495   virtual ~Pli() {}
496 
From(uint32_t ssrc)497   void From(uint32_t ssrc) {
498     pli_.SenderSSRC = ssrc;
499   }
To(uint32_t ssrc)500   void To(uint32_t ssrc) {
501     pli_.MediaSSRC = ssrc;
502   }
503 
504  protected:
505   virtual void Create(
506       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
507 
508  private:
BlockLength()509   size_t BlockLength() const {
510     return kCommonFbFmtLength;
511   }
512 
513   RTCPUtility::RTCPPacketPSFBPLI pli_;
514 
515   DISALLOW_COPY_AND_ASSIGN(Pli);
516 };
517 
518 // Slice loss indication (SLI) (RFC 4585).
519 //
520 // FCI:
521 //    0                   1                   2                   3
522 //    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
523 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
524 //   |            First        |        Number           | PictureID |
525 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
526 
527 class Sli : public RtcpPacket {
528  public:
Sli()529   Sli() : RtcpPacket() {
530     memset(&sli_, 0, sizeof(sli_));
531     memset(&sli_item_, 0, sizeof(sli_item_));
532   }
533 
~Sli()534   virtual ~Sli() {}
535 
From(uint32_t ssrc)536   void From(uint32_t ssrc) {
537     sli_.SenderSSRC = ssrc;
538   }
To(uint32_t ssrc)539   void To(uint32_t ssrc) {
540     sli_.MediaSSRC = ssrc;
541   }
WithFirstMb(uint16_t first_mb)542   void WithFirstMb(uint16_t first_mb) {
543     assert(first_mb <= 0x1fff);
544     sli_item_.FirstMB = first_mb;
545   }
WithNumberOfMb(uint16_t number_mb)546   void WithNumberOfMb(uint16_t number_mb) {
547     assert(number_mb <= 0x1fff);
548     sli_item_.NumberOfMB = number_mb;
549   }
WithPictureId(uint8_t picture_id)550   void WithPictureId(uint8_t picture_id) {
551     assert(picture_id <= 0x3f);
552     sli_item_.PictureId = picture_id;
553   }
554 
555  protected:
556   virtual void Create(
557       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
558 
559  private:
BlockLength()560   size_t BlockLength() const {
561     const size_t kFciLength = 4;
562     return kCommonFbFmtLength + kFciLength;
563   }
564 
565   RTCPUtility::RTCPPacketPSFBSLI sli_;
566   RTCPUtility::RTCPPacketPSFBSLIItem sli_item_;
567 
568   DISALLOW_COPY_AND_ASSIGN(Sli);
569 };
570 
571 // Generic NACK (RFC 4585).
572 //
573 // FCI:
574 //    0                   1                   2                   3
575 //    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
576 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
577 //   |            PID                |             BLP               |
578 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
579 
580 class Nack : public RtcpPacket {
581  public:
Nack()582   Nack() : RtcpPacket() {
583     memset(&nack_, 0, sizeof(nack_));
584   }
585 
~Nack()586   virtual ~Nack() {}
587 
From(uint32_t ssrc)588   void From(uint32_t ssrc) {
589     nack_.SenderSSRC = ssrc;
590   }
To(uint32_t ssrc)591   void To(uint32_t ssrc) {
592     nack_.MediaSSRC = ssrc;
593   }
594   void WithList(const uint16_t* nack_list, int length);
595 
596  protected:
597   virtual void Create(
598       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
599 
600  private:
BlockLength()601   size_t BlockLength() const {
602     size_t fci_length = 4 * nack_fields_.size();
603     return kCommonFbFmtLength + fci_length;
604   }
605 
606   RTCPUtility::RTCPPacketRTPFBNACK nack_;
607   std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_;
608 
609   DISALLOW_COPY_AND_ASSIGN(Nack);
610 };
611 
612 // Reference picture selection indication (RPSI) (RFC 4585).
613 //
614 // FCI:
615 //
616 //    0                   1                   2                   3
617 //    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
618 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
619 //   |      PB       |0| Payload Type|    Native RPSI bit string     |
620 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
621 //   |   defined per codec          ...                | Padding (0) |
622 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
623 
624 class Rpsi : public RtcpPacket {
625  public:
Rpsi()626   Rpsi()
627       : RtcpPacket(),
628         padding_bytes_(0) {
629     memset(&rpsi_, 0, sizeof(rpsi_));
630   }
631 
~Rpsi()632   virtual ~Rpsi() {}
633 
From(uint32_t ssrc)634   void From(uint32_t ssrc) {
635     rpsi_.SenderSSRC = ssrc;
636   }
To(uint32_t ssrc)637   void To(uint32_t ssrc) {
638     rpsi_.MediaSSRC = ssrc;
639   }
WithPayloadType(uint8_t payload)640   void WithPayloadType(uint8_t payload) {
641     assert(payload <= 0x7f);
642     rpsi_.PayloadType = payload;
643   }
644   void WithPictureId(uint64_t picture_id);
645 
646  protected:
647   virtual void Create(
648       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
649 
650  private:
BlockLength()651   size_t BlockLength() const {
652     size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_;
653     return kCommonFbFmtLength + fci_length;
654   }
655 
656   uint8_t padding_bytes_;
657   RTCPUtility::RTCPPacketPSFBRPSI rpsi_;
658 
659   DISALLOW_COPY_AND_ASSIGN(Rpsi);
660 };
661 
662 // Full intra request (FIR) (RFC 5104).
663 //
664 // FCI:
665 //
666 //    0                   1                   2                   3
667 //    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
668 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
669 //   |                              SSRC                             |
670 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
671 //   | Seq nr.       |    Reserved                                   |
672 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
673 
674 class Fir : public RtcpPacket {
675  public:
Fir()676   Fir() : RtcpPacket() {
677     memset(&fir_, 0, sizeof(fir_));
678     memset(&fir_item_, 0, sizeof(fir_item_));
679   }
680 
~Fir()681   virtual ~Fir() {}
682 
From(uint32_t ssrc)683   void From(uint32_t ssrc) {
684     fir_.SenderSSRC = ssrc;
685   }
To(uint32_t ssrc)686   void To(uint32_t ssrc) {
687     fir_item_.SSRC = ssrc;
688   }
WithCommandSeqNum(uint8_t seq_num)689   void WithCommandSeqNum(uint8_t seq_num) {
690     fir_item_.CommandSequenceNumber = seq_num;
691   }
692 
693  protected:
694   virtual void Create(
695       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
696 
697  private:
BlockLength()698   size_t BlockLength() const {
699     const size_t kFciLength = 8;
700     return kCommonFbFmtLength + kFciLength;
701   }
702 
703   RTCPUtility::RTCPPacketPSFBFIR fir_;
704   RTCPUtility::RTCPPacketPSFBFIRItem fir_item_;
705 };
706 
707 // Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104).
708 //
709 // FCI:
710 //
711 //    0                   1                   2                   3
712 //    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
713 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
714 //   |                              SSRC                             |
715 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
716 //   | MxTBR Exp |  MxTBR Mantissa                 |Measured Overhead|
717 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
718 
719 class Tmmbr : public RtcpPacket {
720  public:
Tmmbr()721   Tmmbr() : RtcpPacket() {
722     memset(&tmmbr_, 0, sizeof(tmmbr_));
723     memset(&tmmbr_item_, 0, sizeof(tmmbr_item_));
724   }
725 
~Tmmbr()726   virtual ~Tmmbr() {}
727 
From(uint32_t ssrc)728   void From(uint32_t ssrc) {
729     tmmbr_.SenderSSRC = ssrc;
730   }
To(uint32_t ssrc)731   void To(uint32_t ssrc) {
732     tmmbr_item_.SSRC = ssrc;
733   }
WithBitrateKbps(uint32_t bitrate_kbps)734   void WithBitrateKbps(uint32_t bitrate_kbps) {
735     tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps;
736   }
WithOverhead(uint16_t overhead)737   void WithOverhead(uint16_t overhead) {
738     assert(overhead <= 0x1ff);
739     tmmbr_item_.MeasuredOverhead = overhead;
740   }
741 
742  protected:
743   virtual void Create(
744       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
745 
746  private:
BlockLength()747   size_t BlockLength() const {
748     const size_t kFciLen = 8;
749     return kCommonFbFmtLength + kFciLen;
750   }
751 
752   RTCPUtility::RTCPPacketRTPFBTMMBR tmmbr_;
753   RTCPUtility::RTCPPacketRTPFBTMMBRItem tmmbr_item_;
754 
755   DISALLOW_COPY_AND_ASSIGN(Tmmbr);
756 };
757 
758 // Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
759 //
760 // FCI:
761 //
762 //    0                   1                   2                   3
763 //    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
764 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
765 //   |                              SSRC                             |
766 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
767 //   | MxTBR Exp |  MxTBR Mantissa                 |Measured Overhead|
768 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
769 
770 class Tmmbn : public RtcpPacket {
771  public:
Tmmbn()772   Tmmbn() : RtcpPacket() {
773     memset(&tmmbn_, 0, sizeof(tmmbn_));
774   }
775 
~Tmmbn()776   virtual ~Tmmbn() {}
777 
From(uint32_t ssrc)778   void From(uint32_t ssrc) {
779     tmmbn_.SenderSSRC = ssrc;
780   }
781   void WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead);
782 
783  protected:
784   virtual void Create(
785       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
786 
787  private:
788   enum { kMaxNumberOfTmmbrs = 50 };
789 
BlockLength()790   size_t BlockLength() const {
791     const size_t kFciLen = 8;
792     return kCommonFbFmtLength + kFciLen * tmmbn_items_.size();
793   }
794 
795   RTCPUtility::RTCPPacketRTPFBTMMBN tmmbn_;
796   std::vector<RTCPUtility::RTCPPacketRTPFBTMMBRItem> tmmbn_items_;
797 
798   DISALLOW_COPY_AND_ASSIGN(Tmmbn);
799 };
800 
801 // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
802 //
803 //    0                   1                   2                   3
804 //    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
805 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
806 //   |V=2|P| FMT=15  |   PT=206      |             length            |
807 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
808 //   |                  SSRC of packet sender                        |
809 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
810 //   |                  SSRC of media source                         |
811 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
812 //   |  Unique identifier 'R' 'E' 'M' 'B'                            |
813 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
814 //   |  Num SSRC     | BR Exp    |  BR Mantissa                      |
815 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
816 //   |   SSRC feedback                                               |
817 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
818 //   |  ...
819 
820 class Remb : public RtcpPacket {
821  public:
Remb()822   Remb() : RtcpPacket() {
823     memset(&remb_, 0, sizeof(remb_));
824     memset(&remb_item_, 0, sizeof(remb_item_));
825   }
826 
~Remb()827   virtual ~Remb() {}
828 
From(uint32_t ssrc)829   void From(uint32_t ssrc) {
830     remb_.SenderSSRC = ssrc;
831   }
832   void AppliesTo(uint32_t ssrc);
833 
WithBitrateBps(uint32_t bitrate_bps)834   void WithBitrateBps(uint32_t bitrate_bps) {
835     remb_item_.BitRate = bitrate_bps;
836   }
837 
838  protected:
839   virtual void Create(
840       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
841 
842  private:
843   enum { kMaxNumberOfSsrcs = 0xff };
844 
BlockLength()845   size_t BlockLength() const {
846     return (remb_item_.NumberOfSSRCs + 5) * 4;
847   }
848 
849   RTCPUtility::RTCPPacketPSFBAPP remb_;
850   RTCPUtility::RTCPPacketPSFBREMBItem remb_item_;
851 
852   DISALLOW_COPY_AND_ASSIGN(Remb);
853 };
854 
855 // From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR).
856 //
857 // Format for XR packets:
858 //
859 //   0                   1                   2                   3
860 //   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
861 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
862 //  |V=2|P|reserved |   PT=XR=207   |             length            |
863 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
864 //  |                              SSRC                             |
865 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
866 //  :                         report blocks                         :
867 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
868 
869 class Xr : public RtcpPacket {
870  public:
871   typedef std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> DlrrBlock;
Xr()872   Xr() : RtcpPacket() {
873     memset(&xr_header_, 0, sizeof(xr_header_));
874   }
875 
~Xr()876   virtual ~Xr() {}
877 
From(uint32_t ssrc)878   void From(uint32_t ssrc) {
879     xr_header_.OriginatorSSRC = ssrc;
880   }
881   void WithRrtr(Rrtr* rrtr);
882   void WithDlrr(Dlrr* dlrr);
883   void WithVoipMetric(VoipMetric* voip_metric);
884 
885  protected:
886   virtual void Create(
887       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
888 
889  private:
890   enum { kMaxNumberOfRrtrBlocks = 50 };
891   enum { kMaxNumberOfDlrrBlocks = 50 };
892   enum { kMaxNumberOfVoipMetricBlocks = 50 };
893 
BlockLength()894   size_t BlockLength() const {
895     const size_t kXrHeaderLength = 8;
896     return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength();
897   }
898 
RrtrLength()899   size_t RrtrLength() const {
900     const size_t kRrtrBlockLength = 12;
901     return kRrtrBlockLength * rrtr_blocks_.size();
902   }
903 
904   size_t DlrrLength() const;
905 
VoipMetricLength()906   size_t VoipMetricLength() const {
907     const size_t kVoipMetricBlockLength = 36;
908     return kVoipMetricBlockLength * voip_metric_blocks_.size();
909   }
910 
911   RTCPUtility::RTCPPacketXR xr_header_;
912   std::vector<RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem> rrtr_blocks_;
913   std::vector<DlrrBlock> dlrr_blocks_;
914   std::vector<RTCPUtility::RTCPPacketXRVOIPMetricItem> voip_metric_blocks_;
915 
916   DISALLOW_COPY_AND_ASSIGN(Xr);
917 };
918 
919 // Receiver Reference Time Report Block (RFC 3611).
920 //
921 //   0                   1                   2                   3
922 //   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
923 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
924 //  |     BT=4      |   reserved    |       block length = 2        |
925 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
926 //  |              NTP timestamp, most significant word             |
927 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
928 //  |             NTP timestamp, least significant word             |
929 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
930 
931 class Rrtr {
932  public:
Rrtr()933   Rrtr() {
934     memset(&rrtr_block_, 0, sizeof(rrtr_block_));
935   }
~Rrtr()936   ~Rrtr() {}
937 
WithNtpSec(uint32_t sec)938   void WithNtpSec(uint32_t sec) {
939     rrtr_block_.NTPMostSignificant = sec;
940   }
WithNtpFrac(uint32_t frac)941   void WithNtpFrac(uint32_t frac) {
942     rrtr_block_.NTPLeastSignificant = frac;
943   }
944 
945  private:
946   friend class Xr;
947   RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem rrtr_block_;
948 
949   DISALLOW_COPY_AND_ASSIGN(Rrtr);
950 };
951 
952 // DLRR Report Block (RFC 3611).
953 //
954 //   0                   1                   2                   3
955 //   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
956 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
957 //  |     BT=5      |   reserved    |         block length          |
958 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
959 //  |                 SSRC_1 (SSRC of first receiver)               | sub-
960 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
961 //  |                         last RR (LRR)                         |   1
962 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
963 //  |                   delay since last RR (DLRR)                  |
964 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
965 //  |                 SSRC_2 (SSRC of second receiver)              | sub-
966 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
967 //  :                               ...                             :   2
968 
969 class Dlrr {
970  public:
Dlrr()971   Dlrr() {}
~Dlrr()972   ~Dlrr() {}
973 
974   void WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr);
975 
976  private:
977   friend class Xr;
978   enum { kMaxNumberOfDlrrItems = 100 };
979 
980   std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> dlrr_block_;
981 
982   DISALLOW_COPY_AND_ASSIGN(Dlrr);
983 };
984 
985 // VoIP Metrics Report Block (RFC 3611).
986 //
987 //   0                   1                   2                   3
988 //   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
989 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
990 //  |     BT=7      |   reserved    |       block length = 8        |
991 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
992 //  |                        SSRC of source                         |
993 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
994 //  |   loss rate   | discard rate  | burst density |  gap density  |
995 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
996 //  |       burst duration          |         gap duration          |
997 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
998 //  |     round trip delay          |       end system delay        |
999 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1000 //  | signal level  |  noise level  |     RERL      |     Gmin      |
1001 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1002 //  |   R factor    | ext. R factor |    MOS-LQ     |    MOS-CQ     |
1003 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1004 //  |   RX config   |   reserved    |          JB nominal           |
1005 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1006 //  |          JB maximum           |          JB abs max           |
1007 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1008 
1009 class VoipMetric {
1010  public:
VoipMetric()1011   VoipMetric() {
1012     memset(&metric_, 0, sizeof(metric_));
1013   }
~VoipMetric()1014   ~VoipMetric() {}
1015 
To(uint32_t ssrc)1016   void To(uint32_t ssrc) { metric_.SSRC = ssrc; }
LossRate(uint8_t loss_rate)1017   void LossRate(uint8_t loss_rate) { metric_.lossRate = loss_rate; }
DiscardRate(uint8_t discard_rate)1018   void DiscardRate(uint8_t discard_rate) { metric_.discardRate = discard_rate; }
BurstDensity(uint8_t burst_density)1019   void BurstDensity(uint8_t burst_density) {
1020     metric_.burstDensity = burst_density;
1021   }
GapDensity(uint8_t gap_density)1022   void GapDensity(uint8_t gap_density) { metric_.gapDensity = gap_density; }
BurstDuration(uint16_t burst_duration)1023   void BurstDuration(uint16_t burst_duration) {
1024     metric_.burstDuration = burst_duration;
1025   }
GapDuration(uint16_t gap_duration)1026   void GapDuration(uint16_t gap_duration) {
1027     metric_.gapDuration = gap_duration;
1028   }
RoundTripDelay(uint16_t round_trip_delay)1029   void RoundTripDelay(uint16_t round_trip_delay) {
1030     metric_.roundTripDelay = round_trip_delay;
1031   }
EndSystemDelay(uint16_t end_system_delay)1032   void EndSystemDelay(uint16_t end_system_delay) {
1033     metric_.endSystemDelay = end_system_delay;
1034   }
SignalLevel(uint8_t signal_level)1035   void SignalLevel(uint8_t signal_level) { metric_.signalLevel = signal_level; }
NoiseLevel(uint8_t noise_level)1036   void NoiseLevel(uint8_t noise_level) { metric_.noiseLevel = noise_level; }
Rerl(uint8_t rerl)1037   void Rerl(uint8_t rerl) { metric_.RERL = rerl; }
Gmin(uint8_t gmin)1038   void Gmin(uint8_t gmin) { metric_.Gmin = gmin; }
Rfactor(uint8_t rfactor)1039   void Rfactor(uint8_t rfactor) { metric_.Rfactor = rfactor; }
ExtRfactor(uint8_t extrfactor)1040   void ExtRfactor(uint8_t extrfactor) { metric_.extRfactor = extrfactor; }
MosLq(uint8_t moslq)1041   void MosLq(uint8_t moslq) { metric_.MOSLQ = moslq; }
MosCq(uint8_t moscq)1042   void MosCq(uint8_t moscq) { metric_.MOSCQ = moscq; }
RxConfig(uint8_t rxconfig)1043   void RxConfig(uint8_t rxconfig) { metric_.RXconfig = rxconfig; }
JbNominal(uint16_t jbnominal)1044   void JbNominal(uint16_t jbnominal) { metric_.JBnominal = jbnominal; }
JbMax(uint16_t jbmax)1045   void JbMax(uint16_t jbmax) { metric_.JBmax = jbmax; }
JbAbsMax(uint16_t jbabsmax)1046   void JbAbsMax(uint16_t jbabsmax) { metric_.JBabsMax = jbabsmax; }
1047 
1048  private:
1049   friend class Xr;
1050   RTCPUtility::RTCPPacketXRVOIPMetricItem metric_;
1051 
1052   DISALLOW_COPY_AND_ASSIGN(VoipMetric);
1053 };
1054 
1055 // Class holding a RTCP packet.
1056 //
1057 // Takes a built rtcp packet.
1058 //  RawPacket raw_packet(buffer, length);
1059 //
1060 // To access the raw packet:
1061 //  raw_packet.buffer();         - pointer to the raw packet
1062 //  raw_packet.buffer_length();  - the length of the raw packet
1063 
1064 class RawPacket {
1065  public:
RawPacket(const uint8_t * packet,size_t length)1066   RawPacket(const uint8_t* packet, size_t length) {
1067     assert(length <= IP_PACKET_SIZE);
1068     memcpy(buffer_, packet, length);
1069     buffer_length_ = length;
1070   }
1071 
buffer()1072   const uint8_t* buffer() {
1073     return buffer_;
1074   }
buffer_length()1075   size_t buffer_length() const {
1076     return buffer_length_;
1077   }
1078 
1079  private:
1080   size_t buffer_length_;
1081   uint8_t buffer_[IP_PACKET_SIZE];
1082 };
1083 
1084 }  // namespace rtcp
1085 }  // namespace webrtc
1086 #endif  // WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_
1087