rtcp_packet.h revision b8b6fbb7a5d2f5a14f7f6f81c253747aa28e4c7f
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/report_block.h" 22#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rrtr.h" 23#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" 24#include "webrtc/typedefs.h" 25 26namespace webrtc { 27namespace rtcp { 28 29static const int kCommonFbFmtLength = 12; 30static const int kReportBlockLength = 24; 31 32class Dlrr; 33class RawPacket; 34class VoipMetric; 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// Generic NACK (RFC 4585). 331// 332// FCI: 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// | PID | BLP | 337// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 338 339class Nack : public RtcpPacket { 340 public: 341 Nack() : RtcpPacket() { 342 memset(&nack_, 0, sizeof(nack_)); 343 } 344 345 virtual ~Nack() {} 346 347 void From(uint32_t ssrc) { 348 nack_.SenderSSRC = ssrc; 349 } 350 void To(uint32_t ssrc) { 351 nack_.MediaSSRC = ssrc; 352 } 353 void WithList(const uint16_t* nack_list, int length); 354 355 protected: 356 bool Create(uint8_t* packet, 357 size_t* index, 358 size_t max_length, 359 RtcpPacket::PacketReadyCallback* callback) const override; 360 361 size_t BlockLength() const override; 362 363 private: 364 RTCPUtility::RTCPPacketRTPFBNACK nack_; 365 std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_; 366 367 RTC_DISALLOW_COPY_AND_ASSIGN(Nack); 368}; 369 370// Reference picture selection indication (RPSI) (RFC 4585). 371// 372// FCI: 373// 374// 0 1 2 3 375// 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 376// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 377// | PB |0| Payload Type| Native RPSI bit string | 378// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 379// | defined per codec ... | Padding (0) | 380// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 381 382class Rpsi : public RtcpPacket { 383 public: 384 Rpsi() 385 : RtcpPacket(), 386 padding_bytes_(0) { 387 memset(&rpsi_, 0, sizeof(rpsi_)); 388 } 389 390 virtual ~Rpsi() {} 391 392 void From(uint32_t ssrc) { 393 rpsi_.SenderSSRC = ssrc; 394 } 395 void To(uint32_t ssrc) { 396 rpsi_.MediaSSRC = ssrc; 397 } 398 void WithPayloadType(uint8_t payload) { 399 assert(payload <= 0x7f); 400 rpsi_.PayloadType = payload; 401 } 402 void WithPictureId(uint64_t picture_id); 403 404 protected: 405 bool Create(uint8_t* packet, 406 size_t* index, 407 size_t max_length, 408 RtcpPacket::PacketReadyCallback* callback) const override; 409 410 private: 411 size_t BlockLength() const { 412 size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_; 413 return kCommonFbFmtLength + fci_length; 414 } 415 416 uint8_t padding_bytes_; 417 RTCPUtility::RTCPPacketPSFBRPSI rpsi_; 418 419 RTC_DISALLOW_COPY_AND_ASSIGN(Rpsi); 420}; 421 422// Full intra request (FIR) (RFC 5104). 423// 424// FCI: 425// 426// 0 1 2 3 427// 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 428// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 429// | SSRC | 430// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 431// | Seq nr. | Reserved | 432// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 433 434class Fir : public RtcpPacket { 435 public: 436 Fir() : RtcpPacket() { 437 memset(&fir_, 0, sizeof(fir_)); 438 memset(&fir_item_, 0, sizeof(fir_item_)); 439 } 440 441 virtual ~Fir() {} 442 443 void From(uint32_t ssrc) { 444 fir_.SenderSSRC = ssrc; 445 } 446 void To(uint32_t ssrc) { 447 fir_item_.SSRC = ssrc; 448 } 449 void WithCommandSeqNum(uint8_t seq_num) { 450 fir_item_.CommandSequenceNumber = seq_num; 451 } 452 453 protected: 454 bool Create(uint8_t* packet, 455 size_t* index, 456 size_t max_length, 457 RtcpPacket::PacketReadyCallback* callback) const override; 458 459 private: 460 size_t BlockLength() const { 461 const size_t kFciLength = 8; 462 return kCommonFbFmtLength + kFciLength; 463 } 464 465 RTCPUtility::RTCPPacketPSFBFIR fir_; 466 RTCPUtility::RTCPPacketPSFBFIRItem fir_item_; 467}; 468 469// Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104). 470// 471// FCI: 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// | SSRC | 477// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 478// | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 479// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 480 481class Tmmbr : public RtcpPacket { 482 public: 483 Tmmbr() : RtcpPacket() { 484 memset(&tmmbr_, 0, sizeof(tmmbr_)); 485 memset(&tmmbr_item_, 0, sizeof(tmmbr_item_)); 486 } 487 488 virtual ~Tmmbr() {} 489 490 void From(uint32_t ssrc) { 491 tmmbr_.SenderSSRC = ssrc; 492 } 493 void To(uint32_t ssrc) { 494 tmmbr_item_.SSRC = ssrc; 495 } 496 void WithBitrateKbps(uint32_t bitrate_kbps) { 497 tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps; 498 } 499 void WithOverhead(uint16_t overhead) { 500 assert(overhead <= 0x1ff); 501 tmmbr_item_.MeasuredOverhead = overhead; 502 } 503 504 protected: 505 bool Create(uint8_t* packet, 506 size_t* index, 507 size_t max_length, 508 RtcpPacket::PacketReadyCallback* callback) const override; 509 510 private: 511 size_t BlockLength() const { 512 const size_t kFciLen = 8; 513 return kCommonFbFmtLength + kFciLen; 514 } 515 516 RTCPUtility::RTCPPacketRTPFBTMMBR tmmbr_; 517 RTCPUtility::RTCPPacketRTPFBTMMBRItem tmmbr_item_; 518 519 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbr); 520}; 521 522// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104). 523// 524// FCI: 525// 526// 0 1 2 3 527// 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 528// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 529// | SSRC | 530// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 531// | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 532// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 533 534class Tmmbn : public RtcpPacket { 535 public: 536 Tmmbn() : RtcpPacket() { 537 memset(&tmmbn_, 0, sizeof(tmmbn_)); 538 } 539 540 virtual ~Tmmbn() {} 541 542 void From(uint32_t ssrc) { 543 tmmbn_.SenderSSRC = ssrc; 544 } 545 // Max 50 TMMBR can be added per TMMBN. 546 bool WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead); 547 548 protected: 549 bool Create(uint8_t* packet, 550 size_t* index, 551 size_t max_length, 552 RtcpPacket::PacketReadyCallback* callback) const override; 553 554 private: 555 static const int kMaxNumberOfTmmbrs = 50; 556 557 size_t BlockLength() const { 558 const size_t kFciLen = 8; 559 return kCommonFbFmtLength + kFciLen * tmmbn_items_.size(); 560 } 561 562 RTCPUtility::RTCPPacketRTPFBTMMBN tmmbn_; 563 std::vector<RTCPUtility::RTCPPacketRTPFBTMMBRItem> tmmbn_items_; 564 565 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbn); 566}; 567 568// Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb). 569// 570// 0 1 2 3 571// 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 572// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 573// |V=2|P| FMT=15 | PT=206 | length | 574// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 575// | SSRC of packet sender | 576// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 577// | SSRC of media source | 578// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 579// | Unique identifier 'R' 'E' 'M' 'B' | 580// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 581// | Num SSRC | BR Exp | BR Mantissa | 582// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 583// | SSRC feedback | 584// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 585// | ... 586 587class Remb : public RtcpPacket { 588 public: 589 Remb() : RtcpPacket() { 590 memset(&remb_, 0, sizeof(remb_)); 591 memset(&remb_item_, 0, sizeof(remb_item_)); 592 } 593 594 virtual ~Remb() {} 595 596 void From(uint32_t ssrc) { 597 remb_.SenderSSRC = ssrc; 598 } 599 void AppliesTo(uint32_t ssrc); 600 601 void WithBitrateBps(uint32_t bitrate_bps) { 602 remb_item_.BitRate = bitrate_bps; 603 } 604 605 protected: 606 bool Create(uint8_t* packet, 607 size_t* index, 608 size_t max_length, 609 RtcpPacket::PacketReadyCallback* callback) const override; 610 611 private: 612 static const int kMaxNumberOfSsrcs = 0xff; 613 614 size_t BlockLength() const { 615 return (remb_item_.NumberOfSSRCs + 5) * 4; 616 } 617 618 RTCPUtility::RTCPPacketPSFBAPP remb_; 619 RTCPUtility::RTCPPacketPSFBREMBItem remb_item_; 620 621 RTC_DISALLOW_COPY_AND_ASSIGN(Remb); 622}; 623 624// From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR). 625// 626// Format for XR packets: 627// 628// 0 1 2 3 629// 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 630// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 631// |V=2|P|reserved | PT=XR=207 | length | 632// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 633// | SSRC | 634// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 635// : report blocks : 636// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 637 638class Xr : public RtcpPacket { 639 public: 640 typedef std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> DlrrBlock; 641 Xr() : RtcpPacket() { 642 memset(&xr_header_, 0, sizeof(xr_header_)); 643 } 644 645 virtual ~Xr() {} 646 647 void From(uint32_t ssrc) { 648 xr_header_.OriginatorSSRC = ssrc; 649 } 650 651 // Max 50 items of each of {Rrtr, Dlrr, VoipMetric} allowed per Xr. 652 bool WithRrtr(Rrtr* rrtr); 653 bool WithDlrr(Dlrr* dlrr); 654 bool WithVoipMetric(VoipMetric* voip_metric); 655 656 protected: 657 bool Create(uint8_t* packet, 658 size_t* index, 659 size_t max_length, 660 RtcpPacket::PacketReadyCallback* callback) const override; 661 662 private: 663 static const int kMaxNumberOfRrtrBlocks = 50; 664 static const int kMaxNumberOfDlrrBlocks = 50; 665 static const int kMaxNumberOfVoipMetricBlocks = 50; 666 667 size_t BlockLength() const { 668 const size_t kXrHeaderLength = 8; 669 return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength(); 670 } 671 672 size_t RrtrLength() const { return Rrtr::kLength * rrtr_blocks_.size(); } 673 674 size_t DlrrLength() const; 675 676 size_t VoipMetricLength() const { 677 const size_t kVoipMetricBlockLength = 36; 678 return kVoipMetricBlockLength * voip_metric_blocks_.size(); 679 } 680 681 RTCPUtility::RTCPPacketXR xr_header_; 682 std::vector<Rrtr> rrtr_blocks_; 683 std::vector<DlrrBlock> dlrr_blocks_; 684 std::vector<RTCPUtility::RTCPPacketXRVOIPMetricItem> voip_metric_blocks_; 685 686 RTC_DISALLOW_COPY_AND_ASSIGN(Xr); 687}; 688 689// DLRR Report Block (RFC 3611). 690// 691// 0 1 2 3 692// 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 693// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 694// | BT=5 | reserved | block length | 695// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 696// | SSRC_1 (SSRC of first receiver) | sub- 697// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 698// | last RR (LRR) | 1 699// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 700// | delay since last RR (DLRR) | 701// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 702// | SSRC_2 (SSRC of second receiver) | sub- 703// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 704// : ... : 2 705 706class Dlrr { 707 public: 708 Dlrr() {} 709 ~Dlrr() {} 710 711 // Max 100 DLRR Items can be added per DLRR report block. 712 bool WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr); 713 714 private: 715 friend class Xr; 716 static const int kMaxNumberOfDlrrItems = 100; 717 718 std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> dlrr_block_; 719 720 RTC_DISALLOW_COPY_AND_ASSIGN(Dlrr); 721}; 722 723// VoIP Metrics Report Block (RFC 3611). 724// 725// 0 1 2 3 726// 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 727// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 728// | BT=7 | reserved | block length = 8 | 729// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 730// | SSRC of source | 731// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 732// | loss rate | discard rate | burst density | gap density | 733// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 734// | burst duration | gap duration | 735// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 736// | round trip delay | end system delay | 737// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 738// | signal level | noise level | RERL | Gmin | 739// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 740// | R factor | ext. R factor | MOS-LQ | MOS-CQ | 741// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 742// | RX config | reserved | JB nominal | 743// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 744// | JB maximum | JB abs max | 745// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 746 747class VoipMetric { 748 public: 749 VoipMetric() { 750 memset(&metric_, 0, sizeof(metric_)); 751 } 752 ~VoipMetric() {} 753 754 void To(uint32_t ssrc) { metric_.SSRC = ssrc; } 755 void LossRate(uint8_t loss_rate) { metric_.lossRate = loss_rate; } 756 void DiscardRate(uint8_t discard_rate) { metric_.discardRate = discard_rate; } 757 void BurstDensity(uint8_t burst_density) { 758 metric_.burstDensity = burst_density; 759 } 760 void GapDensity(uint8_t gap_density) { metric_.gapDensity = gap_density; } 761 void BurstDuration(uint16_t burst_duration) { 762 metric_.burstDuration = burst_duration; 763 } 764 void GapDuration(uint16_t gap_duration) { 765 metric_.gapDuration = gap_duration; 766 } 767 void RoundTripDelay(uint16_t round_trip_delay) { 768 metric_.roundTripDelay = round_trip_delay; 769 } 770 void EndSystemDelay(uint16_t end_system_delay) { 771 metric_.endSystemDelay = end_system_delay; 772 } 773 void SignalLevel(uint8_t signal_level) { metric_.signalLevel = signal_level; } 774 void NoiseLevel(uint8_t noise_level) { metric_.noiseLevel = noise_level; } 775 void Rerl(uint8_t rerl) { metric_.RERL = rerl; } 776 void Gmin(uint8_t gmin) { metric_.Gmin = gmin; } 777 void Rfactor(uint8_t rfactor) { metric_.Rfactor = rfactor; } 778 void ExtRfactor(uint8_t extrfactor) { metric_.extRfactor = extrfactor; } 779 void MosLq(uint8_t moslq) { metric_.MOSLQ = moslq; } 780 void MosCq(uint8_t moscq) { metric_.MOSCQ = moscq; } 781 void RxConfig(uint8_t rxconfig) { metric_.RXconfig = rxconfig; } 782 void JbNominal(uint16_t jbnominal) { metric_.JBnominal = jbnominal; } 783 void JbMax(uint16_t jbmax) { metric_.JBmax = jbmax; } 784 void JbAbsMax(uint16_t jbabsmax) { metric_.JBabsMax = jbabsmax; } 785 786 private: 787 friend class Xr; 788 RTCPUtility::RTCPPacketXRVOIPMetricItem metric_; 789 790 RTC_DISALLOW_COPY_AND_ASSIGN(VoipMetric); 791}; 792 793// Class holding a RTCP packet. 794// 795// Takes a built rtcp packet. 796// RawPacket raw_packet(buffer, length); 797// 798// To access the raw packet: 799// raw_packet.Buffer(); - pointer to the raw packet 800// raw_packet.BufferLength(); - the length of the raw packet 801 802class RawPacket { 803 public: 804 explicit RawPacket(size_t buffer_length); 805 RawPacket(const uint8_t* packet, size_t packet_length); 806 807 const uint8_t* Buffer() const; 808 uint8_t* MutableBuffer(); 809 size_t BufferLength() const; 810 size_t Length() const; 811 void SetLength(size_t length); 812 813 private: 814 const size_t buffer_length_; 815 size_t length_; 816 rtc::scoped_ptr<uint8_t[]> buffer_; 817}; 818 819} // namespace rtcp 820} // namespace webrtc 821#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_ 822