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