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