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 RawPacket;
     30 
     31 // Class for building RTCP packets.
     32 //
     33 //  Example:
     34 //  ReportBlock report_block;
     35 //  report_block.To(234)
     36 //  report_block.FractionLost(10);
     37 //
     38 //  ReceiverReport rr;
     39 //  rr.From(123);
     40 //  rr.WithReportBlock(&report_block)
     41 //
     42 //  Fir fir;
     43 //  fir.From(123);
     44 //  fir.To(234)
     45 //  fir.WithCommandSeqNum(123);
     46 //
     47 //  size_t length = 0;                     // Builds an intra frame request
     48 //  uint8_t packet[kPacketSize];           // with sequence number 123.
     49 //  fir.Build(packet, &length, kPacketSize);
     50 //
     51 //  RawPacket packet = fir.Build();        // Returns a RawPacket holding
     52 //                                         // the built rtcp packet.
     53 //
     54 //  rr.Append(&fir)                        // Builds a compound RTCP packet with
     55 //  RawPacket packet = rr.Build();         // a receiver report, report block
     56 //                                         // and fir message.
     57 
     58 class RtcpPacket {
     59  public:
     60   virtual ~RtcpPacket() {}
     61 
     62   void Append(RtcpPacket* packet);
     63 
     64   RawPacket Build() const;
     65 
     66   void Build(uint8_t* packet, size_t* length, size_t max_length) const;
     67 
     68  protected:
     69   RtcpPacket() : kHeaderLength(4) {}
     70 
     71   virtual void Create(
     72       uint8_t* packet, size_t* length, size_t max_length) const = 0;
     73 
     74   const size_t kHeaderLength;
     75 
     76  private:
     77   void CreateAndAddAppended(
     78       uint8_t* packet, size_t* length, size_t max_length) const;
     79 
     80   std::vector<RtcpPacket*> appended_packets_;
     81 };
     82 
     83 class Empty : public RtcpPacket {
     84  public:
     85   Empty() {}
     86 
     87   virtual ~Empty() {}
     88 
     89  protected:
     90   virtual void Create(uint8_t* packet, size_t* length, size_t max_length) const;
     91 };
     92 
     93 // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
     94 //
     95 // RTCP report block (RFC 3550).
     96 //
     97 //   0                   1                   2                   3
     98 //   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
     99 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    100 //  |                 SSRC_1 (SSRC of first source)                 |
    101 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    102 //  | fraction lost |       cumulative number of packets lost       |
    103 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    104 //  |           extended highest sequence number received           |
    105 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    106 //  |                      interarrival jitter                      |
    107 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    108 //  |                         last SR (LSR)                         |
    109 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    110 //  |                   delay since last SR (DLSR)                  |
    111 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    112 
    113 class ReportBlock {
    114  public:
    115   ReportBlock() {
    116     // TODO(asapersson): Consider adding a constructor to struct.
    117     memset(&report_block_, 0, sizeof(report_block_));
    118   }
    119 
    120   ~ReportBlock() {}
    121 
    122   void To(uint32_t ssrc) {
    123     report_block_.SSRC = ssrc;
    124   }
    125   void WithFractionLost(uint8_t fraction_lost) {
    126     report_block_.FractionLost = fraction_lost;
    127   }
    128   void WithCumulativeLost(uint32_t cumulative_lost) {
    129     report_block_.CumulativeNumOfPacketsLost = cumulative_lost;
    130   }
    131   void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) {
    132     report_block_.ExtendedHighestSequenceNumber = ext_highest_seq_num;
    133   }
    134   void WithJitter(uint32_t jitter) {
    135     report_block_.Jitter = jitter;
    136   }
    137   void WithLastSr(uint32_t last_sr) {
    138     report_block_.LastSR = last_sr;
    139   }
    140   void WithDelayLastSr(uint32_t delay_last_sr) {
    141     report_block_.DelayLastSR = delay_last_sr;
    142   }
    143 
    144  private:
    145   friend class SenderReport;
    146   friend class ReceiverReport;
    147   RTCPUtility::RTCPPacketReportBlockItem report_block_;
    148 };
    149 
    150 // RTCP sender report (RFC 3550).
    151 //
    152 //   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
    153 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    154 //  |V=2|P|    RC   |   PT=SR=200   |             length            |
    155 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    156 //  |                         SSRC of sender                        |
    157 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    158 //  |              NTP timestamp, most significant word             |
    159 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    160 //  |             NTP timestamp, least significant word             |
    161 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    162 //  |                         RTP timestamp                         |
    163 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    164 //  |                     sender's packet count                     |
    165 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    166 //  |                      sender's octet count                     |
    167 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    168 //  |                         report block(s)                       |
    169 //  |                            ....                               |
    170 
    171 class SenderReport : public RtcpPacket {
    172  public:
    173   SenderReport() : RtcpPacket() {
    174     memset(&sr_, 0, sizeof(sr_));
    175   }
    176 
    177   virtual ~SenderReport() {}
    178 
    179   void From(uint32_t ssrc) {
    180     sr_.SenderSSRC = ssrc;
    181   }
    182   void WithNtpSec(uint32_t sec) {
    183     sr_.NTPMostSignificant = sec;
    184   }
    185   void WithNtpFrac(uint32_t frac) {
    186     sr_.NTPLeastSignificant = frac;
    187   }
    188   void WithRtpTimestamp(uint32_t rtp_timestamp) {
    189     sr_.RTPTimestamp = rtp_timestamp;
    190   }
    191   void WithPacketCount(uint32_t packet_count) {
    192     sr_.SenderPacketCount = packet_count;
    193   }
    194   void WithOctetCount(uint32_t octet_count) {
    195     sr_.SenderOctetCount = octet_count;
    196   }
    197   void WithReportBlock(ReportBlock* block);
    198 
    199  protected:
    200   virtual void Create(
    201       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    202 
    203  private:
    204   enum { kMaxNumberOfReportBlocks = 0x1f };
    205 
    206   size_t BlockLength() const {
    207     const size_t kSrHeaderLength = 8;
    208     const size_t kSenderInfoLength = 20;
    209     return kSrHeaderLength + kSenderInfoLength +
    210            report_blocks_.size() * kReportBlockLength;
    211   }
    212 
    213   RTCPUtility::RTCPPacketSR sr_;
    214   std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
    215 };
    216 
    217 //
    218 // RTCP receiver report (RFC 3550).
    219 //
    220 //   0                   1                   2                   3
    221 //   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
    222 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    223 //  |V=2|P|    RC   |   PT=RR=201   |             length            |
    224 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    225 //  |                     SSRC of packet sender                     |
    226 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    227 //  |                         report block(s)                       |
    228 //  |                            ....                               |
    229 
    230 class ReceiverReport : public RtcpPacket {
    231  public:
    232   ReceiverReport() : RtcpPacket() {
    233     memset(&rr_, 0, sizeof(rr_));
    234   }
    235 
    236   virtual ~ReceiverReport() {}
    237 
    238   void From(uint32_t ssrc) {
    239     rr_.SenderSSRC = ssrc;
    240   }
    241   void WithReportBlock(ReportBlock* block);
    242 
    243  protected:
    244   virtual void Create(
    245       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    246 
    247  private:
    248   enum { kMaxNumberOfReportBlocks = 0x1f };
    249 
    250   size_t BlockLength() const {
    251     const size_t kRrHeaderLength = 8;
    252     return kRrHeaderLength + report_blocks_.size() * kReportBlockLength;
    253   }
    254 
    255   RTCPUtility::RTCPPacketRR rr_;
    256   std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
    257 };
    258 
    259 // Transmission Time Offsets in RTP Streams (RFC 5450).
    260 //
    261 //      0                   1                   2                   3
    262 //      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
    263 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    264 // hdr |V=2|P|    RC   |   PT=IJ=195   |             length            |
    265 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    266 //     |                      inter-arrival jitter                     |
    267 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    268 //     .                                                               .
    269 //     .                                                               .
    270 //     .                                                               .
    271 //     |                      inter-arrival jitter                     |
    272 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    273 //
    274 //  If present, this RTCP packet must be placed after a receiver report
    275 //  (inside a compound RTCP packet), and MUST have the same value for RC
    276 //  (reception report count) as the receiver report.
    277 
    278 class Ij : public RtcpPacket {
    279  public:
    280   Ij() : RtcpPacket() {}
    281 
    282   virtual ~Ij() {}
    283 
    284   void WithJitterItem(uint32_t jitter);
    285 
    286  protected:
    287   virtual void Create(
    288       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    289 
    290  private:
    291   enum { kMaxNumberOfIjItems = 0x1f };
    292 
    293   size_t BlockLength() const {
    294     return kHeaderLength + 4 * ij_items_.size();
    295   }
    296 
    297   std::vector<uint32_t> ij_items_;
    298 
    299   DISALLOW_COPY_AND_ASSIGN(Ij);
    300 };
    301 
    302 // Source Description (SDES) (RFC 3550).
    303 //
    304 //         0                   1                   2                   3
    305 //         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
    306 //        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    307 // header |V=2|P|    SC   |  PT=SDES=202  |             length            |
    308 //        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    309 // chunk  |                          SSRC/CSRC_1                          |
    310 //   1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    311 //        |                           SDES items                          |
    312 //        |                              ...                              |
    313 //        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    314 // chunk  |                          SSRC/CSRC_2                          |
    315 //   2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    316 //        |                           SDES items                          |
    317 //        |                              ...                              |
    318 //        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    319 //
    320 // Canonical End-Point Identifier SDES Item (CNAME)
    321 //
    322 //    0                   1                   2                   3
    323 //    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
    324 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    325 //   |    CNAME=1    |     length    | user and domain name        ...
    326 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    327 
    328 class Sdes : public RtcpPacket {
    329  public:
    330   Sdes() : RtcpPacket() {}
    331 
    332   virtual ~Sdes() {}
    333 
    334   void WithCName(uint32_t ssrc, std::string cname);
    335 
    336   struct Chunk {
    337     uint32_t ssrc;
    338     std::string name;
    339     int null_octets;
    340   };
    341 
    342  protected:
    343   virtual void Create(
    344       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    345 
    346  private:
    347   enum { kMaxNumberOfChunks = 0x1f };
    348 
    349   size_t BlockLength() const;
    350 
    351   std::vector<Chunk> chunks_;
    352 
    353   DISALLOW_COPY_AND_ASSIGN(Sdes);
    354 };
    355 
    356 //
    357 // Bye packet (BYE) (RFC 3550).
    358 //
    359 //        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
    360 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    361 //       |V=2|P|    SC   |   PT=BYE=203  |             length            |
    362 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    363 //       |                           SSRC/CSRC                           |
    364 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    365 //       :                              ...                              :
    366 //       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    367 // (opt) |     length    |               reason for leaving            ...
    368 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    369 
    370 class Bye : public RtcpPacket {
    371  public:
    372   Bye() : RtcpPacket() {
    373     memset(&bye_, 0, sizeof(bye_));
    374   }
    375 
    376   virtual ~Bye() {}
    377 
    378   void From(uint32_t ssrc) {
    379     bye_.SenderSSRC = ssrc;
    380   }
    381   void WithCsrc(uint32_t csrc);
    382 
    383  protected:
    384   virtual void Create(
    385       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    386 
    387  private:
    388   enum { kMaxNumberOfCsrcs = 0x1f - 1 };
    389 
    390   size_t BlockLength() const {
    391     size_t source_count = 1 + csrcs_.size();
    392     return kHeaderLength + 4 * source_count;
    393   }
    394 
    395   RTCPUtility::RTCPPacketBYE bye_;
    396   std::vector<uint32_t> csrcs_;
    397 };
    398 
    399 // Application-Defined packet (APP) (RFC 3550).
    400 //
    401 //   0                   1                   2                   3
    402 //   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
    403 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    404 //  |V=2|P| subtype |   PT=APP=204  |             length            |
    405 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    406 //  |                           SSRC/CSRC                           |
    407 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    408 //  |                          name (ASCII)                         |
    409 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    410 //  |                   application-dependent data                ...
    411 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    412 
    413 class App : public RtcpPacket {
    414  public:
    415   App()
    416       : RtcpPacket(),
    417         ssrc_(0) {
    418     memset(&app_, 0, sizeof(app_));
    419   }
    420 
    421   virtual ~App() {}
    422 
    423   void From(uint32_t ssrc) {
    424     ssrc_ = ssrc;
    425   }
    426   void WithSubType(uint8_t subtype) {
    427     assert(subtype <= 0x1f);
    428     app_.SubType = subtype;
    429   }
    430   void WithName(uint32_t name) {
    431     app_.Name = name;
    432   }
    433   void WithData(const uint8_t* data, uint16_t data_length) {
    434     assert(data);
    435     assert(data_length <= kRtcpAppCode_DATA_SIZE);
    436     assert(data_length % 4 == 0);
    437     memcpy(app_.Data, data, data_length);
    438     app_.Size = data_length;
    439   }
    440 
    441  protected:
    442   virtual void Create(
    443       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    444 
    445  private:
    446   size_t BlockLength() const {
    447     return 12 + app_.Size;
    448   }
    449 
    450   uint32_t ssrc_;
    451   RTCPUtility::RTCPPacketAPP app_;
    452 
    453   DISALLOW_COPY_AND_ASSIGN(App);
    454 };
    455 
    456 // RFC 4585: Feedback format.
    457 //
    458 // Common packet format:
    459 //
    460 //    0                   1                   2                   3
    461 //    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
    462 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    463 //   |V=2|P|   FMT   |       PT      |          length               |
    464 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    465 //   |                  SSRC of packet sender                        |
    466 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    467 //   |                  SSRC of media source                         |
    468 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    469 //   :            Feedback Control Information (FCI)                 :
    470 //   :
    471 
    472 // Picture loss indication (PLI) (RFC 4585).
    473 //
    474 // FCI: no feedback control information.
    475 
    476 class Pli : public RtcpPacket {
    477  public:
    478   Pli() : RtcpPacket() {
    479     memset(&pli_, 0, sizeof(pli_));
    480   }
    481 
    482   virtual ~Pli() {}
    483 
    484   void From(uint32_t ssrc) {
    485     pli_.SenderSSRC = ssrc;
    486   }
    487   void To(uint32_t ssrc) {
    488     pli_.MediaSSRC = ssrc;
    489   }
    490 
    491  protected:
    492   virtual void Create(
    493       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    494 
    495  private:
    496   size_t BlockLength() const {
    497     return kCommonFbFmtLength;
    498   }
    499 
    500   RTCPUtility::RTCPPacketPSFBPLI pli_;
    501 
    502   DISALLOW_COPY_AND_ASSIGN(Pli);
    503 };
    504 
    505 // Slice loss indication (SLI) (RFC 4585).
    506 //
    507 // FCI:
    508 //    0                   1                   2                   3
    509 //    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
    510 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    511 //   |            First        |        Number           | PictureID |
    512 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    513 
    514 class Sli : public RtcpPacket {
    515  public:
    516   Sli() : RtcpPacket() {
    517     memset(&sli_, 0, sizeof(sli_));
    518     memset(&sli_item_, 0, sizeof(sli_item_));
    519   }
    520 
    521   virtual ~Sli() {}
    522 
    523   void From(uint32_t ssrc) {
    524     sli_.SenderSSRC = ssrc;
    525   }
    526   void To(uint32_t ssrc) {
    527     sli_.MediaSSRC = ssrc;
    528   }
    529   void WithFirstMb(uint16_t first_mb) {
    530     assert(first_mb <= 0x1fff);
    531     sli_item_.FirstMB = first_mb;
    532   }
    533   void WithNumberOfMb(uint16_t number_mb) {
    534     assert(number_mb <= 0x1fff);
    535     sli_item_.NumberOfMB = number_mb;
    536   }
    537   void WithPictureId(uint8_t picture_id) {
    538     assert(picture_id <= 0x3f);
    539     sli_item_.PictureId = picture_id;
    540   }
    541 
    542  protected:
    543   virtual void Create(
    544       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    545 
    546  private:
    547   size_t BlockLength() const {
    548     const size_t kFciLength = 4;
    549     return kCommonFbFmtLength + kFciLength;
    550   }
    551 
    552   RTCPUtility::RTCPPacketPSFBSLI sli_;
    553   RTCPUtility::RTCPPacketPSFBSLIItem sli_item_;
    554 
    555   DISALLOW_COPY_AND_ASSIGN(Sli);
    556 };
    557 
    558 // Generic NACK (RFC 4585).
    559 //
    560 // FCI:
    561 //    0                   1                   2                   3
    562 //    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
    563 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    564 //   |            PID                |             BLP               |
    565 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    566 
    567 class Nack : public RtcpPacket {
    568  public:
    569   Nack() : RtcpPacket() {
    570     memset(&nack_, 0, sizeof(nack_));
    571   }
    572 
    573   virtual ~Nack() {}
    574 
    575   void From(uint32_t ssrc) {
    576     nack_.SenderSSRC = ssrc;
    577   }
    578   void To(uint32_t ssrc) {
    579     nack_.MediaSSRC = ssrc;
    580   }
    581   void WithList(const uint16_t* nack_list, int length);
    582 
    583  protected:
    584   virtual void Create(
    585       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    586 
    587  private:
    588   size_t BlockLength() const {
    589     size_t fci_length = 4 * nack_fields_.size();
    590     return kCommonFbFmtLength + fci_length;
    591   }
    592 
    593   RTCPUtility::RTCPPacketRTPFBNACK nack_;
    594   std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_;
    595 
    596   DISALLOW_COPY_AND_ASSIGN(Nack);
    597 };
    598 
    599 // Reference picture selection indication (RPSI) (RFC 4585).
    600 //
    601 // FCI:
    602 //
    603 //    0                   1                   2                   3
    604 //    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
    605 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    606 //   |      PB       |0| Payload Type|    Native RPSI bit string     |
    607 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    608 //   |   defined per codec          ...                | Padding (0) |
    609 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    610 
    611 class Rpsi : public RtcpPacket {
    612  public:
    613   Rpsi()
    614       : RtcpPacket(),
    615         padding_bytes_(0) {
    616     memset(&rpsi_, 0, sizeof(rpsi_));
    617   }
    618 
    619   virtual ~Rpsi() {}
    620 
    621   void From(uint32_t ssrc) {
    622     rpsi_.SenderSSRC = ssrc;
    623   }
    624   void To(uint32_t ssrc) {
    625     rpsi_.MediaSSRC = ssrc;
    626   }
    627   void WithPayloadType(uint8_t payload) {
    628     assert(payload <= 0x7f);
    629     rpsi_.PayloadType = payload;
    630   }
    631   void WithPictureId(uint64_t picture_id);
    632 
    633  protected:
    634   virtual void Create(
    635       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    636 
    637  private:
    638   size_t BlockLength() const {
    639     size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_;
    640     return kCommonFbFmtLength + fci_length;
    641   }
    642 
    643   uint8_t padding_bytes_;
    644   RTCPUtility::RTCPPacketPSFBRPSI rpsi_;
    645 
    646   DISALLOW_COPY_AND_ASSIGN(Rpsi);
    647 };
    648 
    649 // Full intra request (FIR) (RFC 5104).
    650 //
    651 // FCI:
    652 //
    653 //    0                   1                   2                   3
    654 //    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
    655 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    656 //   |                              SSRC                             |
    657 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    658 //   | Seq nr.       |    Reserved                                   |
    659 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    660 
    661 class Fir : public RtcpPacket {
    662  public:
    663   Fir()
    664       : RtcpPacket() {
    665     memset(&fir_, 0, sizeof(fir_));
    666     memset(&fir_item_, 0, sizeof(fir_item_));
    667   }
    668 
    669   virtual ~Fir() {}
    670 
    671   void From(uint32_t ssrc) {
    672     fir_.SenderSSRC = ssrc;
    673   }
    674   void To(uint32_t ssrc) {
    675     fir_item_.SSRC = ssrc;
    676   }
    677   void WithCommandSeqNum(uint8_t seq_num) {
    678     fir_item_.CommandSequenceNumber = seq_num;
    679   }
    680 
    681  protected:
    682   virtual void Create(
    683       uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
    684 
    685  private:
    686   size_t BlockLength() const {
    687     const size_t kFciLength = 8;
    688     return kCommonFbFmtLength + kFciLength;
    689   }
    690 
    691   RTCPUtility::RTCPPacketPSFBFIR fir_;
    692   RTCPUtility::RTCPPacketPSFBFIRItem fir_item_;
    693 };
    694 
    695 // Class holding a RTCP packet.
    696 //
    697 // Takes a built rtcp packet.
    698 //  RawPacket raw_packet(buffer, length);
    699 //
    700 // To access the raw packet:
    701 //  raw_packet.buffer();         - pointer to the raw packet
    702 //  raw_packet.buffer_length();  - the length of the raw packet
    703 
    704 class RawPacket {
    705  public:
    706   RawPacket(const uint8_t* packet, size_t length) {
    707     assert(length <= IP_PACKET_SIZE);
    708     memcpy(buffer_, packet, length);
    709     buffer_length_ = length;
    710   }
    711 
    712   const uint8_t* buffer() {
    713     return buffer_;
    714   }
    715   size_t buffer_length() const {
    716     return buffer_length_;
    717   }
    718 
    719  private:
    720   size_t buffer_length_;
    721   uint8_t buffer_[IP_PACKET_SIZE];
    722 };
    723 
    724 }  // namespace rtcp
    725 }  // namespace webrtc
    726 #endif  // WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_
    727