blob: 1f5e22316dc43823efa05191ea2873a5b669ff23 [file] [log] [blame]
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001/*
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
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +000015#include <map>
16#include <string>
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000017#include <vector>
18
Erik Språngc1b9d4e2015-06-08 09:54:14 +020019#include "webrtc/base/scoped_ptr.h"
danilchapdf948f02015-11-13 03:03:13 -080020#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h"
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000021#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010022#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000023#include "webrtc/typedefs.h"
24
25namespace webrtc {
26namespace rtcp {
27
Erik Språngc1b9d4e2015-06-08 09:54:14 +020028static const int kCommonFbFmtLength = 12;
29static const int kReportBlockLength = 24;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +000030
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +000031class Dlrr;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000032class RawPacket;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +000033class Rrtr;
34class VoipMetric;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000035
36// Class for building RTCP packets.
37//
38// Example:
39// ReportBlock report_block;
40// report_block.To(234)
41// report_block.FractionLost(10);
42//
43// ReceiverReport rr;
44// rr.From(123);
45// rr.WithReportBlock(&report_block)
46//
47// Fir fir;
48// fir.From(123);
49// fir.To(234)
50// fir.WithCommandSeqNum(123);
51//
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +000052// size_t length = 0; // Builds an intra frame request
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000053// uint8_t packet[kPacketSize]; // with sequence number 123.
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +000054// fir.Build(packet, &length, kPacketSize);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000055//
56// RawPacket packet = fir.Build(); // Returns a RawPacket holding
57// // the built rtcp packet.
58//
59// rr.Append(&fir) // Builds a compound RTCP packet with
60// RawPacket packet = rr.Build(); // a receiver report, report block
61// // and fir message.
62
63class RtcpPacket {
64 public:
65 virtual ~RtcpPacket() {}
66
67 void Append(RtcpPacket* packet);
68
Erik Språngc1b9d4e2015-06-08 09:54:14 +020069 // Callback used to signal that an RTCP packet is ready. Note that this may
70 // not contain all data in this RtcpPacket; if a packet cannot fit in
71 // max_length bytes, it will be fragmented and multiple calls to this
72 // callback will be made.
73 class PacketReadyCallback {
74 public:
75 PacketReadyCallback() {}
76 virtual ~PacketReadyCallback() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000077
Erik Språngc1b9d4e2015-06-08 09:54:14 +020078 virtual void OnPacketReady(uint8_t* data, size_t length) = 0;
79 };
80
81 // Convenience method mostly used for test. Max length of IP_PACKET_SIZE is
82 // used, will cause assertion error if fragmentation occurs.
83 rtc::scoped_ptr<RawPacket> Build() const;
84
85 // Returns true if all calls to Create succeeded. A buffer of size
86 // IP_PACKET_SIZE will be allocated and reused between calls to callback.
87 bool Build(PacketReadyCallback* callback) const;
88
89 // Returns true if all calls to Create succeeded. Provided buffer reference
90 // will be used for all calls to callback.
91 bool BuildExternalBuffer(uint8_t* buffer,
92 size_t max_length,
93 PacketReadyCallback* callback) const;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000094
Erik Språng6b8d3552015-09-24 15:06:57 +020095 // Size of this packet in bytes (including headers, excluding nested packets).
96 virtual size_t BlockLength() const = 0;
97
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000098 protected:
Erik Språnga3b87692015-07-29 10:46:54 +020099 RtcpPacket() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000100
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200101 virtual bool Create(uint8_t* packet,
102 size_t* index,
103 size_t max_length,
104 PacketReadyCallback* callback) const = 0;
105
sprang73a93e82015-09-14 12:50:39 -0700106 static void CreateHeader(uint8_t count_or_format,
107 uint8_t packet_type,
108 size_t block_length, // Size in 32bit words - 1.
109 uint8_t* buffer,
110 size_t* pos);
Erik Språnga3b87692015-07-29 10:46:54 +0200111
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200112 bool OnBufferFull(uint8_t* packet,
113 size_t* index,
114 RtcpPacket::PacketReadyCallback* callback) const;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000115
Erik Språnga3b87692015-07-29 10:46:54 +0200116 size_t HeaderLength() const;
117
118 static const size_t kHeaderLength = 4;
Erik Språngf7c57762015-12-04 10:40:35 +0100119 std::vector<RtcpPacket*> appended_packets_;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000120
121 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200122 bool CreateAndAddAppended(uint8_t* packet,
123 size_t* index,
124 size_t max_length,
125 PacketReadyCallback* callback) const;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000126};
127
Erik Språnga3b87692015-07-29 10:46:54 +0200128// TODO(sprang): Move RtcpPacket subclasses out to separate files.
129
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000130class Empty : public RtcpPacket {
131 public:
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000132 Empty() : RtcpPacket() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000133
134 virtual ~Empty() {}
135
136 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200137 bool Create(uint8_t* packet,
138 size_t* index,
139 size_t max_length,
140 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000141
Erik Språnga3b87692015-07-29 10:46:54 +0200142 size_t BlockLength() const override;
143
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000144 private:
henrikg3c089d72015-09-16 05:37:44 -0700145 RTC_DISALLOW_COPY_AND_ASSIGN(Empty);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000146};
147
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000148// RTCP sender report (RFC 3550).
149//
150// 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
151// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
152// |V=2|P| RC | PT=SR=200 | length |
153// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
154// | SSRC of sender |
155// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
156// | NTP timestamp, most significant word |
157// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158// | NTP timestamp, least significant word |
159// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
160// | RTP timestamp |
161// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
162// | sender's packet count |
163// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
164// | sender's octet count |
165// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
166// | report block(s) |
167// | .... |
168
169class SenderReport : public RtcpPacket {
170 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000171 SenderReport() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000172 memset(&sr_, 0, sizeof(sr_));
173 }
174
175 virtual ~SenderReport() {}
176
177 void From(uint32_t ssrc) {
178 sr_.SenderSSRC = ssrc;
179 }
180 void WithNtpSec(uint32_t sec) {
181 sr_.NTPMostSignificant = sec;
182 }
183 void WithNtpFrac(uint32_t frac) {
184 sr_.NTPLeastSignificant = frac;
185 }
186 void WithRtpTimestamp(uint32_t rtp_timestamp) {
187 sr_.RTPTimestamp = rtp_timestamp;
188 }
189 void WithPacketCount(uint32_t packet_count) {
190 sr_.SenderPacketCount = packet_count;
191 }
192 void WithOctetCount(uint32_t octet_count) {
193 sr_.SenderOctetCount = octet_count;
194 }
Erik Språngbdc0b0d2015-06-22 15:21:24 +0200195 bool WithReportBlock(const ReportBlock& block);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000196
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000197 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200198 bool Create(uint8_t* packet,
199 size_t* index,
200 size_t max_length,
201 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000202
203 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200204 static const int kMaxNumberOfReportBlocks = 0x1f;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000205
206 size_t BlockLength() const {
207 const size_t kSrHeaderLength = 8;
208 const size_t kSenderInfoLength = 20;
209 return kSrHeaderLength + kSenderInfoLength +
210 report_blocks_.size() * kReportBlockLength;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000211 }
212
213 RTCPUtility::RTCPPacketSR sr_;
danilchapdf948f02015-11-13 03:03:13 -0800214 std::vector<ReportBlock> report_blocks_;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000215
henrikg3c089d72015-09-16 05:37:44 -0700216 RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000217};
218
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000219// Source Description (SDES) (RFC 3550).
220//
221// 0 1 2 3
222// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
223// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
224// header |V=2|P| SC | PT=SDES=202 | length |
225// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
226// chunk | SSRC/CSRC_1 |
227// 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
228// | SDES items |
229// | ... |
230// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
231// chunk | SSRC/CSRC_2 |
232// 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
233// | SDES items |
234// | ... |
235// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
236//
237// Canonical End-Point Identifier SDES Item (CNAME)
238//
239// 0 1 2 3
240// 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
241// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
242// | CNAME=1 | length | user and domain name ...
243// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
244
245class Sdes : public RtcpPacket {
246 public:
247 Sdes() : RtcpPacket() {}
248
249 virtual ~Sdes() {}
250
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200251 bool WithCName(uint32_t ssrc, const std::string& cname);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000252
253 struct Chunk {
254 uint32_t ssrc;
255 std::string name;
256 int null_octets;
257 };
258
259 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200260 bool Create(uint8_t* packet,
261 size_t* index,
262 size_t max_length,
263 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000264
265 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200266 static const int kMaxNumberOfChunks = 0x1f;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000267
268 size_t BlockLength() const;
269
270 std::vector<Chunk> chunks_;
271
henrikg3c089d72015-09-16 05:37:44 -0700272 RTC_DISALLOW_COPY_AND_ASSIGN(Sdes);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000273};
274
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000275// Slice loss indication (SLI) (RFC 4585).
276//
277// FCI:
278// 0 1 2 3
279// 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
280// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
281// | First | Number | PictureID |
282// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
283
284class Sli : public RtcpPacket {
285 public:
286 Sli() : RtcpPacket() {
287 memset(&sli_, 0, sizeof(sli_));
288 memset(&sli_item_, 0, sizeof(sli_item_));
289 }
290
291 virtual ~Sli() {}
292
293 void From(uint32_t ssrc) {
294 sli_.SenderSSRC = ssrc;
295 }
296 void To(uint32_t ssrc) {
297 sli_.MediaSSRC = ssrc;
298 }
299 void WithFirstMb(uint16_t first_mb) {
300 assert(first_mb <= 0x1fff);
301 sli_item_.FirstMB = first_mb;
302 }
303 void WithNumberOfMb(uint16_t number_mb) {
304 assert(number_mb <= 0x1fff);
305 sli_item_.NumberOfMB = number_mb;
306 }
307 void WithPictureId(uint8_t picture_id) {
308 assert(picture_id <= 0x3f);
309 sli_item_.PictureId = picture_id;
310 }
311
312 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200313 bool Create(uint8_t* packet,
314 size_t* index,
315 size_t max_length,
316 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000317
318 private:
319 size_t BlockLength() const {
320 const size_t kFciLength = 4;
321 return kCommonFbFmtLength + kFciLength;
322 }
323
324 RTCPUtility::RTCPPacketPSFBSLI sli_;
325 RTCPUtility::RTCPPacketPSFBSLIItem sli_item_;
326
henrikg3c089d72015-09-16 05:37:44 -0700327 RTC_DISALLOW_COPY_AND_ASSIGN(Sli);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000328};
329
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000330// Generic NACK (RFC 4585).
331//
332// FCI:
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// | PID | BLP |
337// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
338
339class Nack : public RtcpPacket {
340 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000341 Nack() : RtcpPacket() {
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000342 memset(&nack_, 0, sizeof(nack_));
343 }
344
345 virtual ~Nack() {}
346
347 void From(uint32_t ssrc) {
348 nack_.SenderSSRC = ssrc;
349 }
350 void To(uint32_t ssrc) {
351 nack_.MediaSSRC = ssrc;
352 }
353 void WithList(const uint16_t* nack_list, int length);
354
355 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200356 bool Create(uint8_t* packet,
357 size_t* index,
358 size_t max_length,
359 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000360
Erik Språnga3b87692015-07-29 10:46:54 +0200361 size_t BlockLength() const override;
362
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000363 private:
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000364
365 RTCPUtility::RTCPPacketRTPFBNACK nack_;
366 std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_;
367
henrikg3c089d72015-09-16 05:37:44 -0700368 RTC_DISALLOW_COPY_AND_ASSIGN(Nack);
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000369};
370
371// Reference picture selection indication (RPSI) (RFC 4585).
372//
373// FCI:
374//
375// 0 1 2 3
376// 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
377// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
378// | PB |0| Payload Type| Native RPSI bit string |
379// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
380// | defined per codec ... | Padding (0) |
381// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
382
383class Rpsi : public RtcpPacket {
384 public:
385 Rpsi()
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000386 : RtcpPacket(),
387 padding_bytes_(0) {
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000388 memset(&rpsi_, 0, sizeof(rpsi_));
389 }
390
391 virtual ~Rpsi() {}
392
393 void From(uint32_t ssrc) {
394 rpsi_.SenderSSRC = ssrc;
395 }
396 void To(uint32_t ssrc) {
397 rpsi_.MediaSSRC = ssrc;
398 }
399 void WithPayloadType(uint8_t payload) {
400 assert(payload <= 0x7f);
401 rpsi_.PayloadType = payload;
402 }
403 void WithPictureId(uint64_t picture_id);
404
405 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200406 bool Create(uint8_t* packet,
407 size_t* index,
408 size_t max_length,
409 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000410
411 private:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000412 size_t BlockLength() const {
413 size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_;
414 return kCommonFbFmtLength + fci_length;
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000415 }
416
417 uint8_t padding_bytes_;
418 RTCPUtility::RTCPPacketPSFBRPSI rpsi_;
419
henrikg3c089d72015-09-16 05:37:44 -0700420 RTC_DISALLOW_COPY_AND_ASSIGN(Rpsi);
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000421};
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000422
423// Full intra request (FIR) (RFC 5104).
424//
425// FCI:
426//
427// 0 1 2 3
428// 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
429// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
430// | SSRC |
431// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
432// | Seq nr. | Reserved |
433// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
434
435class Fir : public RtcpPacket {
436 public:
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000437 Fir() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000438 memset(&fir_, 0, sizeof(fir_));
439 memset(&fir_item_, 0, sizeof(fir_item_));
440 }
441
442 virtual ~Fir() {}
443
444 void From(uint32_t ssrc) {
445 fir_.SenderSSRC = ssrc;
446 }
447 void To(uint32_t ssrc) {
448 fir_item_.SSRC = ssrc;
449 }
450 void WithCommandSeqNum(uint8_t seq_num) {
451 fir_item_.CommandSequenceNumber = seq_num;
452 }
453
454 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200455 bool Create(uint8_t* packet,
456 size_t* index,
457 size_t max_length,
458 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000459
460 private:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000461 size_t BlockLength() const {
462 const size_t kFciLength = 8;
463 return kCommonFbFmtLength + kFciLength;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000464 }
465
466 RTCPUtility::RTCPPacketPSFBFIR fir_;
467 RTCPUtility::RTCPPacketPSFBFIRItem fir_item_;
468};
469
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000470// Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104).
471//
472// FCI:
473//
474// 0 1 2 3
475// 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
476// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
477// | SSRC |
478// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
479// | MxTBR Exp | MxTBR Mantissa |Measured Overhead|
480// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
481
482class Tmmbr : public RtcpPacket {
483 public:
484 Tmmbr() : RtcpPacket() {
485 memset(&tmmbr_, 0, sizeof(tmmbr_));
486 memset(&tmmbr_item_, 0, sizeof(tmmbr_item_));
487 }
488
489 virtual ~Tmmbr() {}
490
491 void From(uint32_t ssrc) {
492 tmmbr_.SenderSSRC = ssrc;
493 }
494 void To(uint32_t ssrc) {
495 tmmbr_item_.SSRC = ssrc;
496 }
497 void WithBitrateKbps(uint32_t bitrate_kbps) {
498 tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps;
499 }
500 void WithOverhead(uint16_t overhead) {
501 assert(overhead <= 0x1ff);
502 tmmbr_item_.MeasuredOverhead = overhead;
503 }
504
505 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200506 bool Create(uint8_t* packet,
507 size_t* index,
508 size_t max_length,
509 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000510
511 private:
512 size_t BlockLength() const {
513 const size_t kFciLen = 8;
514 return kCommonFbFmtLength + kFciLen;
515 }
516
517 RTCPUtility::RTCPPacketRTPFBTMMBR tmmbr_;
518 RTCPUtility::RTCPPacketRTPFBTMMBRItem tmmbr_item_;
519
henrikg3c089d72015-09-16 05:37:44 -0700520 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000521};
522
523// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
524//
525// FCI:
526//
527// 0 1 2 3
528// 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
529// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
530// | SSRC |
531// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
532// | MxTBR Exp | MxTBR Mantissa |Measured Overhead|
533// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
534
535class Tmmbn : public RtcpPacket {
536 public:
537 Tmmbn() : RtcpPacket() {
538 memset(&tmmbn_, 0, sizeof(tmmbn_));
539 }
540
541 virtual ~Tmmbn() {}
542
543 void From(uint32_t ssrc) {
544 tmmbn_.SenderSSRC = ssrc;
545 }
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200546 // Max 50 TMMBR can be added per TMMBN.
547 bool WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000548
549 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200550 bool Create(uint8_t* packet,
551 size_t* index,
552 size_t max_length,
553 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000554
555 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200556 static const int kMaxNumberOfTmmbrs = 50;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000557
558 size_t BlockLength() const {
559 const size_t kFciLen = 8;
560 return kCommonFbFmtLength + kFciLen * tmmbn_items_.size();
561 }
562
563 RTCPUtility::RTCPPacketRTPFBTMMBN tmmbn_;
564 std::vector<RTCPUtility::RTCPPacketRTPFBTMMBRItem> tmmbn_items_;
565
henrikg3c089d72015-09-16 05:37:44 -0700566 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbn);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000567};
568
569// Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
570//
571// 0 1 2 3
572// 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
573// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
574// |V=2|P| FMT=15 | PT=206 | length |
575// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
576// | SSRC of packet sender |
577// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
578// | SSRC of media source |
579// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
580// | Unique identifier 'R' 'E' 'M' 'B' |
581// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
582// | Num SSRC | BR Exp | BR Mantissa |
583// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
584// | SSRC feedback |
585// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
586// | ...
587
588class Remb : public RtcpPacket {
589 public:
590 Remb() : RtcpPacket() {
591 memset(&remb_, 0, sizeof(remb_));
592 memset(&remb_item_, 0, sizeof(remb_item_));
593 }
594
595 virtual ~Remb() {}
596
597 void From(uint32_t ssrc) {
598 remb_.SenderSSRC = ssrc;
599 }
600 void AppliesTo(uint32_t ssrc);
601
602 void WithBitrateBps(uint32_t bitrate_bps) {
603 remb_item_.BitRate = bitrate_bps;
604 }
605
606 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200607 bool Create(uint8_t* packet,
608 size_t* index,
609 size_t max_length,
610 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000611
612 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200613 static const int kMaxNumberOfSsrcs = 0xff;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000614
615 size_t BlockLength() const {
616 return (remb_item_.NumberOfSSRCs + 5) * 4;
617 }
618
619 RTCPUtility::RTCPPacketPSFBAPP remb_;
620 RTCPUtility::RTCPPacketPSFBREMBItem remb_item_;
621
henrikg3c089d72015-09-16 05:37:44 -0700622 RTC_DISALLOW_COPY_AND_ASSIGN(Remb);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000623};
624
625// From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR).
626//
627// Format for XR packets:
628//
629// 0 1 2 3
630// 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
631// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
632// |V=2|P|reserved | PT=XR=207 | length |
633// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
634// | SSRC |
635// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
636// : report blocks :
637// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
638
639class Xr : public RtcpPacket {
640 public:
641 typedef std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> DlrrBlock;
642 Xr() : RtcpPacket() {
643 memset(&xr_header_, 0, sizeof(xr_header_));
644 }
645
646 virtual ~Xr() {}
647
648 void From(uint32_t ssrc) {
649 xr_header_.OriginatorSSRC = ssrc;
650 }
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200651
652 // Max 50 items of each of {Rrtr, Dlrr, VoipMetric} allowed per Xr.
653 bool WithRrtr(Rrtr* rrtr);
654 bool WithDlrr(Dlrr* dlrr);
655 bool WithVoipMetric(VoipMetric* voip_metric);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000656
657 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200658 bool Create(uint8_t* packet,
659 size_t* index,
660 size_t max_length,
661 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000662
663 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200664 static const int kMaxNumberOfRrtrBlocks = 50;
665 static const int kMaxNumberOfDlrrBlocks = 50;
666 static const int kMaxNumberOfVoipMetricBlocks = 50;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000667
668 size_t BlockLength() const {
669 const size_t kXrHeaderLength = 8;
670 return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength();
671 }
672
673 size_t RrtrLength() const {
674 const size_t kRrtrBlockLength = 12;
675 return kRrtrBlockLength * rrtr_blocks_.size();
676 }
677
678 size_t DlrrLength() const;
679
680 size_t VoipMetricLength() const {
681 const size_t kVoipMetricBlockLength = 36;
682 return kVoipMetricBlockLength * voip_metric_blocks_.size();
683 }
684
685 RTCPUtility::RTCPPacketXR xr_header_;
686 std::vector<RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem> rrtr_blocks_;
687 std::vector<DlrrBlock> dlrr_blocks_;
688 std::vector<RTCPUtility::RTCPPacketXRVOIPMetricItem> voip_metric_blocks_;
689
henrikg3c089d72015-09-16 05:37:44 -0700690 RTC_DISALLOW_COPY_AND_ASSIGN(Xr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000691};
692
693// Receiver Reference Time Report Block (RFC 3611).
694//
695// 0 1 2 3
696// 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
697// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
698// | BT=4 | reserved | block length = 2 |
699// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
700// | NTP timestamp, most significant word |
701// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
702// | NTP timestamp, least significant word |
703// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
704
705class Rrtr {
706 public:
707 Rrtr() {
708 memset(&rrtr_block_, 0, sizeof(rrtr_block_));
709 }
710 ~Rrtr() {}
711
712 void WithNtpSec(uint32_t sec) {
713 rrtr_block_.NTPMostSignificant = sec;
714 }
715 void WithNtpFrac(uint32_t frac) {
716 rrtr_block_.NTPLeastSignificant = frac;
717 }
718
719 private:
720 friend class Xr;
721 RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem rrtr_block_;
722
henrikg3c089d72015-09-16 05:37:44 -0700723 RTC_DISALLOW_COPY_AND_ASSIGN(Rrtr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000724};
725
726// DLRR Report Block (RFC 3611).
727//
728// 0 1 2 3
729// 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
730// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
731// | BT=5 | reserved | block length |
732// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
733// | SSRC_1 (SSRC of first receiver) | sub-
734// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
735// | last RR (LRR) | 1
736// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
737// | delay since last RR (DLRR) |
738// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
739// | SSRC_2 (SSRC of second receiver) | sub-
740// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
741// : ... : 2
742
743class Dlrr {
744 public:
745 Dlrr() {}
746 ~Dlrr() {}
747
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200748 // Max 100 DLRR Items can be added per DLRR report block.
749 bool WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000750
751 private:
752 friend class Xr;
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200753 static const int kMaxNumberOfDlrrItems = 100;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000754
755 std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> dlrr_block_;
756
henrikg3c089d72015-09-16 05:37:44 -0700757 RTC_DISALLOW_COPY_AND_ASSIGN(Dlrr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000758};
759
760// VoIP Metrics Report Block (RFC 3611).
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// | BT=7 | reserved | block length = 8 |
766// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
767// | SSRC of source |
768// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
769// | loss rate | discard rate | burst density | gap density |
770// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
771// | burst duration | gap duration |
772// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
773// | round trip delay | end system delay |
774// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
775// | signal level | noise level | RERL | Gmin |
776// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
777// | R factor | ext. R factor | MOS-LQ | MOS-CQ |
778// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
779// | RX config | reserved | JB nominal |
780// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
781// | JB maximum | JB abs max |
782// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
783
784class VoipMetric {
785 public:
786 VoipMetric() {
787 memset(&metric_, 0, sizeof(metric_));
788 }
789 ~VoipMetric() {}
790
791 void To(uint32_t ssrc) { metric_.SSRC = ssrc; }
792 void LossRate(uint8_t loss_rate) { metric_.lossRate = loss_rate; }
793 void DiscardRate(uint8_t discard_rate) { metric_.discardRate = discard_rate; }
794 void BurstDensity(uint8_t burst_density) {
795 metric_.burstDensity = burst_density;
796 }
797 void GapDensity(uint8_t gap_density) { metric_.gapDensity = gap_density; }
798 void BurstDuration(uint16_t burst_duration) {
799 metric_.burstDuration = burst_duration;
800 }
801 void GapDuration(uint16_t gap_duration) {
802 metric_.gapDuration = gap_duration;
803 }
804 void RoundTripDelay(uint16_t round_trip_delay) {
805 metric_.roundTripDelay = round_trip_delay;
806 }
807 void EndSystemDelay(uint16_t end_system_delay) {
808 metric_.endSystemDelay = end_system_delay;
809 }
810 void SignalLevel(uint8_t signal_level) { metric_.signalLevel = signal_level; }
811 void NoiseLevel(uint8_t noise_level) { metric_.noiseLevel = noise_level; }
812 void Rerl(uint8_t rerl) { metric_.RERL = rerl; }
813 void Gmin(uint8_t gmin) { metric_.Gmin = gmin; }
814 void Rfactor(uint8_t rfactor) { metric_.Rfactor = rfactor; }
815 void ExtRfactor(uint8_t extrfactor) { metric_.extRfactor = extrfactor; }
816 void MosLq(uint8_t moslq) { metric_.MOSLQ = moslq; }
817 void MosCq(uint8_t moscq) { metric_.MOSCQ = moscq; }
818 void RxConfig(uint8_t rxconfig) { metric_.RXconfig = rxconfig; }
819 void JbNominal(uint16_t jbnominal) { metric_.JBnominal = jbnominal; }
820 void JbMax(uint16_t jbmax) { metric_.JBmax = jbmax; }
821 void JbAbsMax(uint16_t jbabsmax) { metric_.JBabsMax = jbabsmax; }
822
823 private:
824 friend class Xr;
825 RTCPUtility::RTCPPacketXRVOIPMetricItem metric_;
826
henrikg3c089d72015-09-16 05:37:44 -0700827 RTC_DISALLOW_COPY_AND_ASSIGN(VoipMetric);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000828};
829
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000830// Class holding a RTCP packet.
831//
832// Takes a built rtcp packet.
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000833// RawPacket raw_packet(buffer, length);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000834//
835// To access the raw packet:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200836// raw_packet.Buffer(); - pointer to the raw packet
837// raw_packet.BufferLength(); - the length of the raw packet
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000838
839class RawPacket {
840 public:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200841 explicit RawPacket(size_t buffer_length);
842 RawPacket(const uint8_t* packet, size_t packet_length);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000843
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200844 const uint8_t* Buffer() const;
845 uint8_t* MutableBuffer();
846 size_t BufferLength() const;
847 size_t Length() const;
848 void SetLength(size_t length);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000849
850 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200851 const size_t buffer_length_;
852 size_t length_;
853 rtc::scoped_ptr<uint8_t[]> buffer_;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000854};
855
856} // namespace rtcp
857} // namespace webrtc
858#endif // WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_