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
16using webrtc::RTCPUtility::kBtDlrr;
17using webrtc::RTCPUtility::kBtReceiverReferenceTime;
18using webrtc::RTCPUtility::kBtVoipMetric;
19
20using webrtc::RTCPUtility::PT_APP;
21using webrtc::RTCPUtility::PT_BYE;
22using webrtc::RTCPUtility::PT_IJ;
23using webrtc::RTCPUtility::PT_PSFB;
24using webrtc::RTCPUtility::PT_RR;
25using webrtc::RTCPUtility::PT_RTPFB;
26using webrtc::RTCPUtility::PT_SDES;
27using webrtc::RTCPUtility::PT_SR;
28using webrtc::RTCPUtility::PT_XR;
29
30using webrtc::RTCPUtility::RTCPPacketAPP;
31using webrtc::RTCPUtility::RTCPPacketBYE;
32using webrtc::RTCPUtility::RTCPPacketPSFBAPP;
33using webrtc::RTCPUtility::RTCPPacketPSFBFIR;
34using webrtc::RTCPUtility::RTCPPacketPSFBFIRItem;
35using webrtc::RTCPUtility::RTCPPacketPSFBPLI;
36using webrtc::RTCPUtility::RTCPPacketPSFBREMBItem;
37using webrtc::RTCPUtility::RTCPPacketPSFBRPSI;
38using webrtc::RTCPUtility::RTCPPacketPSFBSLI;
39using webrtc::RTCPUtility::RTCPPacketPSFBSLIItem;
40using webrtc::RTCPUtility::RTCPPacketReportBlockItem;
41using webrtc::RTCPUtility::RTCPPacketRR;
42using webrtc::RTCPUtility::RTCPPacketRTPFBNACK;
43using webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem;
44using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBN;
45using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBNItem;
46using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBR;
47using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBRItem;
48using webrtc::RTCPUtility::RTCPPacketSR;
49using webrtc::RTCPUtility::RTCPPacketXRDLRRReportBlockItem;
50using webrtc::RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem;
51using webrtc::RTCPUtility::RTCPPacketXR;
52using webrtc::RTCPUtility::RTCPPacketXRVOIPMetricItem;
53
54namespace webrtc {
55namespace rtcp {
56namespace {
57// Unused SSRC of media source, set to 0.
58const uint32_t kUnusedMediaSourceSsrc0 = 0;
59
60void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) {
61  buffer[(*offset)++] = value;
62}
63void AssignUWord16(uint8_t* buffer, size_t* offset, uint16_t value) {
64  RtpUtility::AssignUWord16ToBuffer(buffer + *offset, value);
65  *offset += 2;
66}
67void AssignUWord24(uint8_t* buffer, size_t* offset, uint32_t value) {
68  RtpUtility::AssignUWord24ToBuffer(buffer + *offset, value);
69  *offset += 3;
70}
71void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) {
72  RtpUtility::AssignUWord32ToBuffer(buffer + *offset, value);
73  *offset += 4;
74}
75
76void 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
94size_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
110void 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
141void 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
163void 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
188void 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
218void 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
255void 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
286void 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
313void 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
346void 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
366void 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
393void 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
421void 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
452void 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
466void 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
494void 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
518void 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
551void 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
591void 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
599void 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
620void 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
649void 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
692void 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
725void RtcpPacket::Append(RtcpPacket* packet) {
726  assert(packet);
727  appended_packets_.push_back(packet);
728}
729
730RawPacket 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
737void 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
744void 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
754void Empty::Create(uint8_t* packet, size_t* length, size_t max_length) const {
755}
756
757void 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
768void 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
778void 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
789void 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
799void 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
807void 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
815void 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
824void 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
841size_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
854void 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
862void 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
870void 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
878void 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
886void 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
895void 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
905void 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
929void 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
939void 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
966void 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
975void 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
984void 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
992void 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
1001void 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
1014void 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
1023void 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
1035void 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
1044void 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
1053void 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
1062size_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
1075void 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