blob: 85aa438b893a217c179e58a74a452e6742c91ba6 [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;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000119
120 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200121 bool CreateAndAddAppended(uint8_t* packet,
122 size_t* index,
123 size_t max_length,
124 PacketReadyCallback* callback) const;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000125
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000126 std::vector<RtcpPacket*> appended_packets_;
127};
128
Erik Språnga3b87692015-07-29 10:46:54 +0200129// TODO(sprang): Move RtcpPacket subclasses out to separate files.
130
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000131class Empty : public RtcpPacket {
132 public:
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000133 Empty() : RtcpPacket() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000134
135 virtual ~Empty() {}
136
137 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200138 bool Create(uint8_t* packet,
139 size_t* index,
140 size_t max_length,
141 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000142
Erik Språnga3b87692015-07-29 10:46:54 +0200143 size_t BlockLength() const override;
144
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000145 private:
henrikg3c089d72015-09-16 05:37:44 -0700146 RTC_DISALLOW_COPY_AND_ASSIGN(Empty);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000147};
148
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000149// RTCP sender report (RFC 3550).
150//
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// |V=2|P| RC | PT=SR=200 | length |
154// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
155// | SSRC of sender |
156// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
157// | NTP timestamp, most significant word |
158// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159// | NTP timestamp, least significant word |
160// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161// | RTP timestamp |
162// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163// | sender's packet count |
164// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165// | sender's octet count |
166// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
167// | report block(s) |
168// | .... |
169
170class SenderReport : public RtcpPacket {
171 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000172 SenderReport() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000173 memset(&sr_, 0, sizeof(sr_));
174 }
175
176 virtual ~SenderReport() {}
177
178 void From(uint32_t ssrc) {
179 sr_.SenderSSRC = ssrc;
180 }
181 void WithNtpSec(uint32_t sec) {
182 sr_.NTPMostSignificant = sec;
183 }
184 void WithNtpFrac(uint32_t frac) {
185 sr_.NTPLeastSignificant = frac;
186 }
187 void WithRtpTimestamp(uint32_t rtp_timestamp) {
188 sr_.RTPTimestamp = rtp_timestamp;
189 }
190 void WithPacketCount(uint32_t packet_count) {
191 sr_.SenderPacketCount = packet_count;
192 }
193 void WithOctetCount(uint32_t octet_count) {
194 sr_.SenderOctetCount = octet_count;
195 }
Erik Språngbdc0b0d2015-06-22 15:21:24 +0200196 bool WithReportBlock(const ReportBlock& block);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000197
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000198 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200199 bool Create(uint8_t* packet,
200 size_t* index,
201 size_t max_length,
202 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000203
204 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200205 static const int kMaxNumberOfReportBlocks = 0x1f;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000206
207 size_t BlockLength() const {
208 const size_t kSrHeaderLength = 8;
209 const size_t kSenderInfoLength = 20;
210 return kSrHeaderLength + kSenderInfoLength +
211 report_blocks_.size() * kReportBlockLength;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000212 }
213
214 RTCPUtility::RTCPPacketSR sr_;
danilchapdf948f02015-11-13 03:03:13 -0800215 std::vector<ReportBlock> report_blocks_;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000216
henrikg3c089d72015-09-16 05:37:44 -0700217 RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000218};
219
220//
221// RTCP receiver report (RFC 3550).
222//
223// 0 1 2 3
224// 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
225// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
226// |V=2|P| RC | PT=RR=201 | length |
227// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
228// | SSRC of packet sender |
229// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
230// | report block(s) |
231// | .... |
232
233class ReceiverReport : public RtcpPacket {
234 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000235 ReceiverReport() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000236 memset(&rr_, 0, sizeof(rr_));
237 }
238
239 virtual ~ReceiverReport() {}
240
241 void From(uint32_t ssrc) {
242 rr_.SenderSSRC = ssrc;
243 }
Erik Språngbdc0b0d2015-06-22 15:21:24 +0200244 bool WithReportBlock(const ReportBlock& block);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000245
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000246 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200247 bool Create(uint8_t* packet,
248 size_t* index,
249 size_t max_length,
250 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000251
252 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200253 static const int kMaxNumberOfReportBlocks = 0x1F;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000254
255 size_t BlockLength() const {
256 const size_t kRrHeaderLength = 8;
257 return kRrHeaderLength + report_blocks_.size() * kReportBlockLength;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000258 }
259
260 RTCPUtility::RTCPPacketRR rr_;
danilchapdf948f02015-11-13 03:03:13 -0800261 std::vector<ReportBlock> report_blocks_;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000262
henrikg3c089d72015-09-16 05:37:44 -0700263 RTC_DISALLOW_COPY_AND_ASSIGN(ReceiverReport);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000264};
265
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000266// Transmission Time Offsets in RTP Streams (RFC 5450).
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000267//
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000268// 0 1 2 3
269// 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
270// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
271// hdr |V=2|P| RC | PT=IJ=195 | length |
272// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
273// | inter-arrival jitter |
274// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
275// . .
276// . .
277// . .
278// | inter-arrival jitter |
279// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000280//
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000281// If present, this RTCP packet must be placed after a receiver report
282// (inside a compound RTCP packet), and MUST have the same value for RC
283// (reception report count) as the receiver report.
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000284
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000285class Ij : public RtcpPacket {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000286 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000287 Ij() : RtcpPacket() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000288
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000289 virtual ~Ij() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000290
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200291 bool WithJitterItem(uint32_t jitter);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000292
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000293 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200294 bool Create(uint8_t* packet,
295 size_t* index,
296 size_t max_length,
297 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000298
299 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200300 static const int kMaxNumberOfIjItems = 0x1f;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000301
302 size_t BlockLength() const {
303 return kHeaderLength + 4 * ij_items_.size();
304 }
305
306 std::vector<uint32_t> ij_items_;
307
henrikg3c089d72015-09-16 05:37:44 -0700308 RTC_DISALLOW_COPY_AND_ASSIGN(Ij);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000309};
310
311// Source Description (SDES) (RFC 3550).
312//
313// 0 1 2 3
314// 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
315// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
316// header |V=2|P| SC | PT=SDES=202 | length |
317// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
318// chunk | SSRC/CSRC_1 |
319// 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
320// | SDES items |
321// | ... |
322// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
323// chunk | SSRC/CSRC_2 |
324// 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
325// | SDES items |
326// | ... |
327// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
328//
329// Canonical End-Point Identifier SDES Item (CNAME)
330//
331// 0 1 2 3
332// 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
333// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
334// | CNAME=1 | length | user and domain name ...
335// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
336
337class Sdes : public RtcpPacket {
338 public:
339 Sdes() : RtcpPacket() {}
340
341 virtual ~Sdes() {}
342
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200343 bool WithCName(uint32_t ssrc, const std::string& cname);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000344
345 struct Chunk {
346 uint32_t ssrc;
347 std::string name;
348 int null_octets;
349 };
350
351 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200352 bool Create(uint8_t* packet,
353 size_t* index,
354 size_t max_length,
355 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000356
357 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200358 static const int kMaxNumberOfChunks = 0x1f;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000359
360 size_t BlockLength() const;
361
362 std::vector<Chunk> chunks_;
363
henrikg3c089d72015-09-16 05:37:44 -0700364 RTC_DISALLOW_COPY_AND_ASSIGN(Sdes);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000365};
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:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000383 Bye() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000384 memset(&bye_, 0, sizeof(bye_));
385 }
386
387 virtual ~Bye() {}
388
389 void From(uint32_t ssrc) {
390 bye_.SenderSSRC = ssrc;
391 }
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200392
393 bool WithCsrc(uint32_t csrc);
394
395 // TODO(sprang): Add support for reason field?
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000396
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000397 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200398 bool Create(uint8_t* packet,
399 size_t* index,
400 size_t max_length,
401 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000402
403 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200404 static const int kMaxNumberOfCsrcs = 0x1f - 1; // First item is sender SSRC.
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000405
406 size_t BlockLength() const {
407 size_t source_count = 1 + csrcs_.size();
408 return kHeaderLength + 4 * source_count;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000409 }
410
411 RTCPUtility::RTCPPacketBYE bye_;
412 std::vector<uint32_t> csrcs_;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000413
henrikg3c089d72015-09-16 05:37:44 -0700414 RTC_DISALLOW_COPY_AND_ASSIGN(Bye);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000415};
416
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000417// Application-Defined packet (APP) (RFC 3550).
418//
419// 0 1 2 3
420// 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
421// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
422// |V=2|P| subtype | PT=APP=204 | length |
423// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
424// | SSRC/CSRC |
425// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
426// | name (ASCII) |
427// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
428// | application-dependent data ...
429// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
430
431class App : public RtcpPacket {
432 public:
433 App()
434 : RtcpPacket(),
435 ssrc_(0) {
436 memset(&app_, 0, sizeof(app_));
437 }
438
439 virtual ~App() {}
440
441 void From(uint32_t ssrc) {
442 ssrc_ = ssrc;
443 }
444 void WithSubType(uint8_t subtype) {
445 assert(subtype <= 0x1f);
446 app_.SubType = subtype;
447 }
448 void WithName(uint32_t name) {
449 app_.Name = name;
450 }
451 void WithData(const uint8_t* data, uint16_t data_length) {
452 assert(data);
453 assert(data_length <= kRtcpAppCode_DATA_SIZE);
454 assert(data_length % 4 == 0);
455 memcpy(app_.Data, data, data_length);
456 app_.Size = data_length;
457 }
458
459 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200460 bool Create(uint8_t* packet,
461 size_t* index,
462 size_t max_length,
463 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000464
465 private:
466 size_t BlockLength() const {
467 return 12 + app_.Size;
468 }
469
470 uint32_t ssrc_;
471 RTCPUtility::RTCPPacketAPP app_;
472
henrikg3c089d72015-09-16 05:37:44 -0700473 RTC_DISALLOW_COPY_AND_ASSIGN(App);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000474};
475
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000476// RFC 4585: Feedback format.
477//
478// Common packet format:
479//
480// 0 1 2 3
481// 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
482// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
483// |V=2|P| FMT | PT | length |
484// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
485// | SSRC of packet sender |
486// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
487// | SSRC of media source |
488// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
489// : Feedback Control Information (FCI) :
490// :
491
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000492// Picture loss indication (PLI) (RFC 4585).
493//
494// FCI: no feedback control information.
495
496class Pli : public RtcpPacket {
497 public:
498 Pli() : RtcpPacket() {
499 memset(&pli_, 0, sizeof(pli_));
500 }
501
502 virtual ~Pli() {}
503
504 void From(uint32_t ssrc) {
505 pli_.SenderSSRC = ssrc;
506 }
507 void To(uint32_t ssrc) {
508 pli_.MediaSSRC = ssrc;
509 }
510
511 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200512 bool Create(uint8_t* packet,
513 size_t* index,
514 size_t max_length,
515 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000516
517 private:
518 size_t BlockLength() const {
519 return kCommonFbFmtLength;
520 }
521
522 RTCPUtility::RTCPPacketPSFBPLI pli_;
523
henrikg3c089d72015-09-16 05:37:44 -0700524 RTC_DISALLOW_COPY_AND_ASSIGN(Pli);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000525};
526
527// Slice loss indication (SLI) (RFC 4585).
528//
529// FCI:
530// 0 1 2 3
531// 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
532// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
533// | First | Number | PictureID |
534// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
535
536class Sli : public RtcpPacket {
537 public:
538 Sli() : RtcpPacket() {
539 memset(&sli_, 0, sizeof(sli_));
540 memset(&sli_item_, 0, sizeof(sli_item_));
541 }
542
543 virtual ~Sli() {}
544
545 void From(uint32_t ssrc) {
546 sli_.SenderSSRC = ssrc;
547 }
548 void To(uint32_t ssrc) {
549 sli_.MediaSSRC = ssrc;
550 }
551 void WithFirstMb(uint16_t first_mb) {
552 assert(first_mb <= 0x1fff);
553 sli_item_.FirstMB = first_mb;
554 }
555 void WithNumberOfMb(uint16_t number_mb) {
556 assert(number_mb <= 0x1fff);
557 sli_item_.NumberOfMB = number_mb;
558 }
559 void WithPictureId(uint8_t picture_id) {
560 assert(picture_id <= 0x3f);
561 sli_item_.PictureId = picture_id;
562 }
563
564 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200565 bool Create(uint8_t* packet,
566 size_t* index,
567 size_t max_length,
568 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000569
570 private:
571 size_t BlockLength() const {
572 const size_t kFciLength = 4;
573 return kCommonFbFmtLength + kFciLength;
574 }
575
576 RTCPUtility::RTCPPacketPSFBSLI sli_;
577 RTCPUtility::RTCPPacketPSFBSLIItem sli_item_;
578
henrikg3c089d72015-09-16 05:37:44 -0700579 RTC_DISALLOW_COPY_AND_ASSIGN(Sli);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000580};
581
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000582// Generic NACK (RFC 4585).
583//
584// FCI:
585// 0 1 2 3
586// 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
587// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
588// | PID | BLP |
589// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
590
591class Nack : public RtcpPacket {
592 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000593 Nack() : RtcpPacket() {
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000594 memset(&nack_, 0, sizeof(nack_));
595 }
596
597 virtual ~Nack() {}
598
599 void From(uint32_t ssrc) {
600 nack_.SenderSSRC = ssrc;
601 }
602 void To(uint32_t ssrc) {
603 nack_.MediaSSRC = ssrc;
604 }
605 void WithList(const uint16_t* nack_list, int length);
606
607 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200608 bool Create(uint8_t* packet,
609 size_t* index,
610 size_t max_length,
611 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000612
Erik Språnga3b87692015-07-29 10:46:54 +0200613 size_t BlockLength() const override;
614
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000615 private:
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000616
617 RTCPUtility::RTCPPacketRTPFBNACK nack_;
618 std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_;
619
henrikg3c089d72015-09-16 05:37:44 -0700620 RTC_DISALLOW_COPY_AND_ASSIGN(Nack);
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000621};
622
623// Reference picture selection indication (RPSI) (RFC 4585).
624//
625// FCI:
626//
627// 0 1 2 3
628// 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
629// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
630// | PB |0| Payload Type| Native RPSI bit string |
631// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
632// | defined per codec ... | Padding (0) |
633// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
634
635class Rpsi : public RtcpPacket {
636 public:
637 Rpsi()
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000638 : RtcpPacket(),
639 padding_bytes_(0) {
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000640 memset(&rpsi_, 0, sizeof(rpsi_));
641 }
642
643 virtual ~Rpsi() {}
644
645 void From(uint32_t ssrc) {
646 rpsi_.SenderSSRC = ssrc;
647 }
648 void To(uint32_t ssrc) {
649 rpsi_.MediaSSRC = ssrc;
650 }
651 void WithPayloadType(uint8_t payload) {
652 assert(payload <= 0x7f);
653 rpsi_.PayloadType = payload;
654 }
655 void WithPictureId(uint64_t picture_id);
656
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.orga8260062014-05-20 09:53:51 +0000662
663 private:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000664 size_t BlockLength() const {
665 size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_;
666 return kCommonFbFmtLength + fci_length;
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000667 }
668
669 uint8_t padding_bytes_;
670 RTCPUtility::RTCPPacketPSFBRPSI rpsi_;
671
henrikg3c089d72015-09-16 05:37:44 -0700672 RTC_DISALLOW_COPY_AND_ASSIGN(Rpsi);
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000673};
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000674
675// Full intra request (FIR) (RFC 5104).
676//
677// FCI:
678//
679// 0 1 2 3
680// 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
681// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
682// | SSRC |
683// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
684// | Seq nr. | Reserved |
685// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
686
687class Fir : public RtcpPacket {
688 public:
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000689 Fir() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000690 memset(&fir_, 0, sizeof(fir_));
691 memset(&fir_item_, 0, sizeof(fir_item_));
692 }
693
694 virtual ~Fir() {}
695
696 void From(uint32_t ssrc) {
697 fir_.SenderSSRC = ssrc;
698 }
699 void To(uint32_t ssrc) {
700 fir_item_.SSRC = ssrc;
701 }
702 void WithCommandSeqNum(uint8_t seq_num) {
703 fir_item_.CommandSequenceNumber = seq_num;
704 }
705
706 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200707 bool Create(uint8_t* packet,
708 size_t* index,
709 size_t max_length,
710 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000711
712 private:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000713 size_t BlockLength() const {
714 const size_t kFciLength = 8;
715 return kCommonFbFmtLength + kFciLength;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000716 }
717
718 RTCPUtility::RTCPPacketPSFBFIR fir_;
719 RTCPUtility::RTCPPacketPSFBFIRItem fir_item_;
720};
721
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000722// Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104).
723//
724// FCI:
725//
726// 0 1 2 3
727// 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
728// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
729// | SSRC |
730// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
731// | MxTBR Exp | MxTBR Mantissa |Measured Overhead|
732// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
733
734class Tmmbr : public RtcpPacket {
735 public:
736 Tmmbr() : RtcpPacket() {
737 memset(&tmmbr_, 0, sizeof(tmmbr_));
738 memset(&tmmbr_item_, 0, sizeof(tmmbr_item_));
739 }
740
741 virtual ~Tmmbr() {}
742
743 void From(uint32_t ssrc) {
744 tmmbr_.SenderSSRC = ssrc;
745 }
746 void To(uint32_t ssrc) {
747 tmmbr_item_.SSRC = ssrc;
748 }
749 void WithBitrateKbps(uint32_t bitrate_kbps) {
750 tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps;
751 }
752 void WithOverhead(uint16_t overhead) {
753 assert(overhead <= 0x1ff);
754 tmmbr_item_.MeasuredOverhead = overhead;
755 }
756
757 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200758 bool Create(uint8_t* packet,
759 size_t* index,
760 size_t max_length,
761 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000762
763 private:
764 size_t BlockLength() const {
765 const size_t kFciLen = 8;
766 return kCommonFbFmtLength + kFciLen;
767 }
768
769 RTCPUtility::RTCPPacketRTPFBTMMBR tmmbr_;
770 RTCPUtility::RTCPPacketRTPFBTMMBRItem tmmbr_item_;
771
henrikg3c089d72015-09-16 05:37:44 -0700772 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000773};
774
775// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
776//
777// FCI:
778//
779// 0 1 2 3
780// 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
781// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
782// | SSRC |
783// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
784// | MxTBR Exp | MxTBR Mantissa |Measured Overhead|
785// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
786
787class Tmmbn : public RtcpPacket {
788 public:
789 Tmmbn() : RtcpPacket() {
790 memset(&tmmbn_, 0, sizeof(tmmbn_));
791 }
792
793 virtual ~Tmmbn() {}
794
795 void From(uint32_t ssrc) {
796 tmmbn_.SenderSSRC = ssrc;
797 }
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200798 // Max 50 TMMBR can be added per TMMBN.
799 bool WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000800
801 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200802 bool Create(uint8_t* packet,
803 size_t* index,
804 size_t max_length,
805 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000806
807 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200808 static const int kMaxNumberOfTmmbrs = 50;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000809
810 size_t BlockLength() const {
811 const size_t kFciLen = 8;
812 return kCommonFbFmtLength + kFciLen * tmmbn_items_.size();
813 }
814
815 RTCPUtility::RTCPPacketRTPFBTMMBN tmmbn_;
816 std::vector<RTCPUtility::RTCPPacketRTPFBTMMBRItem> tmmbn_items_;
817
henrikg3c089d72015-09-16 05:37:44 -0700818 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbn);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000819};
820
821// Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
822//
823// 0 1 2 3
824// 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
825// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
826// |V=2|P| FMT=15 | PT=206 | length |
827// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
828// | SSRC of packet sender |
829// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
830// | SSRC of media source |
831// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
832// | Unique identifier 'R' 'E' 'M' 'B' |
833// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
834// | Num SSRC | BR Exp | BR Mantissa |
835// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
836// | SSRC feedback |
837// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
838// | ...
839
840class Remb : public RtcpPacket {
841 public:
842 Remb() : RtcpPacket() {
843 memset(&remb_, 0, sizeof(remb_));
844 memset(&remb_item_, 0, sizeof(remb_item_));
845 }
846
847 virtual ~Remb() {}
848
849 void From(uint32_t ssrc) {
850 remb_.SenderSSRC = ssrc;
851 }
852 void AppliesTo(uint32_t ssrc);
853
854 void WithBitrateBps(uint32_t bitrate_bps) {
855 remb_item_.BitRate = bitrate_bps;
856 }
857
858 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200859 bool Create(uint8_t* packet,
860 size_t* index,
861 size_t max_length,
862 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000863
864 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200865 static const int kMaxNumberOfSsrcs = 0xff;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000866
867 size_t BlockLength() const {
868 return (remb_item_.NumberOfSSRCs + 5) * 4;
869 }
870
871 RTCPUtility::RTCPPacketPSFBAPP remb_;
872 RTCPUtility::RTCPPacketPSFBREMBItem remb_item_;
873
henrikg3c089d72015-09-16 05:37:44 -0700874 RTC_DISALLOW_COPY_AND_ASSIGN(Remb);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000875};
876
877// From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR).
878//
879// Format for XR packets:
880//
881// 0 1 2 3
882// 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
883// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
884// |V=2|P|reserved | PT=XR=207 | length |
885// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
886// | SSRC |
887// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
888// : report blocks :
889// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
890
891class Xr : public RtcpPacket {
892 public:
893 typedef std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> DlrrBlock;
894 Xr() : RtcpPacket() {
895 memset(&xr_header_, 0, sizeof(xr_header_));
896 }
897
898 virtual ~Xr() {}
899
900 void From(uint32_t ssrc) {
901 xr_header_.OriginatorSSRC = ssrc;
902 }
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200903
904 // Max 50 items of each of {Rrtr, Dlrr, VoipMetric} allowed per Xr.
905 bool WithRrtr(Rrtr* rrtr);
906 bool WithDlrr(Dlrr* dlrr);
907 bool WithVoipMetric(VoipMetric* voip_metric);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000908
909 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200910 bool Create(uint8_t* packet,
911 size_t* index,
912 size_t max_length,
913 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000914
915 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200916 static const int kMaxNumberOfRrtrBlocks = 50;
917 static const int kMaxNumberOfDlrrBlocks = 50;
918 static const int kMaxNumberOfVoipMetricBlocks = 50;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000919
920 size_t BlockLength() const {
921 const size_t kXrHeaderLength = 8;
922 return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength();
923 }
924
925 size_t RrtrLength() const {
926 const size_t kRrtrBlockLength = 12;
927 return kRrtrBlockLength * rrtr_blocks_.size();
928 }
929
930 size_t DlrrLength() const;
931
932 size_t VoipMetricLength() const {
933 const size_t kVoipMetricBlockLength = 36;
934 return kVoipMetricBlockLength * voip_metric_blocks_.size();
935 }
936
937 RTCPUtility::RTCPPacketXR xr_header_;
938 std::vector<RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem> rrtr_blocks_;
939 std::vector<DlrrBlock> dlrr_blocks_;
940 std::vector<RTCPUtility::RTCPPacketXRVOIPMetricItem> voip_metric_blocks_;
941
henrikg3c089d72015-09-16 05:37:44 -0700942 RTC_DISALLOW_COPY_AND_ASSIGN(Xr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000943};
944
945// Receiver Reference Time Report Block (RFC 3611).
946//
947// 0 1 2 3
948// 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
949// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
950// | BT=4 | reserved | block length = 2 |
951// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
952// | NTP timestamp, most significant word |
953// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
954// | NTP timestamp, least significant word |
955// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
956
957class Rrtr {
958 public:
959 Rrtr() {
960 memset(&rrtr_block_, 0, sizeof(rrtr_block_));
961 }
962 ~Rrtr() {}
963
964 void WithNtpSec(uint32_t sec) {
965 rrtr_block_.NTPMostSignificant = sec;
966 }
967 void WithNtpFrac(uint32_t frac) {
968 rrtr_block_.NTPLeastSignificant = frac;
969 }
970
971 private:
972 friend class Xr;
973 RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem rrtr_block_;
974
henrikg3c089d72015-09-16 05:37:44 -0700975 RTC_DISALLOW_COPY_AND_ASSIGN(Rrtr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000976};
977
978// DLRR Report Block (RFC 3611).
979//
980// 0 1 2 3
981// 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
982// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
983// | BT=5 | reserved | block length |
984// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
985// | SSRC_1 (SSRC of first receiver) | sub-
986// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
987// | last RR (LRR) | 1
988// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
989// | delay since last RR (DLRR) |
990// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
991// | SSRC_2 (SSRC of second receiver) | sub-
992// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
993// : ... : 2
994
995class Dlrr {
996 public:
997 Dlrr() {}
998 ~Dlrr() {}
999
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001000 // Max 100 DLRR Items can be added per DLRR report block.
1001 bool WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +00001002
1003 private:
1004 friend class Xr;
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001005 static const int kMaxNumberOfDlrrItems = 100;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +00001006
1007 std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> dlrr_block_;
1008
henrikg3c089d72015-09-16 05:37:44 -07001009 RTC_DISALLOW_COPY_AND_ASSIGN(Dlrr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +00001010};
1011
1012// VoIP Metrics Report Block (RFC 3611).
1013//
1014// 0 1 2 3
1015// 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
1016// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1017// | BT=7 | reserved | block length = 8 |
1018// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1019// | SSRC of source |
1020// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1021// | loss rate | discard rate | burst density | gap density |
1022// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1023// | burst duration | gap duration |
1024// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1025// | round trip delay | end system delay |
1026// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1027// | signal level | noise level | RERL | Gmin |
1028// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1029// | R factor | ext. R factor | MOS-LQ | MOS-CQ |
1030// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1031// | RX config | reserved | JB nominal |
1032// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1033// | JB maximum | JB abs max |
1034// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1035
1036class VoipMetric {
1037 public:
1038 VoipMetric() {
1039 memset(&metric_, 0, sizeof(metric_));
1040 }
1041 ~VoipMetric() {}
1042
1043 void To(uint32_t ssrc) { metric_.SSRC = ssrc; }
1044 void LossRate(uint8_t loss_rate) { metric_.lossRate = loss_rate; }
1045 void DiscardRate(uint8_t discard_rate) { metric_.discardRate = discard_rate; }
1046 void BurstDensity(uint8_t burst_density) {
1047 metric_.burstDensity = burst_density;
1048 }
1049 void GapDensity(uint8_t gap_density) { metric_.gapDensity = gap_density; }
1050 void BurstDuration(uint16_t burst_duration) {
1051 metric_.burstDuration = burst_duration;
1052 }
1053 void GapDuration(uint16_t gap_duration) {
1054 metric_.gapDuration = gap_duration;
1055 }
1056 void RoundTripDelay(uint16_t round_trip_delay) {
1057 metric_.roundTripDelay = round_trip_delay;
1058 }
1059 void EndSystemDelay(uint16_t end_system_delay) {
1060 metric_.endSystemDelay = end_system_delay;
1061 }
1062 void SignalLevel(uint8_t signal_level) { metric_.signalLevel = signal_level; }
1063 void NoiseLevel(uint8_t noise_level) { metric_.noiseLevel = noise_level; }
1064 void Rerl(uint8_t rerl) { metric_.RERL = rerl; }
1065 void Gmin(uint8_t gmin) { metric_.Gmin = gmin; }
1066 void Rfactor(uint8_t rfactor) { metric_.Rfactor = rfactor; }
1067 void ExtRfactor(uint8_t extrfactor) { metric_.extRfactor = extrfactor; }
1068 void MosLq(uint8_t moslq) { metric_.MOSLQ = moslq; }
1069 void MosCq(uint8_t moscq) { metric_.MOSCQ = moscq; }
1070 void RxConfig(uint8_t rxconfig) { metric_.RXconfig = rxconfig; }
1071 void JbNominal(uint16_t jbnominal) { metric_.JBnominal = jbnominal; }
1072 void JbMax(uint16_t jbmax) { metric_.JBmax = jbmax; }
1073 void JbAbsMax(uint16_t jbabsmax) { metric_.JBabsMax = jbabsmax; }
1074
1075 private:
1076 friend class Xr;
1077 RTCPUtility::RTCPPacketXRVOIPMetricItem metric_;
1078
henrikg3c089d72015-09-16 05:37:44 -07001079 RTC_DISALLOW_COPY_AND_ASSIGN(VoipMetric);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +00001080};
1081
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001082// Class holding a RTCP packet.
1083//
1084// Takes a built rtcp packet.
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +00001085// RawPacket raw_packet(buffer, length);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001086//
1087// To access the raw packet:
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001088// raw_packet.Buffer(); - pointer to the raw packet
1089// raw_packet.BufferLength(); - the length of the raw packet
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001090
1091class RawPacket {
1092 public:
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001093 explicit RawPacket(size_t buffer_length);
1094 RawPacket(const uint8_t* packet, size_t packet_length);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001095
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001096 const uint8_t* Buffer() const;
1097 uint8_t* MutableBuffer();
1098 size_t BufferLength() const;
1099 size_t Length() const;
1100 void SetLength(size_t length);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001101
1102 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001103 const size_t buffer_length_;
1104 size_t length_;
1105 rtc::scoped_ptr<uint8_t[]> buffer_;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001106};
1107
1108} // namespace rtcp
1109} // namespace webrtc
1110#endif // WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_