Home | History | Annotate | Download | only in source
      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:
     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:
     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:
     88   Empty() : RtcpPacket() {}
     89 
     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:
    122   ReportBlock() {
    123     // TODO(asapersson): Consider adding a constructor to struct.
    124     memset(&report_block_, 0, sizeof(report_block_));
    125   }
    126 
    127   ~ReportBlock() {}
    128 
    129   void To(uint32_t ssrc) {
    130     report_block_.SSRC = ssrc;
    131   }
    132   void WithFractionLost(uint8_t fraction_lost) {
    133     report_block_.FractionLost = fraction_lost;
    134   }
    135   void WithCumulativeLost(uint32_t cumulative_lost) {
    136     report_block_.CumulativeNumOfPacketsLost = cumulative_lost;
    137   }
    138   void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) {
    139     report_block_.ExtendedHighestSequenceNumber = ext_highest_seq_num;
    140   }
    141   void WithJitter(uint32_t jitter) {
    142     report_block_.Jitter = jitter;
    143   }
    144   void WithLastSr(uint32_t last_sr) {
    145     report_block_.LastSR = last_sr;
    146   }
    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:
    180   SenderReport() : RtcpPacket() {
    181     memset(&sr_, 0, sizeof(sr_));
    182   }
    183 
    184   virtual ~SenderReport() {}
    185 
    186   void From(uint32_t ssrc) {
    187     sr_.SenderSSRC = ssrc;
    188   }
    189   void WithNtpSec(uint32_t sec) {
    190     sr_.NTPMostSignificant = sec;
    191   }
    192   void WithNtpFrac(uint32_t frac) {
    193     sr_.NTPLeastSignificant = frac;
    194   }
    195   void WithRtpTimestamp(uint32_t rtp_timestamp) {
    196     sr_.RTPTimestamp = rtp_timestamp;
    197   }
    198   void WithPacketCount(uint32_t packet_count) {
    199     sr_.SenderPacketCount = packet_count;
    200   }
    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 
    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:
    241   ReceiverReport() : RtcpPacket() {
    242     memset(&rr_, 0, sizeof(rr_));
    243   }
    244 
    245   virtual ~ReceiverReport() {}
    246 
    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 
    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:
    291   Ij() : RtcpPacket() {}
    292 
    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 
    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:
    341   Sdes() : RtcpPacket() {}
    342 
    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:
    383   Bye() : RtcpPacket() {
    384     memset(&bye_, 0, sizeof(bye_));
    385   }
    386 
    387   virtual ~Bye() {}
    388 
    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 
    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:
    428   App()
    429       : RtcpPacket(),
    430         ssrc_(0) {
    431     memset(&app_, 0, sizeof(app_));
    432   }
    433 
    434   virtual ~App() {}
    435 
    436   void From(uint32_t ssrc) {
    437     ssrc_ = ssrc;
    438   }
    439   void WithSubType(uint8_t subtype) {
    440     assert(subtype <= 0x1f);
    441     app_.SubType = subtype;
    442   }
    443   void WithName(uint32_t name) {
    444     app_.Name = name;
    445   }
    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:
    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:
    491   Pli() : RtcpPacket() {
    492     memset(&pli_, 0, sizeof(pli_));
    493   }
    494 
    495   virtual ~Pli() {}
    496 
    497   void From(uint32_t ssrc) {
    498     pli_.SenderSSRC = ssrc;
    499   }
    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:
    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:
    529   Sli() : RtcpPacket() {
    530     memset(&sli_, 0, sizeof(sli_));
    531     memset(&sli_item_, 0, sizeof(sli_item_));
    532   }
    533 
    534   virtual ~Sli() {}
    535 
    536   void From(uint32_t ssrc) {
    537     sli_.SenderSSRC = ssrc;
    538   }
    539   void To(uint32_t ssrc) {
    540     sli_.MediaSSRC = ssrc;
    541   }
    542   void WithFirstMb(uint16_t first_mb) {
    543     assert(first_mb <= 0x1fff);
    544     sli_item_.FirstMB = first_mb;
    545   }
    546   void WithNumberOfMb(uint16_t number_mb) {
    547     assert(number_mb <= 0x1fff);
    548     sli_item_.NumberOfMB = number_mb;
    549   }
    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:
    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:
    582   Nack() : RtcpPacket() {
    583     memset(&nack_, 0, sizeof(nack_));
    584   }
    585 
    586   virtual ~Nack() {}
    587 
    588   void From(uint32_t ssrc) {
    589     nack_.SenderSSRC = ssrc;
    590   }
    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:
    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:
    626   Rpsi()
    627       : RtcpPacket(),
    628         padding_bytes_(0) {
    629     memset(&rpsi_, 0, sizeof(rpsi_));
    630   }
    631 
    632   virtual ~Rpsi() {}
    633 
    634   void From(uint32_t ssrc) {
    635     rpsi_.SenderSSRC = ssrc;
    636   }
    637   void To(uint32_t ssrc) {
    638     rpsi_.MediaSSRC = ssrc;
    639   }
    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:
    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:
    676   Fir() : RtcpPacket() {
    677     memset(&fir_, 0, sizeof(fir_));
    678     memset(&fir_item_, 0, sizeof(fir_item_));
    679   }
    680 
    681   virtual ~Fir() {}
    682 
    683   void From(uint32_t ssrc) {
    684     fir_.SenderSSRC = ssrc;
    685   }
    686   void To(uint32_t ssrc) {
    687     fir_item_.SSRC = ssrc;
    688   }
    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:
    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:
    721   Tmmbr() : RtcpPacket() {
    722     memset(&tmmbr_, 0, sizeof(tmmbr_));
    723     memset(&tmmbr_item_, 0, sizeof(tmmbr_item_));
    724   }
    725 
    726   virtual ~Tmmbr() {}
    727 
    728   void From(uint32_t ssrc) {
    729     tmmbr_.SenderSSRC = ssrc;
    730   }
    731   void To(uint32_t ssrc) {
    732     tmmbr_item_.SSRC = ssrc;
    733   }
    734   void WithBitrateKbps(uint32_t bitrate_kbps) {
    735     tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps;
    736   }
    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:
    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:
    772   Tmmbn() : RtcpPacket() {
    773     memset(&tmmbn_, 0, sizeof(tmmbn_));
    774   }
    775 
    776   virtual ~Tmmbn() {}
    777 
    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 
    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:
    822   Remb() : RtcpPacket() {
    823     memset(&remb_, 0, sizeof(remb_));
    824     memset(&remb_item_, 0, sizeof(remb_item_));
    825   }
    826 
    827   virtual ~Remb() {}
    828 
    829   void From(uint32_t ssrc) {
    830     remb_.SenderSSRC = ssrc;
    831   }
    832   void AppliesTo(uint32_t ssrc);
    833 
    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 
    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;
    872   Xr() : RtcpPacket() {
    873     memset(&xr_header_, 0, sizeof(xr_header_));
    874   }
    875 
    876   virtual ~Xr() {}
    877 
    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 
    894   size_t BlockLength() const {
    895     const size_t kXrHeaderLength = 8;
    896     return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength();
    897   }
    898 
    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 
    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:
    933   Rrtr() {
    934     memset(&rrtr_block_, 0, sizeof(rrtr_block_));
    935   }
    936   ~Rrtr() {}
    937 
    938   void WithNtpSec(uint32_t sec) {
    939     rrtr_block_.NTPMostSignificant = sec;
    940   }
    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:
    971   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:
   1011   VoipMetric() {
   1012     memset(&metric_, 0, sizeof(metric_));
   1013   }
   1014   ~VoipMetric() {}
   1015 
   1016   void To(uint32_t ssrc) { metric_.SSRC = ssrc; }
   1017   void LossRate(uint8_t loss_rate) { metric_.lossRate = loss_rate; }
   1018   void DiscardRate(uint8_t discard_rate) { metric_.discardRate = discard_rate; }
   1019   void BurstDensity(uint8_t burst_density) {
   1020     metric_.burstDensity = burst_density;
   1021   }
   1022   void GapDensity(uint8_t gap_density) { metric_.gapDensity = gap_density; }
   1023   void BurstDuration(uint16_t burst_duration) {
   1024     metric_.burstDuration = burst_duration;
   1025   }
   1026   void GapDuration(uint16_t gap_duration) {
   1027     metric_.gapDuration = gap_duration;
   1028   }
   1029   void RoundTripDelay(uint16_t round_trip_delay) {
   1030     metric_.roundTripDelay = round_trip_delay;
   1031   }
   1032   void EndSystemDelay(uint16_t end_system_delay) {
   1033     metric_.endSystemDelay = end_system_delay;
   1034   }
   1035   void SignalLevel(uint8_t signal_level) { metric_.signalLevel = signal_level; }
   1036   void NoiseLevel(uint8_t noise_level) { metric_.noiseLevel = noise_level; }
   1037   void Rerl(uint8_t rerl) { metric_.RERL = rerl; }
   1038   void Gmin(uint8_t gmin) { metric_.Gmin = gmin; }
   1039   void Rfactor(uint8_t rfactor) { metric_.Rfactor = rfactor; }
   1040   void ExtRfactor(uint8_t extrfactor) { metric_.extRfactor = extrfactor; }
   1041   void MosLq(uint8_t moslq) { metric_.MOSLQ = moslq; }
   1042   void MosCq(uint8_t moscq) { metric_.MOSCQ = moscq; }
   1043   void RxConfig(uint8_t rxconfig) { metric_.RXconfig = rxconfig; }
   1044   void JbNominal(uint16_t jbnominal) { metric_.JBnominal = jbnominal; }
   1045   void JbMax(uint16_t jbmax) { metric_.JBmax = jbmax; }
   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:
   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 
   1072   const uint8_t* buffer() {
   1073     return buffer_;
   1074   }
   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