rtcp_packet.h revision ef3d805f6e50bc488f8e4e9e353068b78c73d17f
1/* 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_SOURCE_RTCP_PACKET_H_ 13#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_ 14 15#include <map> 16#include <string> 17#include <vector> 18 19#include "webrtc/base/scoped_ptr.h" 20#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 21#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/dlrr.h" 22#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h" 23#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.h" 24#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.h" 25#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" 26#include "webrtc/typedefs.h" 27 28namespace webrtc { 29namespace rtcp { 30 31static const int kCommonFbFmtLength = 12; 32static const int kReportBlockLength = 24; 33 34class RawPacket; 35 36// Class for building RTCP packets. 37// 38// Example: 39// ReportBlock report_block; 40// report_block.To(234) 41// report_block.FractionLost(10); 42// 43// ReceiverReport rr; 44// rr.From(123); 45// rr.WithReportBlock(&report_block) 46// 47// Fir fir; 48// fir.From(123); 49// fir.To(234) 50// fir.WithCommandSeqNum(123); 51// 52// size_t length = 0; // Builds an intra frame request 53// uint8_t packet[kPacketSize]; // with sequence number 123. 54// fir.Build(packet, &length, kPacketSize); 55// 56// RawPacket packet = fir.Build(); // Returns a RawPacket holding 57// // the built rtcp packet. 58// 59// rr.Append(&fir) // Builds a compound RTCP packet with 60// RawPacket packet = rr.Build(); // a receiver report, report block 61// // and fir message. 62 63class RtcpPacket { 64 public: 65 virtual ~RtcpPacket() {} 66 67 void Append(RtcpPacket* packet); 68 69 // Callback used to signal that an RTCP packet is ready. Note that this may 70 // not contain all data in this RtcpPacket; if a packet cannot fit in 71 // max_length bytes, it will be fragmented and multiple calls to this 72 // callback will be made. 73 class PacketReadyCallback { 74 public: 75 PacketReadyCallback() {} 76 virtual ~PacketReadyCallback() {} 77 78 virtual void OnPacketReady(uint8_t* data, size_t length) = 0; 79 }; 80 81 // Convenience method mostly used for test. Max length of IP_PACKET_SIZE is 82 // used, will cause assertion error if fragmentation occurs. 83 rtc::scoped_ptr<RawPacket> Build() const; 84 85 // Returns true if all calls to Create succeeded. A buffer of size 86 // IP_PACKET_SIZE will be allocated and reused between calls to callback. 87 bool Build(PacketReadyCallback* callback) const; 88 89 // Returns true if all calls to Create succeeded. Provided buffer reference 90 // will be used for all calls to callback. 91 bool BuildExternalBuffer(uint8_t* buffer, 92 size_t max_length, 93 PacketReadyCallback* callback) const; 94 95 // Size of this packet in bytes (including headers, excluding nested packets). 96 virtual size_t BlockLength() const = 0; 97 98 protected: 99 RtcpPacket() {} 100 101 virtual bool Create(uint8_t* packet, 102 size_t* index, 103 size_t max_length, 104 PacketReadyCallback* callback) const = 0; 105 106 static void CreateHeader(uint8_t count_or_format, 107 uint8_t packet_type, 108 size_t block_length, // Size in 32bit words - 1. 109 uint8_t* buffer, 110 size_t* pos); 111 112 bool OnBufferFull(uint8_t* packet, 113 size_t* index, 114 RtcpPacket::PacketReadyCallback* callback) const; 115 116 size_t HeaderLength() const; 117 118 static const size_t kHeaderLength = 4; 119 std::vector<RtcpPacket*> appended_packets_; 120 121 private: 122 bool CreateAndAddAppended(uint8_t* packet, 123 size_t* index, 124 size_t max_length, 125 PacketReadyCallback* callback) const; 126}; 127 128// TODO(sprang): Move RtcpPacket subclasses out to separate files. 129 130class Empty : public RtcpPacket { 131 public: 132 Empty() : RtcpPacket() {} 133 134 virtual ~Empty() {} 135 136 protected: 137 bool Create(uint8_t* packet, 138 size_t* index, 139 size_t max_length, 140 RtcpPacket::PacketReadyCallback* callback) const override; 141 142 size_t BlockLength() const override; 143 144 private: 145 RTC_DISALLOW_COPY_AND_ASSIGN(Empty); 146}; 147 148// RTCP sender report (RFC 3550). 149// 150// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 151// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 152// |V=2|P| RC | PT=SR=200 | length | 153// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 154// | SSRC of sender | 155// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 156// | NTP timestamp, most significant word | 157// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 158// | NTP timestamp, least significant word | 159// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 160// | RTP timestamp | 161// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 162// | sender's packet count | 163// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 164// | sender's octet count | 165// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 166// | report block(s) | 167// | .... | 168 169class SenderReport : public RtcpPacket { 170 public: 171 SenderReport() : RtcpPacket() { 172 memset(&sr_, 0, sizeof(sr_)); 173 } 174 175 virtual ~SenderReport() {} 176 177 void From(uint32_t ssrc) { 178 sr_.SenderSSRC = ssrc; 179 } 180 void WithNtpSec(uint32_t sec) { 181 sr_.NTPMostSignificant = sec; 182 } 183 void WithNtpFrac(uint32_t frac) { 184 sr_.NTPLeastSignificant = frac; 185 } 186 void WithRtpTimestamp(uint32_t rtp_timestamp) { 187 sr_.RTPTimestamp = rtp_timestamp; 188 } 189 void WithPacketCount(uint32_t packet_count) { 190 sr_.SenderPacketCount = packet_count; 191 } 192 void WithOctetCount(uint32_t octet_count) { 193 sr_.SenderOctetCount = octet_count; 194 } 195 bool WithReportBlock(const ReportBlock& block); 196 197 protected: 198 bool Create(uint8_t* packet, 199 size_t* index, 200 size_t max_length, 201 RtcpPacket::PacketReadyCallback* callback) const override; 202 203 private: 204 static const int kMaxNumberOfReportBlocks = 0x1f; 205 206 size_t BlockLength() const { 207 const size_t kSrHeaderLength = 8; 208 const size_t kSenderInfoLength = 20; 209 return kSrHeaderLength + kSenderInfoLength + 210 report_blocks_.size() * kReportBlockLength; 211 } 212 213 RTCPUtility::RTCPPacketSR sr_; 214 std::vector<ReportBlock> report_blocks_; 215 216 RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport); 217}; 218 219// Source Description (SDES) (RFC 3550). 220// 221// 0 1 2 3 222// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 223// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 224// header |V=2|P| SC | PT=SDES=202 | length | 225// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 226// chunk | SSRC/CSRC_1 | 227// 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 228// | SDES items | 229// | ... | 230// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 231// chunk | SSRC/CSRC_2 | 232// 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 233// | SDES items | 234// | ... | 235// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 236// 237// Canonical End-Point Identifier SDES Item (CNAME) 238// 239// 0 1 2 3 240// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 241// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 242// | CNAME=1 | length | user and domain name ... 243// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 244 245class Sdes : public RtcpPacket { 246 public: 247 Sdes() : RtcpPacket() {} 248 249 virtual ~Sdes() {} 250 251 bool WithCName(uint32_t ssrc, const std::string& cname); 252 253 struct Chunk { 254 uint32_t ssrc; 255 std::string name; 256 int null_octets; 257 }; 258 259 protected: 260 bool Create(uint8_t* packet, 261 size_t* index, 262 size_t max_length, 263 RtcpPacket::PacketReadyCallback* callback) const override; 264 265 private: 266 static const int kMaxNumberOfChunks = 0x1f; 267 268 size_t BlockLength() const; 269 270 std::vector<Chunk> chunks_; 271 272 RTC_DISALLOW_COPY_AND_ASSIGN(Sdes); 273}; 274 275// Slice loss indication (SLI) (RFC 4585). 276// 277// FCI: 278// 0 1 2 3 279// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 280// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 281// | First | Number | PictureID | 282// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 283 284class Sli : public RtcpPacket { 285 public: 286 Sli() : RtcpPacket() { 287 memset(&sli_, 0, sizeof(sli_)); 288 memset(&sli_item_, 0, sizeof(sli_item_)); 289 } 290 291 virtual ~Sli() {} 292 293 void From(uint32_t ssrc) { 294 sli_.SenderSSRC = ssrc; 295 } 296 void To(uint32_t ssrc) { 297 sli_.MediaSSRC = ssrc; 298 } 299 void WithFirstMb(uint16_t first_mb) { 300 assert(first_mb <= 0x1fff); 301 sli_item_.FirstMB = first_mb; 302 } 303 void WithNumberOfMb(uint16_t number_mb) { 304 assert(number_mb <= 0x1fff); 305 sli_item_.NumberOfMB = number_mb; 306 } 307 void WithPictureId(uint8_t picture_id) { 308 assert(picture_id <= 0x3f); 309 sli_item_.PictureId = picture_id; 310 } 311 312 protected: 313 bool Create(uint8_t* packet, 314 size_t* index, 315 size_t max_length, 316 RtcpPacket::PacketReadyCallback* callback) const override; 317 318 private: 319 size_t BlockLength() const { 320 const size_t kFciLength = 4; 321 return kCommonFbFmtLength + kFciLength; 322 } 323 324 RTCPUtility::RTCPPacketPSFBSLI sli_; 325 RTCPUtility::RTCPPacketPSFBSLIItem sli_item_; 326 327 RTC_DISALLOW_COPY_AND_ASSIGN(Sli); 328}; 329 330// Reference picture selection indication (RPSI) (RFC 4585). 331// 332// FCI: 333// 334// 0 1 2 3 335// 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 336// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 337// | PB |0| Payload Type| Native RPSI bit string | 338// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 339// | defined per codec ... | Padding (0) | 340// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 341 342class Rpsi : public RtcpPacket { 343 public: 344 Rpsi() 345 : RtcpPacket(), 346 padding_bytes_(0) { 347 memset(&rpsi_, 0, sizeof(rpsi_)); 348 } 349 350 virtual ~Rpsi() {} 351 352 void From(uint32_t ssrc) { 353 rpsi_.SenderSSRC = ssrc; 354 } 355 void To(uint32_t ssrc) { 356 rpsi_.MediaSSRC = ssrc; 357 } 358 void WithPayloadType(uint8_t payload) { 359 assert(payload <= 0x7f); 360 rpsi_.PayloadType = payload; 361 } 362 void WithPictureId(uint64_t picture_id); 363 364 protected: 365 bool Create(uint8_t* packet, 366 size_t* index, 367 size_t max_length, 368 RtcpPacket::PacketReadyCallback* callback) const override; 369 370 private: 371 size_t BlockLength() const { 372 size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_; 373 return kCommonFbFmtLength + fci_length; 374 } 375 376 uint8_t padding_bytes_; 377 RTCPUtility::RTCPPacketPSFBRPSI rpsi_; 378 379 RTC_DISALLOW_COPY_AND_ASSIGN(Rpsi); 380}; 381 382// Full intra request (FIR) (RFC 5104). 383// 384// FCI: 385// 386// 0 1 2 3 387// 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 388// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 389// | SSRC | 390// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 391// | Seq nr. | Reserved | 392// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 393 394class Fir : public RtcpPacket { 395 public: 396 Fir() : RtcpPacket() { 397 memset(&fir_, 0, sizeof(fir_)); 398 memset(&fir_item_, 0, sizeof(fir_item_)); 399 } 400 401 virtual ~Fir() {} 402 403 void From(uint32_t ssrc) { 404 fir_.SenderSSRC = ssrc; 405 } 406 void To(uint32_t ssrc) { 407 fir_item_.SSRC = ssrc; 408 } 409 void WithCommandSeqNum(uint8_t seq_num) { 410 fir_item_.CommandSequenceNumber = seq_num; 411 } 412 413 protected: 414 bool Create(uint8_t* packet, 415 size_t* index, 416 size_t max_length, 417 RtcpPacket::PacketReadyCallback* callback) const override; 418 419 private: 420 size_t BlockLength() const { 421 const size_t kFciLength = 8; 422 return kCommonFbFmtLength + kFciLength; 423 } 424 425 RTCPUtility::RTCPPacketPSFBFIR fir_; 426 RTCPUtility::RTCPPacketPSFBFIRItem fir_item_; 427}; 428 429// Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104). 430// 431// FCI: 432// 433// 0 1 2 3 434// 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 435// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 436// | SSRC | 437// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 438// | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 439// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 440 441class Tmmbr : public RtcpPacket { 442 public: 443 Tmmbr() : RtcpPacket() { 444 memset(&tmmbr_, 0, sizeof(tmmbr_)); 445 memset(&tmmbr_item_, 0, sizeof(tmmbr_item_)); 446 } 447 448 virtual ~Tmmbr() {} 449 450 void From(uint32_t ssrc) { 451 tmmbr_.SenderSSRC = ssrc; 452 } 453 void To(uint32_t ssrc) { 454 tmmbr_item_.SSRC = ssrc; 455 } 456 void WithBitrateKbps(uint32_t bitrate_kbps) { 457 tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps; 458 } 459 void WithOverhead(uint16_t overhead) { 460 assert(overhead <= 0x1ff); 461 tmmbr_item_.MeasuredOverhead = overhead; 462 } 463 464 protected: 465 bool Create(uint8_t* packet, 466 size_t* index, 467 size_t max_length, 468 RtcpPacket::PacketReadyCallback* callback) const override; 469 470 private: 471 size_t BlockLength() const { 472 const size_t kFciLen = 8; 473 return kCommonFbFmtLength + kFciLen; 474 } 475 476 RTCPUtility::RTCPPacketRTPFBTMMBR tmmbr_; 477 RTCPUtility::RTCPPacketRTPFBTMMBRItem tmmbr_item_; 478 479 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbr); 480}; 481 482// Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb). 483// 484// 0 1 2 3 485// 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 486// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 487// |V=2|P| FMT=15 | PT=206 | length | 488// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 489// | SSRC of packet sender | 490// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 491// | SSRC of media source | 492// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 493// | Unique identifier 'R' 'E' 'M' 'B' | 494// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 495// | Num SSRC | BR Exp | BR Mantissa | 496// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 497// | SSRC feedback | 498// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 499// | ... 500 501class Remb : public RtcpPacket { 502 public: 503 Remb() : RtcpPacket() { 504 memset(&remb_, 0, sizeof(remb_)); 505 memset(&remb_item_, 0, sizeof(remb_item_)); 506 } 507 508 virtual ~Remb() {} 509 510 void From(uint32_t ssrc) { 511 remb_.SenderSSRC = ssrc; 512 } 513 void AppliesTo(uint32_t ssrc); 514 515 void WithBitrateBps(uint32_t bitrate_bps) { 516 remb_item_.BitRate = bitrate_bps; 517 } 518 519 protected: 520 bool Create(uint8_t* packet, 521 size_t* index, 522 size_t max_length, 523 RtcpPacket::PacketReadyCallback* callback) const override; 524 525 private: 526 static const int kMaxNumberOfSsrcs = 0xff; 527 528 size_t BlockLength() const { 529 return (remb_item_.NumberOfSSRCs + 5) * 4; 530 } 531 532 RTCPUtility::RTCPPacketPSFBAPP remb_; 533 RTCPUtility::RTCPPacketPSFBREMBItem remb_item_; 534 535 RTC_DISALLOW_COPY_AND_ASSIGN(Remb); 536}; 537 538// From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR). 539// 540// Format for XR packets: 541// 542// 0 1 2 3 543// 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 544// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 545// |V=2|P|reserved | PT=XR=207 | length | 546// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 547// | SSRC | 548// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 549// : report blocks : 550// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 551 552class Xr : public RtcpPacket { 553 public: 554 typedef std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> DlrrBlock; 555 Xr() : RtcpPacket() { 556 memset(&xr_header_, 0, sizeof(xr_header_)); 557 } 558 559 virtual ~Xr() {} 560 561 void From(uint32_t ssrc) { 562 xr_header_.OriginatorSSRC = ssrc; 563 } 564 565 // Max 50 items of each of {Rrtr, Dlrr, VoipMetric} allowed per Xr. 566 bool WithRrtr(Rrtr* rrtr); 567 bool WithDlrr(Dlrr* dlrr); 568 bool WithVoipMetric(VoipMetric* voip_metric); 569 570 protected: 571 bool Create(uint8_t* packet, 572 size_t* index, 573 size_t max_length, 574 RtcpPacket::PacketReadyCallback* callback) const override; 575 576 private: 577 static const int kMaxNumberOfRrtrBlocks = 50; 578 static const int kMaxNumberOfDlrrBlocks = 50; 579 static const int kMaxNumberOfVoipMetricBlocks = 50; 580 581 size_t BlockLength() const { 582 const size_t kXrHeaderLength = 8; 583 return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength(); 584 } 585 586 size_t RrtrLength() const { return Rrtr::kLength * rrtr_blocks_.size(); } 587 588 size_t DlrrLength() const; 589 590 size_t VoipMetricLength() const { 591 return VoipMetric::kLength * voip_metric_blocks_.size(); 592 } 593 594 RTCPUtility::RTCPPacketXR xr_header_; 595 std::vector<Rrtr> rrtr_blocks_; 596 std::vector<Dlrr> dlrr_blocks_; 597 std::vector<VoipMetric> voip_metric_blocks_; 598 599 RTC_DISALLOW_COPY_AND_ASSIGN(Xr); 600}; 601 602// Class holding a RTCP packet. 603// 604// Takes a built rtcp packet. 605// RawPacket raw_packet(buffer, length); 606// 607// To access the raw packet: 608// raw_packet.Buffer(); - pointer to the raw packet 609// raw_packet.BufferLength(); - the length of the raw packet 610 611class RawPacket { 612 public: 613 explicit RawPacket(size_t buffer_length); 614 RawPacket(const uint8_t* packet, size_t packet_length); 615 616 const uint8_t* Buffer() const; 617 uint8_t* MutableBuffer(); 618 size_t BufferLength() const; 619 size_t Length() const; 620 void SetLength(size_t length); 621 622 private: 623 const size_t buffer_length_; 624 size_t length_; 625 rtc::scoped_ptr<uint8_t[]> buffer_; 626}; 627 628} // namespace rtcp 629} // namespace webrtc 630#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_ 631