blob: 3c34957c361bab8f206791dc7670bd59194a3e48 [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"
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000020#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
Erik Språngc1b9d4e2015-06-08 09:54:14 +020027static const int kCommonFbFmtLength = 12;
28static const int kReportBlockLength = 24;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +000029
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +000030class Dlrr;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000031class RawPacket;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +000032class Rrtr;
33class VoipMetric;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000034
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//
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +000051// size_t length = 0; // Builds an intra frame request
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000052// uint8_t packet[kPacketSize]; // with sequence number 123.
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +000053// fir.Build(packet, &length, kPacketSize);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000054//
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
Erik Språngc1b9d4e2015-06-08 09:54:14 +020068 // 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() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000076
Erik Språngc1b9d4e2015-06-08 09:54:14 +020077 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;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000093
Erik Språng6b8d3552015-09-24 15:06:57 +020094 // Size of this packet in bytes (including headers, excluding nested packets).
95 virtual size_t BlockLength() const = 0;
96
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000097 protected:
Erik Språnga3b87692015-07-29 10:46:54 +020098 RtcpPacket() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000099
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200100 virtual bool Create(uint8_t* packet,
101 size_t* index,
102 size_t max_length,
103 PacketReadyCallback* callback) const = 0;
104
sprang73a93e82015-09-14 12:50:39 -0700105 static void CreateHeader(uint8_t count_or_format,
106 uint8_t packet_type,
107 size_t block_length, // Size in 32bit words - 1.
108 uint8_t* buffer,
109 size_t* pos);
Erik Språnga3b87692015-07-29 10:46:54 +0200110
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200111 bool OnBufferFull(uint8_t* packet,
112 size_t* index,
113 RtcpPacket::PacketReadyCallback* callback) const;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000114
Erik Språnga3b87692015-07-29 10:46:54 +0200115 size_t HeaderLength() const;
116
117 static const size_t kHeaderLength = 4;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000118
119 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200120 bool CreateAndAddAppended(uint8_t* packet,
121 size_t* index,
122 size_t max_length,
123 PacketReadyCallback* callback) const;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000124
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000125 std::vector<RtcpPacket*> appended_packets_;
126};
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.org4b12d402014-06-16 14:09:28 +0000148// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000149//
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000150// RTCP report block (RFC 3550).
151//
152// 0 1 2 3
153// 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
154// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
155// | SSRC_1 (SSRC of first source) |
156// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
157// | fraction lost | cumulative number of packets lost |
158// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159// | extended highest sequence number received |
160// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161// | interarrival jitter |
162// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163// | last SR (LSR) |
164// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165// | delay since last SR (DLSR) |
166// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
167
168class ReportBlock {
169 public:
170 ReportBlock() {
171 // TODO(asapersson): Consider adding a constructor to struct.
172 memset(&report_block_, 0, sizeof(report_block_));
173 }
174
175 ~ReportBlock() {}
176
177 void To(uint32_t ssrc) {
178 report_block_.SSRC = ssrc;
179 }
180 void WithFractionLost(uint8_t fraction_lost) {
181 report_block_.FractionLost = fraction_lost;
182 }
183 void WithCumulativeLost(uint32_t cumulative_lost) {
184 report_block_.CumulativeNumOfPacketsLost = cumulative_lost;
185 }
186 void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) {
187 report_block_.ExtendedHighestSequenceNumber = ext_highest_seq_num;
188 }
189 void WithJitter(uint32_t jitter) {
190 report_block_.Jitter = jitter;
191 }
192 void WithLastSr(uint32_t last_sr) {
193 report_block_.LastSR = last_sr;
194 }
195 void WithDelayLastSr(uint32_t delay_last_sr) {
196 report_block_.DelayLastSR = delay_last_sr;
197 }
198
199 private:
200 friend class SenderReport;
201 friend class ReceiverReport;
202 RTCPUtility::RTCPPacketReportBlockItem report_block_;
203};
204
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000205// RTCP sender report (RFC 3550).
206//
207// 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
208// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
209// |V=2|P| RC | PT=SR=200 | length |
210// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211// | SSRC of sender |
212// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
213// | NTP timestamp, most significant word |
214// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
215// | NTP timestamp, least significant word |
216// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
217// | RTP timestamp |
218// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
219// | sender's packet count |
220// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
221// | sender's octet count |
222// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
223// | report block(s) |
224// | .... |
225
226class SenderReport : public RtcpPacket {
227 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000228 SenderReport() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000229 memset(&sr_, 0, sizeof(sr_));
230 }
231
232 virtual ~SenderReport() {}
233
234 void From(uint32_t ssrc) {
235 sr_.SenderSSRC = ssrc;
236 }
237 void WithNtpSec(uint32_t sec) {
238 sr_.NTPMostSignificant = sec;
239 }
240 void WithNtpFrac(uint32_t frac) {
241 sr_.NTPLeastSignificant = frac;
242 }
243 void WithRtpTimestamp(uint32_t rtp_timestamp) {
244 sr_.RTPTimestamp = rtp_timestamp;
245 }
246 void WithPacketCount(uint32_t packet_count) {
247 sr_.SenderPacketCount = packet_count;
248 }
249 void WithOctetCount(uint32_t octet_count) {
250 sr_.SenderOctetCount = octet_count;
251 }
Erik Språngbdc0b0d2015-06-22 15:21:24 +0200252 bool WithReportBlock(const ReportBlock& block);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000253
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000254 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200255 bool Create(uint8_t* packet,
256 size_t* index,
257 size_t max_length,
258 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000259
260 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200261 static const int kMaxNumberOfReportBlocks = 0x1f;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000262
263 size_t BlockLength() const {
264 const size_t kSrHeaderLength = 8;
265 const size_t kSenderInfoLength = 20;
266 return kSrHeaderLength + kSenderInfoLength +
267 report_blocks_.size() * kReportBlockLength;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000268 }
269
270 RTCPUtility::RTCPPacketSR sr_;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000271 std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000272
henrikg3c089d72015-09-16 05:37:44 -0700273 RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000274};
275
276//
277// RTCP receiver report (RFC 3550).
278//
279// 0 1 2 3
280// 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
281// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
282// |V=2|P| RC | PT=RR=201 | length |
283// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
284// | SSRC of packet sender |
285// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
286// | report block(s) |
287// | .... |
288
289class ReceiverReport : public RtcpPacket {
290 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000291 ReceiverReport() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000292 memset(&rr_, 0, sizeof(rr_));
293 }
294
295 virtual ~ReceiverReport() {}
296
297 void From(uint32_t ssrc) {
298 rr_.SenderSSRC = ssrc;
299 }
Erik Språngbdc0b0d2015-06-22 15:21:24 +0200300 bool WithReportBlock(const ReportBlock& block);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000301
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000302 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200303 bool Create(uint8_t* packet,
304 size_t* index,
305 size_t max_length,
306 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000307
308 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200309 static const int kMaxNumberOfReportBlocks = 0x1F;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000310
311 size_t BlockLength() const {
312 const size_t kRrHeaderLength = 8;
313 return kRrHeaderLength + report_blocks_.size() * kReportBlockLength;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000314 }
315
316 RTCPUtility::RTCPPacketRR rr_;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000317 std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000318
henrikg3c089d72015-09-16 05:37:44 -0700319 RTC_DISALLOW_COPY_AND_ASSIGN(ReceiverReport);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000320};
321
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000322// Transmission Time Offsets in RTP Streams (RFC 5450).
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000323//
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000324// 0 1 2 3
325// 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
326// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
327// hdr |V=2|P| RC | PT=IJ=195 | length |
328// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
329// | inter-arrival jitter |
330// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
331// . .
332// . .
333// . .
334// | inter-arrival jitter |
335// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000336//
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000337// If present, this RTCP packet must be placed after a receiver report
338// (inside a compound RTCP packet), and MUST have the same value for RC
339// (reception report count) as the receiver report.
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000340
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000341class Ij : public RtcpPacket {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000342 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000343 Ij() : RtcpPacket() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000344
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000345 virtual ~Ij() {}
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000346
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200347 bool WithJitterItem(uint32_t jitter);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000348
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000349 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200350 bool Create(uint8_t* packet,
351 size_t* index,
352 size_t max_length,
353 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000354
355 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200356 static const int kMaxNumberOfIjItems = 0x1f;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000357
358 size_t BlockLength() const {
359 return kHeaderLength + 4 * ij_items_.size();
360 }
361
362 std::vector<uint32_t> ij_items_;
363
henrikg3c089d72015-09-16 05:37:44 -0700364 RTC_DISALLOW_COPY_AND_ASSIGN(Ij);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000365};
366
367// Source Description (SDES) (RFC 3550).
368//
369// 0 1 2 3
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// header |V=2|P| SC | PT=SDES=202 | length |
373// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
374// chunk | SSRC/CSRC_1 |
375// 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
376// | SDES items |
377// | ... |
378// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
379// chunk | SSRC/CSRC_2 |
380// 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
381// | SDES items |
382// | ... |
383// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
384//
385// Canonical End-Point Identifier SDES Item (CNAME)
386//
387// 0 1 2 3
388// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
389// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
390// | CNAME=1 | length | user and domain name ...
391// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
392
393class Sdes : public RtcpPacket {
394 public:
395 Sdes() : RtcpPacket() {}
396
397 virtual ~Sdes() {}
398
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200399 bool WithCName(uint32_t ssrc, const std::string& cname);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000400
401 struct Chunk {
402 uint32_t ssrc;
403 std::string name;
404 int null_octets;
405 };
406
407 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200408 bool Create(uint8_t* packet,
409 size_t* index,
410 size_t max_length,
411 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000412
413 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200414 static const int kMaxNumberOfChunks = 0x1f;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000415
416 size_t BlockLength() const;
417
418 std::vector<Chunk> chunks_;
419
henrikg3c089d72015-09-16 05:37:44 -0700420 RTC_DISALLOW_COPY_AND_ASSIGN(Sdes);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000421};
422
423//
424// Bye packet (BYE) (RFC 3550).
425//
426// 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
427// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
428// |V=2|P| SC | PT=BYE=203 | length |
429// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
430// | SSRC/CSRC |
431// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
432// : ... :
433// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
434// (opt) | length | reason for leaving ...
435// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
436
437class Bye : public RtcpPacket {
438 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000439 Bye() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000440 memset(&bye_, 0, sizeof(bye_));
441 }
442
443 virtual ~Bye() {}
444
445 void From(uint32_t ssrc) {
446 bye_.SenderSSRC = ssrc;
447 }
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200448
449 bool WithCsrc(uint32_t csrc);
450
451 // TODO(sprang): Add support for reason field?
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000452
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000453 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200454 bool Create(uint8_t* packet,
455 size_t* index,
456 size_t max_length,
457 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000458
459 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200460 static const int kMaxNumberOfCsrcs = 0x1f - 1; // First item is sender SSRC.
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000461
462 size_t BlockLength() const {
463 size_t source_count = 1 + csrcs_.size();
464 return kHeaderLength + 4 * source_count;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000465 }
466
467 RTCPUtility::RTCPPacketBYE bye_;
468 std::vector<uint32_t> csrcs_;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000469
henrikg3c089d72015-09-16 05:37:44 -0700470 RTC_DISALLOW_COPY_AND_ASSIGN(Bye);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000471};
472
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000473// Application-Defined packet (APP) (RFC 3550).
474//
475// 0 1 2 3
476// 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
477// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
478// |V=2|P| subtype | PT=APP=204 | length |
479// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
480// | SSRC/CSRC |
481// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
482// | name (ASCII) |
483// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
484// | application-dependent data ...
485// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
486
487class App : public RtcpPacket {
488 public:
489 App()
490 : RtcpPacket(),
491 ssrc_(0) {
492 memset(&app_, 0, sizeof(app_));
493 }
494
495 virtual ~App() {}
496
497 void From(uint32_t ssrc) {
498 ssrc_ = ssrc;
499 }
500 void WithSubType(uint8_t subtype) {
501 assert(subtype <= 0x1f);
502 app_.SubType = subtype;
503 }
504 void WithName(uint32_t name) {
505 app_.Name = name;
506 }
507 void WithData(const uint8_t* data, uint16_t data_length) {
508 assert(data);
509 assert(data_length <= kRtcpAppCode_DATA_SIZE);
510 assert(data_length % 4 == 0);
511 memcpy(app_.Data, data, data_length);
512 app_.Size = data_length;
513 }
514
515 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200516 bool Create(uint8_t* packet,
517 size_t* index,
518 size_t max_length,
519 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000520
521 private:
522 size_t BlockLength() const {
523 return 12 + app_.Size;
524 }
525
526 uint32_t ssrc_;
527 RTCPUtility::RTCPPacketAPP app_;
528
henrikg3c089d72015-09-16 05:37:44 -0700529 RTC_DISALLOW_COPY_AND_ASSIGN(App);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000530};
531
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000532// RFC 4585: Feedback format.
533//
534// Common packet format:
535//
536// 0 1 2 3
537// 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
538// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
539// |V=2|P| FMT | PT | length |
540// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
541// | SSRC of packet sender |
542// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
543// | SSRC of media source |
544// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
545// : Feedback Control Information (FCI) :
546// :
547
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000548// Picture loss indication (PLI) (RFC 4585).
549//
550// FCI: no feedback control information.
551
552class Pli : public RtcpPacket {
553 public:
554 Pli() : RtcpPacket() {
555 memset(&pli_, 0, sizeof(pli_));
556 }
557
558 virtual ~Pli() {}
559
560 void From(uint32_t ssrc) {
561 pli_.SenderSSRC = ssrc;
562 }
563 void To(uint32_t ssrc) {
564 pli_.MediaSSRC = ssrc;
565 }
566
567 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200568 bool Create(uint8_t* packet,
569 size_t* index,
570 size_t max_length,
571 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000572
573 private:
574 size_t BlockLength() const {
575 return kCommonFbFmtLength;
576 }
577
578 RTCPUtility::RTCPPacketPSFBPLI pli_;
579
henrikg3c089d72015-09-16 05:37:44 -0700580 RTC_DISALLOW_COPY_AND_ASSIGN(Pli);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000581};
582
583// Slice loss indication (SLI) (RFC 4585).
584//
585// FCI:
586// 0 1 2 3
587// 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
588// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
589// | First | Number | PictureID |
590// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
591
592class Sli : public RtcpPacket {
593 public:
594 Sli() : RtcpPacket() {
595 memset(&sli_, 0, sizeof(sli_));
596 memset(&sli_item_, 0, sizeof(sli_item_));
597 }
598
599 virtual ~Sli() {}
600
601 void From(uint32_t ssrc) {
602 sli_.SenderSSRC = ssrc;
603 }
604 void To(uint32_t ssrc) {
605 sli_.MediaSSRC = ssrc;
606 }
607 void WithFirstMb(uint16_t first_mb) {
608 assert(first_mb <= 0x1fff);
609 sli_item_.FirstMB = first_mb;
610 }
611 void WithNumberOfMb(uint16_t number_mb) {
612 assert(number_mb <= 0x1fff);
613 sli_item_.NumberOfMB = number_mb;
614 }
615 void WithPictureId(uint8_t picture_id) {
616 assert(picture_id <= 0x3f);
617 sli_item_.PictureId = picture_id;
618 }
619
620 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200621 bool Create(uint8_t* packet,
622 size_t* index,
623 size_t max_length,
624 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000625
626 private:
627 size_t BlockLength() const {
628 const size_t kFciLength = 4;
629 return kCommonFbFmtLength + kFciLength;
630 }
631
632 RTCPUtility::RTCPPacketPSFBSLI sli_;
633 RTCPUtility::RTCPPacketPSFBSLIItem sli_item_;
634
henrikg3c089d72015-09-16 05:37:44 -0700635 RTC_DISALLOW_COPY_AND_ASSIGN(Sli);
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000636};
637
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000638// Generic NACK (RFC 4585).
639//
640// FCI:
641// 0 1 2 3
642// 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
643// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
644// | PID | BLP |
645// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
646
647class Nack : public RtcpPacket {
648 public:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000649 Nack() : RtcpPacket() {
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000650 memset(&nack_, 0, sizeof(nack_));
651 }
652
653 virtual ~Nack() {}
654
655 void From(uint32_t ssrc) {
656 nack_.SenderSSRC = ssrc;
657 }
658 void To(uint32_t ssrc) {
659 nack_.MediaSSRC = ssrc;
660 }
661 void WithList(const uint16_t* nack_list, int length);
662
663 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200664 bool Create(uint8_t* packet,
665 size_t* index,
666 size_t max_length,
667 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000668
Erik Språnga3b87692015-07-29 10:46:54 +0200669 size_t BlockLength() const override;
670
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000671 private:
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000672
673 RTCPUtility::RTCPPacketRTPFBNACK nack_;
674 std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_;
675
henrikg3c089d72015-09-16 05:37:44 -0700676 RTC_DISALLOW_COPY_AND_ASSIGN(Nack);
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000677};
678
679// Reference picture selection indication (RPSI) (RFC 4585).
680//
681// FCI:
682//
683// 0 1 2 3
684// 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
685// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
686// | PB |0| Payload Type| Native RPSI bit string |
687// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
688// | defined per codec ... | Padding (0) |
689// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
690
691class Rpsi : public RtcpPacket {
692 public:
693 Rpsi()
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000694 : RtcpPacket(),
695 padding_bytes_(0) {
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000696 memset(&rpsi_, 0, sizeof(rpsi_));
697 }
698
699 virtual ~Rpsi() {}
700
701 void From(uint32_t ssrc) {
702 rpsi_.SenderSSRC = ssrc;
703 }
704 void To(uint32_t ssrc) {
705 rpsi_.MediaSSRC = ssrc;
706 }
707 void WithPayloadType(uint8_t payload) {
708 assert(payload <= 0x7f);
709 rpsi_.PayloadType = payload;
710 }
711 void WithPictureId(uint64_t picture_id);
712
713 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200714 bool Create(uint8_t* packet,
715 size_t* index,
716 size_t max_length,
717 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000718
719 private:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000720 size_t BlockLength() const {
721 size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_;
722 return kCommonFbFmtLength + fci_length;
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000723 }
724
725 uint8_t padding_bytes_;
726 RTCPUtility::RTCPPacketPSFBRPSI rpsi_;
727
henrikg3c089d72015-09-16 05:37:44 -0700728 RTC_DISALLOW_COPY_AND_ASSIGN(Rpsi);
asapersson@webrtc.orga8260062014-05-20 09:53:51 +0000729};
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000730
731// Full intra request (FIR) (RFC 5104).
732//
733// FCI:
734//
735// 0 1 2 3
736// 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
737// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
738// | SSRC |
739// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
740// | Seq nr. | Reserved |
741// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
742
743class Fir : public RtcpPacket {
744 public:
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000745 Fir() : RtcpPacket() {
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000746 memset(&fir_, 0, sizeof(fir_));
747 memset(&fir_item_, 0, sizeof(fir_item_));
748 }
749
750 virtual ~Fir() {}
751
752 void From(uint32_t ssrc) {
753 fir_.SenderSSRC = ssrc;
754 }
755 void To(uint32_t ssrc) {
756 fir_item_.SSRC = ssrc;
757 }
758 void WithCommandSeqNum(uint8_t seq_num) {
759 fir_item_.CommandSequenceNumber = seq_num;
760 }
761
762 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200763 bool Create(uint8_t* packet,
764 size_t* index,
765 size_t max_length,
766 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000767
768 private:
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +0000769 size_t BlockLength() const {
770 const size_t kFciLength = 8;
771 return kCommonFbFmtLength + kFciLength;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +0000772 }
773
774 RTCPUtility::RTCPPacketPSFBFIR fir_;
775 RTCPUtility::RTCPPacketPSFBFIRItem fir_item_;
776};
777
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000778// Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104).
779//
780// FCI:
781//
782// 0 1 2 3
783// 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
784// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
785// | SSRC |
786// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
787// | MxTBR Exp | MxTBR Mantissa |Measured Overhead|
788// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
789
790class Tmmbr : public RtcpPacket {
791 public:
792 Tmmbr() : RtcpPacket() {
793 memset(&tmmbr_, 0, sizeof(tmmbr_));
794 memset(&tmmbr_item_, 0, sizeof(tmmbr_item_));
795 }
796
797 virtual ~Tmmbr() {}
798
799 void From(uint32_t ssrc) {
800 tmmbr_.SenderSSRC = ssrc;
801 }
802 void To(uint32_t ssrc) {
803 tmmbr_item_.SSRC = ssrc;
804 }
805 void WithBitrateKbps(uint32_t bitrate_kbps) {
806 tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps;
807 }
808 void WithOverhead(uint16_t overhead) {
809 assert(overhead <= 0x1ff);
810 tmmbr_item_.MeasuredOverhead = overhead;
811 }
812
813 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200814 bool Create(uint8_t* packet,
815 size_t* index,
816 size_t max_length,
817 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000818
819 private:
820 size_t BlockLength() const {
821 const size_t kFciLen = 8;
822 return kCommonFbFmtLength + kFciLen;
823 }
824
825 RTCPUtility::RTCPPacketRTPFBTMMBR tmmbr_;
826 RTCPUtility::RTCPPacketRTPFBTMMBRItem tmmbr_item_;
827
henrikg3c089d72015-09-16 05:37:44 -0700828 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000829};
830
831// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
832//
833// FCI:
834//
835// 0 1 2 3
836// 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
837// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
838// | SSRC |
839// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
840// | MxTBR Exp | MxTBR Mantissa |Measured Overhead|
841// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
842
843class Tmmbn : public RtcpPacket {
844 public:
845 Tmmbn() : RtcpPacket() {
846 memset(&tmmbn_, 0, sizeof(tmmbn_));
847 }
848
849 virtual ~Tmmbn() {}
850
851 void From(uint32_t ssrc) {
852 tmmbn_.SenderSSRC = ssrc;
853 }
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200854 // Max 50 TMMBR can be added per TMMBN.
855 bool WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000856
857 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200858 bool Create(uint8_t* packet,
859 size_t* index,
860 size_t max_length,
861 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000862
863 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200864 static const int kMaxNumberOfTmmbrs = 50;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000865
866 size_t BlockLength() const {
867 const size_t kFciLen = 8;
868 return kCommonFbFmtLength + kFciLen * tmmbn_items_.size();
869 }
870
871 RTCPUtility::RTCPPacketRTPFBTMMBN tmmbn_;
872 std::vector<RTCPUtility::RTCPPacketRTPFBTMMBRItem> tmmbn_items_;
873
henrikg3c089d72015-09-16 05:37:44 -0700874 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbn);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000875};
876
877// Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
878//
879// 0 1 2 3
880// 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
881// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
882// |V=2|P| FMT=15 | PT=206 | length |
883// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
884// | SSRC of packet sender |
885// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
886// | SSRC of media source |
887// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
888// | Unique identifier 'R' 'E' 'M' 'B' |
889// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
890// | Num SSRC | BR Exp | BR Mantissa |
891// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
892// | SSRC feedback |
893// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
894// | ...
895
896class Remb : public RtcpPacket {
897 public:
898 Remb() : RtcpPacket() {
899 memset(&remb_, 0, sizeof(remb_));
900 memset(&remb_item_, 0, sizeof(remb_item_));
901 }
902
903 virtual ~Remb() {}
904
905 void From(uint32_t ssrc) {
906 remb_.SenderSSRC = ssrc;
907 }
908 void AppliesTo(uint32_t ssrc);
909
910 void WithBitrateBps(uint32_t bitrate_bps) {
911 remb_item_.BitRate = bitrate_bps;
912 }
913
914 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200915 bool Create(uint8_t* packet,
916 size_t* index,
917 size_t max_length,
918 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000919
920 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200921 static const int kMaxNumberOfSsrcs = 0xff;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000922
923 size_t BlockLength() const {
924 return (remb_item_.NumberOfSSRCs + 5) * 4;
925 }
926
927 RTCPUtility::RTCPPacketPSFBAPP remb_;
928 RTCPUtility::RTCPPacketPSFBREMBItem remb_item_;
929
henrikg3c089d72015-09-16 05:37:44 -0700930 RTC_DISALLOW_COPY_AND_ASSIGN(Remb);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000931};
932
933// From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR).
934//
935// Format for XR packets:
936//
937// 0 1 2 3
938// 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
939// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
940// |V=2|P|reserved | PT=XR=207 | length |
941// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
942// | SSRC |
943// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
944// : report blocks :
945// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
946
947class Xr : public RtcpPacket {
948 public:
949 typedef std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> DlrrBlock;
950 Xr() : RtcpPacket() {
951 memset(&xr_header_, 0, sizeof(xr_header_));
952 }
953
954 virtual ~Xr() {}
955
956 void From(uint32_t ssrc) {
957 xr_header_.OriginatorSSRC = ssrc;
958 }
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200959
960 // Max 50 items of each of {Rrtr, Dlrr, VoipMetric} allowed per Xr.
961 bool WithRrtr(Rrtr* rrtr);
962 bool WithDlrr(Dlrr* dlrr);
963 bool WithVoipMetric(VoipMetric* voip_metric);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000964
965 protected:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200966 bool Create(uint8_t* packet,
967 size_t* index,
968 size_t max_length,
969 RtcpPacket::PacketReadyCallback* callback) const override;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000970
971 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +0200972 static const int kMaxNumberOfRrtrBlocks = 50;
973 static const int kMaxNumberOfDlrrBlocks = 50;
974 static const int kMaxNumberOfVoipMetricBlocks = 50;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000975
976 size_t BlockLength() const {
977 const size_t kXrHeaderLength = 8;
978 return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength();
979 }
980
981 size_t RrtrLength() const {
982 const size_t kRrtrBlockLength = 12;
983 return kRrtrBlockLength * rrtr_blocks_.size();
984 }
985
986 size_t DlrrLength() const;
987
988 size_t VoipMetricLength() const {
989 const size_t kVoipMetricBlockLength = 36;
990 return kVoipMetricBlockLength * voip_metric_blocks_.size();
991 }
992
993 RTCPUtility::RTCPPacketXR xr_header_;
994 std::vector<RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem> rrtr_blocks_;
995 std::vector<DlrrBlock> dlrr_blocks_;
996 std::vector<RTCPUtility::RTCPPacketXRVOIPMetricItem> voip_metric_blocks_;
997
henrikg3c089d72015-09-16 05:37:44 -0700998 RTC_DISALLOW_COPY_AND_ASSIGN(Xr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +0000999};
1000
1001// Receiver Reference Time Report Block (RFC 3611).
1002//
1003// 0 1 2 3
1004// 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
1005// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1006// | BT=4 | reserved | block length = 2 |
1007// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1008// | NTP timestamp, most significant word |
1009// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1010// | NTP timestamp, least significant word |
1011// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1012
1013class Rrtr {
1014 public:
1015 Rrtr() {
1016 memset(&rrtr_block_, 0, sizeof(rrtr_block_));
1017 }
1018 ~Rrtr() {}
1019
1020 void WithNtpSec(uint32_t sec) {
1021 rrtr_block_.NTPMostSignificant = sec;
1022 }
1023 void WithNtpFrac(uint32_t frac) {
1024 rrtr_block_.NTPLeastSignificant = frac;
1025 }
1026
1027 private:
1028 friend class Xr;
1029 RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem rrtr_block_;
1030
henrikg3c089d72015-09-16 05:37:44 -07001031 RTC_DISALLOW_COPY_AND_ASSIGN(Rrtr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +00001032};
1033
1034// DLRR Report Block (RFC 3611).
1035//
1036// 0 1 2 3
1037// 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
1038// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1039// | BT=5 | reserved | block length |
1040// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1041// | SSRC_1 (SSRC of first receiver) | sub-
1042// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
1043// | last RR (LRR) | 1
1044// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1045// | delay since last RR (DLRR) |
1046// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1047// | SSRC_2 (SSRC of second receiver) | sub-
1048// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
1049// : ... : 2
1050
1051class Dlrr {
1052 public:
1053 Dlrr() {}
1054 ~Dlrr() {}
1055
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001056 // Max 100 DLRR Items can be added per DLRR report block.
1057 bool WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +00001058
1059 private:
1060 friend class Xr;
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001061 static const int kMaxNumberOfDlrrItems = 100;
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +00001062
1063 std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> dlrr_block_;
1064
henrikg3c089d72015-09-16 05:37:44 -07001065 RTC_DISALLOW_COPY_AND_ASSIGN(Dlrr);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +00001066};
1067
1068// VoIP Metrics Report Block (RFC 3611).
1069//
1070// 0 1 2 3
1071// 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
1072// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1073// | BT=7 | reserved | block length = 8 |
1074// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1075// | SSRC of source |
1076// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1077// | loss rate | discard rate | burst density | gap density |
1078// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1079// | burst duration | gap duration |
1080// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1081// | round trip delay | end system delay |
1082// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1083// | signal level | noise level | RERL | Gmin |
1084// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1085// | R factor | ext. R factor | MOS-LQ | MOS-CQ |
1086// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1087// | RX config | reserved | JB nominal |
1088// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1089// | JB maximum | JB abs max |
1090// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1091
1092class VoipMetric {
1093 public:
1094 VoipMetric() {
1095 memset(&metric_, 0, sizeof(metric_));
1096 }
1097 ~VoipMetric() {}
1098
1099 void To(uint32_t ssrc) { metric_.SSRC = ssrc; }
1100 void LossRate(uint8_t loss_rate) { metric_.lossRate = loss_rate; }
1101 void DiscardRate(uint8_t discard_rate) { metric_.discardRate = discard_rate; }
1102 void BurstDensity(uint8_t burst_density) {
1103 metric_.burstDensity = burst_density;
1104 }
1105 void GapDensity(uint8_t gap_density) { metric_.gapDensity = gap_density; }
1106 void BurstDuration(uint16_t burst_duration) {
1107 metric_.burstDuration = burst_duration;
1108 }
1109 void GapDuration(uint16_t gap_duration) {
1110 metric_.gapDuration = gap_duration;
1111 }
1112 void RoundTripDelay(uint16_t round_trip_delay) {
1113 metric_.roundTripDelay = round_trip_delay;
1114 }
1115 void EndSystemDelay(uint16_t end_system_delay) {
1116 metric_.endSystemDelay = end_system_delay;
1117 }
1118 void SignalLevel(uint8_t signal_level) { metric_.signalLevel = signal_level; }
1119 void NoiseLevel(uint8_t noise_level) { metric_.noiseLevel = noise_level; }
1120 void Rerl(uint8_t rerl) { metric_.RERL = rerl; }
1121 void Gmin(uint8_t gmin) { metric_.Gmin = gmin; }
1122 void Rfactor(uint8_t rfactor) { metric_.Rfactor = rfactor; }
1123 void ExtRfactor(uint8_t extrfactor) { metric_.extRfactor = extrfactor; }
1124 void MosLq(uint8_t moslq) { metric_.MOSLQ = moslq; }
1125 void MosCq(uint8_t moscq) { metric_.MOSCQ = moscq; }
1126 void RxConfig(uint8_t rxconfig) { metric_.RXconfig = rxconfig; }
1127 void JbNominal(uint16_t jbnominal) { metric_.JBnominal = jbnominal; }
1128 void JbMax(uint16_t jbmax) { metric_.JBmax = jbmax; }
1129 void JbAbsMax(uint16_t jbabsmax) { metric_.JBabsMax = jbabsmax; }
1130
1131 private:
1132 friend class Xr;
1133 RTCPUtility::RTCPPacketXRVOIPMetricItem metric_;
1134
henrikg3c089d72015-09-16 05:37:44 -07001135 RTC_DISALLOW_COPY_AND_ASSIGN(VoipMetric);
asapersson@webrtc.org3b84b3a2014-06-25 12:22:17 +00001136};
1137
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001138// Class holding a RTCP packet.
1139//
1140// Takes a built rtcp packet.
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +00001141// RawPacket raw_packet(buffer, length);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001142//
1143// To access the raw packet:
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001144// raw_packet.Buffer(); - pointer to the raw packet
1145// raw_packet.BufferLength(); - the length of the raw packet
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001146
1147class RawPacket {
1148 public:
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001149 explicit RawPacket(size_t buffer_length);
1150 RawPacket(const uint8_t* packet, size_t packet_length);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001151
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001152 const uint8_t* Buffer() const;
1153 uint8_t* MutableBuffer();
1154 size_t BufferLength() const;
1155 size_t Length() const;
1156 void SetLength(size_t length);
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001157
1158 private:
Erik Språngc1b9d4e2015-06-08 09:54:14 +02001159 const size_t buffer_length_;
1160 size_t length_;
1161 rtc::scoped_ptr<uint8_t[]> buffer_;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001162};
1163
1164} // namespace rtcp
1165} // namespace webrtc
1166#endif // WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_