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