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_SOURCE_RTCP_PACKET_H_
     13 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_
     14 
     15 #include <map>
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "webrtc/base/scoped_ptr.h"
     20 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     21 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
     22 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h"
     23 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.h"
     24 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.h"
     25 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
     26 #include "webrtc/typedefs.h"
     27 
     28 namespace webrtc {
     29 namespace rtcp {
     30 
     31 static const int kCommonFbFmtLength = 12;
     32 static const int kReportBlockLength = 24;
     33 
     34 class RawPacket;
     35 
     36 // Class for building RTCP packets.
     37 //
     38 //  Example:
     39 //  ReportBlock report_block;
     40 //  report_block.To(234)
     41 //  report_block.FractionLost(10);
     42 //
     43 //  ReceiverReport rr;
     44 //  rr.From(123);
     45 //  rr.WithReportBlock(&report_block)
     46 //
     47 //  Fir fir;
     48 //  fir.From(123);
     49 //  fir.To(234)
     50 //  fir.WithCommandSeqNum(123);
     51 //
     52 //  size_t length = 0;                     // Builds an intra frame request
     53 //  uint8_t packet[kPacketSize];           // with sequence number 123.
     54 //  fir.Build(packet, &length, kPacketSize);
     55 //
     56 //  RawPacket packet = fir.Build();        // Returns a RawPacket holding
     57 //                                         // the built rtcp packet.
     58 //
     59 //  rr.Append(&fir)                        // Builds a compound RTCP packet with
     60 //  RawPacket packet = rr.Build();         // a receiver report, report block
     61 //                                         // and fir message.
     62 
     63 class RtcpPacket {
     64  public:
     65   virtual ~RtcpPacket() {}
     66 
     67   void Append(RtcpPacket* packet);
     68 
     69   // Callback used to signal that an RTCP packet is ready. Note that this may
     70   // not contain all data in this RtcpPacket; if a packet cannot fit in
     71   // max_length bytes, it will be fragmented and multiple calls to this
     72   // callback will be made.
     73   class PacketReadyCallback {
     74    public:
     75     PacketReadyCallback() {}
     76     virtual ~PacketReadyCallback() {}
     77 
     78     virtual void OnPacketReady(uint8_t* data, size_t length) = 0;
     79   };
     80 
     81   // Convenience method mostly used for test. Max length of IP_PACKET_SIZE is
     82   // used, will cause assertion error if fragmentation occurs.
     83   rtc::scoped_ptr<RawPacket> Build() const;
     84 
     85   // Returns true if all calls to Create succeeded. A buffer of size
     86   // IP_PACKET_SIZE will be allocated and reused between calls to callback.
     87   bool Build(PacketReadyCallback* callback) const;
     88 
     89   // Returns true if all calls to Create succeeded. Provided buffer reference
     90   // will be used for all calls to callback.
     91   bool BuildExternalBuffer(uint8_t* buffer,
     92                            size_t max_length,
     93                            PacketReadyCallback* callback) const;
     94 
     95   // Size of this packet in bytes (including headers, excluding nested packets).
     96   virtual size_t BlockLength() const = 0;
     97 
     98  protected:
     99   RtcpPacket() {}
    100 
    101   virtual bool Create(uint8_t* packet,
    102                       size_t* index,
    103                       size_t max_length,
    104                       PacketReadyCallback* callback) const = 0;
    105 
    106   static void CreateHeader(uint8_t count_or_format,
    107                            uint8_t packet_type,
    108                            size_t block_length,  // Size in 32bit words - 1.
    109                            uint8_t* buffer,
    110                            size_t* pos);
    111 
    112   bool OnBufferFull(uint8_t* packet,
    113                     size_t* index,
    114                     RtcpPacket::PacketReadyCallback* callback) const;
    115 
    116   size_t HeaderLength() const;
    117 
    118   static const size_t kHeaderLength = 4;
    119   std::vector<RtcpPacket*> appended_packets_;
    120 
    121  private:
    122   bool CreateAndAddAppended(uint8_t* packet,
    123                             size_t* index,
    124                             size_t max_length,
    125                             PacketReadyCallback* callback) const;
    126 };
    127 
    128 // TODO(sprang): Move RtcpPacket subclasses out to separate files.
    129 
    130 // RTCP sender report (RFC 3550).
    131 //
    132 //   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
    133 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    134 //  |V=2|P|    RC   |   PT=SR=200   |             length            |
    135 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    136 //  |                         SSRC of sender                        |
    137 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    138 //  |              NTP timestamp, most significant word             |
    139 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    140 //  |             NTP timestamp, least significant word             |
    141 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    142 //  |                         RTP timestamp                         |
    143 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    144 //  |                     sender's packet count                     |
    145 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    146 //  |                      sender's octet count                     |
    147 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    148 //  |                         report block(s)                       |
    149 //  |                            ....                               |
    150 
    151 class SenderReport : public RtcpPacket {
    152  public:
    153   SenderReport() : RtcpPacket() {
    154     memset(&sr_, 0, sizeof(sr_));
    155   }
    156 
    157   virtual ~SenderReport() {}
    158 
    159   void From(uint32_t ssrc) {
    160     sr_.SenderSSRC = ssrc;
    161   }
    162   void WithNtpSec(uint32_t sec) {
    163     sr_.NTPMostSignificant = sec;
    164   }
    165   void WithNtpFrac(uint32_t frac) {
    166     sr_.NTPLeastSignificant = frac;
    167   }
    168   void WithRtpTimestamp(uint32_t rtp_timestamp) {
    169     sr_.RTPTimestamp = rtp_timestamp;
    170   }
    171   void WithPacketCount(uint32_t packet_count) {
    172     sr_.SenderPacketCount = packet_count;
    173   }
    174   void WithOctetCount(uint32_t octet_count) {
    175     sr_.SenderOctetCount = octet_count;
    176   }
    177   bool WithReportBlock(const ReportBlock& block);
    178 
    179  protected:
    180   bool Create(uint8_t* packet,
    181               size_t* index,
    182               size_t max_length,
    183               RtcpPacket::PacketReadyCallback* callback) const override;
    184 
    185  private:
    186   static const int kMaxNumberOfReportBlocks = 0x1f;
    187 
    188   size_t BlockLength() const {
    189     const size_t kSrHeaderLength = 8;
    190     const size_t kSenderInfoLength = 20;
    191     return kSrHeaderLength + kSenderInfoLength +
    192            report_blocks_.size() * kReportBlockLength;
    193   }
    194 
    195   RTCPUtility::RTCPPacketSR sr_;
    196   std::vector<ReportBlock> report_blocks_;
    197 
    198   RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport);
    199 };
    200 
    201 // Source Description (SDES) (RFC 3550).
    202 //
    203 //         0                   1                   2                   3
    204 //         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
    205 //        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    206 // header |V=2|P|    SC   |  PT=SDES=202  |             length            |
    207 //        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    208 // chunk  |                          SSRC/CSRC_1                          |
    209 //   1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    210 //        |                           SDES items                          |
    211 //        |                              ...                              |
    212 //        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    213 // chunk  |                          SSRC/CSRC_2                          |
    214 //   2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    215 //        |                           SDES items                          |
    216 //        |                              ...                              |
    217 //        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    218 //
    219 // Canonical End-Point Identifier SDES Item (CNAME)
    220 //
    221 //    0                   1                   2                   3
    222 //    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
    223 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    224 //   |    CNAME=1    |     length    | user and domain name        ...
    225 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    226 
    227 class Sdes : public RtcpPacket {
    228  public:
    229   Sdes() : RtcpPacket() {}
    230 
    231   virtual ~Sdes() {}
    232 
    233   bool WithCName(uint32_t ssrc, const std::string& cname);
    234 
    235   struct Chunk {
    236     uint32_t ssrc;
    237     std::string name;
    238     int null_octets;
    239   };
    240 
    241  protected:
    242   bool Create(uint8_t* packet,
    243               size_t* index,
    244               size_t max_length,
    245               RtcpPacket::PacketReadyCallback* callback) const override;
    246 
    247  private:
    248   static const int kMaxNumberOfChunks = 0x1f;
    249 
    250   size_t BlockLength() const;
    251 
    252   std::vector<Chunk> chunks_;
    253 
    254   RTC_DISALLOW_COPY_AND_ASSIGN(Sdes);
    255 };
    256 
    257 // Reference picture selection indication (RPSI) (RFC 4585).
    258 //
    259 // FCI:
    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 //   |      PB       |0| Payload Type|    Native RPSI bit string     |
    265 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    266 //   |   defined per codec          ...                | Padding (0) |
    267 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    268 
    269 class Rpsi : public RtcpPacket {
    270  public:
    271   Rpsi()
    272       : RtcpPacket(),
    273         padding_bytes_(0) {
    274     memset(&rpsi_, 0, sizeof(rpsi_));
    275   }
    276 
    277   virtual ~Rpsi() {}
    278 
    279   void From(uint32_t ssrc) {
    280     rpsi_.SenderSSRC = ssrc;
    281   }
    282   void To(uint32_t ssrc) {
    283     rpsi_.MediaSSRC = ssrc;
    284   }
    285   void WithPayloadType(uint8_t payload) {
    286     assert(payload <= 0x7f);
    287     rpsi_.PayloadType = payload;
    288   }
    289   void WithPictureId(uint64_t picture_id);
    290 
    291  protected:
    292   bool Create(uint8_t* packet,
    293               size_t* index,
    294               size_t max_length,
    295               RtcpPacket::PacketReadyCallback* callback) const override;
    296 
    297  private:
    298   size_t BlockLength() const {
    299     size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_;
    300     return kCommonFbFmtLength + fci_length;
    301   }
    302 
    303   uint8_t padding_bytes_;
    304   RTCPUtility::RTCPPacketPSFBRPSI rpsi_;
    305 
    306   RTC_DISALLOW_COPY_AND_ASSIGN(Rpsi);
    307 };
    308 
    309 // Full intra request (FIR) (RFC 5104).
    310 //
    311 // FCI:
    312 //
    313 //    0                   1                   2                   3
    314 //    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
    315 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    316 //   |                              SSRC                             |
    317 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    318 //   | Seq nr.       |    Reserved                                   |
    319 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    320 
    321 class Fir : public RtcpPacket {
    322  public:
    323   Fir() : RtcpPacket() {
    324     memset(&fir_, 0, sizeof(fir_));
    325     memset(&fir_item_, 0, sizeof(fir_item_));
    326   }
    327 
    328   virtual ~Fir() {}
    329 
    330   void From(uint32_t ssrc) {
    331     fir_.SenderSSRC = ssrc;
    332   }
    333   void To(uint32_t ssrc) {
    334     fir_item_.SSRC = ssrc;
    335   }
    336   void WithCommandSeqNum(uint8_t seq_num) {
    337     fir_item_.CommandSequenceNumber = seq_num;
    338   }
    339 
    340  protected:
    341   bool Create(uint8_t* packet,
    342               size_t* index,
    343               size_t max_length,
    344               RtcpPacket::PacketReadyCallback* callback) const override;
    345 
    346  private:
    347   size_t BlockLength() const {
    348     const size_t kFciLength = 8;
    349     return kCommonFbFmtLength + kFciLength;
    350   }
    351 
    352   RTCPUtility::RTCPPacketPSFBFIR fir_;
    353   RTCPUtility::RTCPPacketPSFBFIRItem fir_item_;
    354 };
    355 
    356 // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
    357 //
    358 //    0                   1                   2                   3
    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| FMT=15  |   PT=206      |             length            |
    362 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    363 //   |                  SSRC of packet sender                        |
    364 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    365 //   |                  SSRC of media source                         |
    366 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    367 //   |  Unique identifier 'R' 'E' 'M' 'B'                            |
    368 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    369 //   |  Num SSRC     | BR Exp    |  BR Mantissa                      |
    370 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    371 //   |   SSRC feedback                                               |
    372 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    373 //   |  ...
    374 
    375 class Remb : public RtcpPacket {
    376  public:
    377   Remb() : RtcpPacket() {
    378     memset(&remb_, 0, sizeof(remb_));
    379     memset(&remb_item_, 0, sizeof(remb_item_));
    380   }
    381 
    382   virtual ~Remb() {}
    383 
    384   void From(uint32_t ssrc) {
    385     remb_.SenderSSRC = ssrc;
    386   }
    387   void AppliesTo(uint32_t ssrc);
    388 
    389   void WithBitrateBps(uint32_t bitrate_bps) {
    390     remb_item_.BitRate = bitrate_bps;
    391   }
    392 
    393  protected:
    394   bool Create(uint8_t* packet,
    395               size_t* index,
    396               size_t max_length,
    397               RtcpPacket::PacketReadyCallback* callback) const override;
    398 
    399  private:
    400   static const int kMaxNumberOfSsrcs = 0xff;
    401 
    402   size_t BlockLength() const {
    403     return (remb_item_.NumberOfSSRCs + 5) * 4;
    404   }
    405 
    406   RTCPUtility::RTCPPacketPSFBAPP remb_;
    407   RTCPUtility::RTCPPacketPSFBREMBItem remb_item_;
    408 
    409   RTC_DISALLOW_COPY_AND_ASSIGN(Remb);
    410 };
    411 
    412 // From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR).
    413 //
    414 // Format for XR packets:
    415 //
    416 //   0                   1                   2                   3
    417 //   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
    418 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    419 //  |V=2|P|reserved |   PT=XR=207   |             length            |
    420 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    421 //  |                              SSRC                             |
    422 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    423 //  :                         report blocks                         :
    424 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    425 
    426 class Xr : public RtcpPacket {
    427  public:
    428   typedef std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> DlrrBlock;
    429   Xr() : RtcpPacket() {
    430     memset(&xr_header_, 0, sizeof(xr_header_));
    431   }
    432 
    433   virtual ~Xr() {}
    434 
    435   void From(uint32_t ssrc) {
    436     xr_header_.OriginatorSSRC = ssrc;
    437   }
    438 
    439   // Max 50 items of each of {Rrtr, Dlrr, VoipMetric} allowed per Xr.
    440   bool WithRrtr(Rrtr* rrtr);
    441   bool WithDlrr(Dlrr* dlrr);
    442   bool WithVoipMetric(VoipMetric* voip_metric);
    443 
    444  protected:
    445   bool Create(uint8_t* packet,
    446               size_t* index,
    447               size_t max_length,
    448               RtcpPacket::PacketReadyCallback* callback) const override;
    449 
    450  private:
    451   static const int kMaxNumberOfRrtrBlocks = 50;
    452   static const int kMaxNumberOfDlrrBlocks = 50;
    453   static const int kMaxNumberOfVoipMetricBlocks = 50;
    454 
    455   size_t BlockLength() const {
    456     const size_t kXrHeaderLength = 8;
    457     return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength();
    458   }
    459 
    460   size_t RrtrLength() const { return Rrtr::kLength * rrtr_blocks_.size(); }
    461 
    462   size_t DlrrLength() const;
    463 
    464   size_t VoipMetricLength() const {
    465     return VoipMetric::kLength * voip_metric_blocks_.size();
    466   }
    467 
    468   RTCPUtility::RTCPPacketXR xr_header_;
    469   std::vector<Rrtr> rrtr_blocks_;
    470   std::vector<Dlrr> dlrr_blocks_;
    471   std::vector<VoipMetric> voip_metric_blocks_;
    472 
    473   RTC_DISALLOW_COPY_AND_ASSIGN(Xr);
    474 };
    475 
    476 // Class holding a RTCP packet.
    477 //
    478 // Takes a built rtcp packet.
    479 //  RawPacket raw_packet(buffer, length);
    480 //
    481 // To access the raw packet:
    482 //  raw_packet.Buffer();         - pointer to the raw packet
    483 //  raw_packet.BufferLength();   - the length of the raw packet
    484 
    485 class RawPacket {
    486  public:
    487   explicit RawPacket(size_t buffer_length);
    488   RawPacket(const uint8_t* packet, size_t packet_length);
    489 
    490   const uint8_t* Buffer() const;
    491   uint8_t* MutableBuffer();
    492   size_t BufferLength() const;
    493   size_t Length() const;
    494   void SetLength(size_t length);
    495 
    496  private:
    497   const size_t buffer_length_;
    498   size_t length_;
    499   rtc::scoped_ptr<uint8_t[]> buffer_;
    500 };
    501 
    502 }  // namespace rtcp
    503 }  // namespace webrtc
    504 #endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_
    505