blob: 13ad808b9da54ff9cd51976376359a372abb396b [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
15#include <vector>
16
17#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
18#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
19#include "webrtc/typedefs.h"
20
21namespace webrtc {
22namespace rtcp {
23
24class RawPacket;
25class ReportBlock;
26
27// Class for building RTCP packets.
28//
29// Example:
30// ReportBlock report_block;
31// report_block.To(234)
32// report_block.FractionLost(10);
33//
34// ReceiverReport rr;
35// rr.From(123);
36// rr.WithReportBlock(&report_block)
37//
38// Fir fir;
39// fir.From(123);
40// fir.To(234)
41// fir.WithCommandSeqNum(123);
42//
43// uint16_t len = 0; // Builds an intra frame request
44// uint8_t packet[kPacketSize]; // with sequence number 123.
45// fir.Build(packet, &len, kPacketSize);
46//
47// RawPacket packet = fir.Build(); // Returns a RawPacket holding
48// // the built rtcp packet.
49//
50// rr.Append(&fir) // Builds a compound RTCP packet with
51// RawPacket packet = rr.Build(); // a receiver report, report block
52// // and fir message.
53
54class RtcpPacket {
55 public:
56 virtual ~RtcpPacket() {}
57
58 void Append(RtcpPacket* packet);
59
60 RawPacket Build() const;
61
62 void Build(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
63
64 protected:
65 RtcpPacket() {}
66
67 virtual void Create(
68 uint8_t* packet, uint16_t* len, uint16_t max_len) const = 0;
69
70 void CreateAndAddAppended(
71 uint8_t* packet, uint16_t* len, uint16_t max_len) const;
72
73 private:
74 std::vector<RtcpPacket*> appended_packets_;
75};
76
77class Empty : public RtcpPacket {
78 public:
79 Empty() {}
80
81 virtual ~Empty() {}
82
83 protected:
84 virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
85};
86
87//// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
88//
89// RTCP sender report (RFC 3550).
90//
91// 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
92// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
93// |V=2|P| RC | PT=SR=200 | length |
94// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
95// | SSRC of sender |
96// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
97// | NTP timestamp, most significant word |
98// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99// | NTP timestamp, least significant word |
100// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101// | RTP timestamp |
102// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103// | sender's packet count |
104// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105// | sender's octet count |
106// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
107// | report block(s) |
108// | .... |
109
110class SenderReport : public RtcpPacket {
111 public:
112 SenderReport()
113 : RtcpPacket() {
114 memset(&sr_, 0, sizeof(sr_));
115 }
116
117 virtual ~SenderReport() {}
118
119 void From(uint32_t ssrc) {
120 sr_.SenderSSRC = ssrc;
121 }
122 void WithNtpSec(uint32_t sec) {
123 sr_.NTPMostSignificant = sec;
124 }
125 void WithNtpFrac(uint32_t frac) {
126 sr_.NTPLeastSignificant = frac;
127 }
128 void WithRtpTimestamp(uint32_t rtp_timestamp) {
129 sr_.RTPTimestamp = rtp_timestamp;
130 }
131 void WithPacketCount(uint32_t packet_count) {
132 sr_.SenderPacketCount = packet_count;
133 }
134 void WithOctetCount(uint32_t octet_count) {
135 sr_.SenderOctetCount = octet_count;
136 }
137 void WithReportBlock(ReportBlock* block);
138
139 enum { kMaxNumberOfReportBlocks = 0x1f };
140
141 protected:
142 virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
143
144 private:
145 uint16_t Length() const {
146 const uint16_t kSrBlockLen = 28;
147 const uint16_t kReportBlockLen = 24;
148 return kSrBlockLen + report_blocks_.size() * kReportBlockLen;
149 }
150
151 RTCPUtility::RTCPPacketSR sr_;
152 std::vector<ReportBlock*> report_blocks_;
153};
154
155//
156// RTCP receiver report (RFC 3550).
157//
158// 0 1 2 3
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=RR=201 | length |
162// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163// | SSRC of packet sender |
164// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
165// | report block(s) |
166// | .... |
167
168class ReceiverReport : public RtcpPacket {
169 public:
170 ReceiverReport()
171 : RtcpPacket() {
172 memset(&rr_, 0, sizeof(rr_));
173 }
174
175 virtual ~ReceiverReport() {}
176
177 void From(uint32_t ssrc) {
178 rr_.SenderSSRC = ssrc;
179 }
180 void WithReportBlock(ReportBlock* block);
181
182 enum { kMaxNumberOfReportBlocks = 0x1f };
183
184 protected:
185 virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
186
187 private:
188 uint16_t Length() const {
189 const uint16_t kRrBlockLen = 8;
190 const uint16_t kReportBlockLen = 24;
191 return kRrBlockLen + report_blocks_.size() * kReportBlockLen;
192 }
193
194 RTCPUtility::RTCPPacketRR rr_;
195 std::vector<ReportBlock*> report_blocks_;
196};
197
198//
199// RTCP report block (RFC 3550).
200//
201// 0 1 2 3
202// 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
203// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
204// | SSRC_1 (SSRC of first source) |
205// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
206// | fraction lost | cumulative number of packets lost |
207// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
208// | extended highest sequence number received |
209// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
210// | interarrival jitter |
211// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
212// | last SR (LSR) |
213// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
214// | delay since last SR (DLSR) |
215// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
216
217class ReportBlock {
218 public:
219 ReportBlock() {
220 memset(&report_block_, 0, sizeof(report_block_));
221 }
222
223 ~ReportBlock() {}
224
225 void To(uint32_t ssrc) {
226 report_block_.SSRC = ssrc;
227 }
228 void WithFractionLost(uint8_t fraction_lost) {
229 report_block_.FractionLost = fraction_lost;
230 }
231 void WithCumPacketsLost(uint32_t cum_packets_lost) {
232 report_block_.CumulativeNumOfPacketsLost = cum_packets_lost;
233 }
234 void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) {
235 report_block_.ExtendedHighestSequenceNumber = ext_highest_seq_num;
236 }
237 void WithJitter(uint32_t jitter) {
238 report_block_.Jitter = jitter;
239 }
240 void WithLastSr(uint32_t last_sr) {
241 report_block_.LastSR = last_sr;
242 }
243 void WithDelayLastSr(uint32_t delay_last_sr) {
244 report_block_.DelayLastSR = delay_last_sr;
245 }
246
247 void Create(uint8_t* array, uint16_t* cur_pos) const;
248
249 private:
250 RTCPUtility::RTCPPacketReportBlockItem report_block_;
251};
252
253//
254// Bye packet (BYE) (RFC 3550).
255//
256// 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
257// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
258// |V=2|P| SC | PT=BYE=203 | length |
259// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
260// | SSRC/CSRC |
261// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
262// : ... :
263// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
264// (opt) | length | reason for leaving ...
265// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
266
267class Bye : public RtcpPacket {
268 public:
269 Bye()
270 : RtcpPacket() {
271 memset(&bye_, 0, sizeof(bye_));
272 }
273
274 virtual ~Bye() {}
275
276 void From(uint32_t ssrc) {
277 bye_.SenderSSRC = ssrc;
278 }
279 void WithCsrc(uint32_t csrc);
280
281 enum { kMaxNumberOfCsrcs = 0x1f - 1 };
282
283 protected:
284 virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
285
286 private:
287 uint16_t Length() const {
288 const uint16_t kByeBlockLen = 8 + 4*csrcs_.size();
289 return kByeBlockLen;
290 }
291
292 RTCPUtility::RTCPPacketBYE bye_;
293 std::vector<uint32_t> csrcs_;
294};
295
296// RFC 4585: Feedback format.
297//
298// Common packet format:
299//
300// 0 1 2 3
301// 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
302// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
303// |V=2|P| FMT | PT | length |
304// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
305// | SSRC of packet sender |
306// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
307// | SSRC of media source |
308// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
309// : Feedback Control Information (FCI) :
310// :
311
312
313// Full intra request (FIR) (RFC 5104).
314//
315// FCI:
316//
317// 0 1 2 3
318// 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
319// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
320// | SSRC |
321// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
322// | Seq nr. | Reserved |
323// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
324
325class Fir : public RtcpPacket {
326 public:
327 Fir()
328 : RtcpPacket() {
329 memset(&fir_, 0, sizeof(fir_));
330 memset(&fir_item_, 0, sizeof(fir_item_));
331 }
332
333 virtual ~Fir() {}
334
335 void From(uint32_t ssrc) {
336 fir_.SenderSSRC = ssrc;
337 }
338 void To(uint32_t ssrc) {
339 fir_item_.SSRC = ssrc;
340 }
341 void WithCommandSeqNum(uint8_t seq_num) {
342 fir_item_.CommandSequenceNumber = seq_num;
343 }
344
345 protected:
346 virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
347
348 private:
349 uint16_t Length() const {
350 const uint16_t kFirBlockLen = 20;
351 return kFirBlockLen;
352 }
353
354 RTCPUtility::RTCPPacketPSFBFIR fir_;
355 RTCPUtility::RTCPPacketPSFBFIRItem fir_item_;
356};
357
358// Class holding a RTCP packet.
359//
360// Takes a built rtcp packet.
361// RawPacket raw_packet(buffer, len);
362//
363// To access the raw packet:
364// raw_packet.buffer(); - pointer to the raw packet
365// raw_packet.buffer_length(); - the length of the raw packet
366
367class RawPacket {
368 public:
369 RawPacket(const uint8_t* buffer, uint16_t len) {
370 assert(len <= IP_PACKET_SIZE);
371 memcpy(packet_, buffer, len);
372 packet_length_ = len;
373 }
374
375 const uint8_t* buffer() {
376 return packet_;
377 }
378 uint16_t buffer_length() const {
379 return packet_length_;
380 }
381
382 private:
383 uint16_t packet_length_;
384 uint8_t packet_[IP_PACKET_SIZE];
385};
386
387} // namespace rtcp
388} // namespace webrtc
389#endif // WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_