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