rtcp_packet.h revision ff761fba8274d93bd73e76c8b8a1f2d0776dd840
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_RTCP_PACKET_H_ 13#define WEBRTC_MODULES_RTP_RTCP_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/source/rtcp_utility.h" 21#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 22#include "webrtc/typedefs.h" 23 24namespace webrtc { 25namespace rtcp { 26 27static const int kCommonFbFmtLength = 12; 28static const int kReportBlockLength = 24; 29 30class Dlrr; 31class RawPacket; 32class Rrtr; 33class VoipMetric; 34 35// Class for building RTCP packets. 36// 37// Example: 38// ReportBlock report_block; 39// report_block.To(234) 40// report_block.FractionLost(10); 41// 42// ReceiverReport rr; 43// rr.From(123); 44// rr.WithReportBlock(&report_block) 45// 46// Fir fir; 47// fir.From(123); 48// fir.To(234) 49// fir.WithCommandSeqNum(123); 50// 51// size_t length = 0; // Builds an intra frame request 52// uint8_t packet[kPacketSize]; // with sequence number 123. 53// fir.Build(packet, &length, kPacketSize); 54// 55// RawPacket packet = fir.Build(); // Returns a RawPacket holding 56// // the built rtcp packet. 57// 58// rr.Append(&fir) // Builds a compound RTCP packet with 59// RawPacket packet = rr.Build(); // a receiver report, report block 60// // and fir message. 61 62class RtcpPacket { 63 public: 64 virtual ~RtcpPacket() {} 65 66 void Append(RtcpPacket* packet); 67 68 // Callback used to signal that an RTCP packet is ready. Note that this may 69 // not contain all data in this RtcpPacket; if a packet cannot fit in 70 // max_length bytes, it will be fragmented and multiple calls to this 71 // callback will be made. 72 class PacketReadyCallback { 73 public: 74 PacketReadyCallback() {} 75 virtual ~PacketReadyCallback() {} 76 77 virtual void OnPacketReady(uint8_t* data, size_t length) = 0; 78 }; 79 80 // Convenience method mostly used for test. Max length of IP_PACKET_SIZE is 81 // used, will cause assertion error if fragmentation occurs. 82 rtc::scoped_ptr<RawPacket> Build() const; 83 84 // Returns true if all calls to Create succeeded. A buffer of size 85 // IP_PACKET_SIZE will be allocated and reused between calls to callback. 86 bool Build(PacketReadyCallback* callback) const; 87 88 // Returns true if all calls to Create succeeded. Provided buffer reference 89 // will be used for all calls to callback. 90 bool BuildExternalBuffer(uint8_t* buffer, 91 size_t max_length, 92 PacketReadyCallback* callback) const; 93 94 // Size of this packet in bytes (including headers, excluding nested packets). 95 virtual size_t BlockLength() const = 0; 96 97 protected: 98 RtcpPacket() {} 99 100 virtual bool Create(uint8_t* packet, 101 size_t* index, 102 size_t max_length, 103 PacketReadyCallback* callback) const = 0; 104 105 static void CreateHeader(uint8_t count_or_format, 106 uint8_t packet_type, 107 size_t block_length, // Size in 32bit words - 1. 108 uint8_t* buffer, 109 size_t* pos); 110 111 bool OnBufferFull(uint8_t* packet, 112 size_t* index, 113 RtcpPacket::PacketReadyCallback* callback) const; 114 115 size_t HeaderLength() const; 116 117 static const size_t kHeaderLength = 4; 118 119 private: 120 bool CreateAndAddAppended(uint8_t* packet, 121 size_t* index, 122 size_t max_length, 123 PacketReadyCallback* callback) const; 124 125 std::vector<RtcpPacket*> appended_packets_; 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// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications. 149// 150// RTCP report block (RFC 3550). 151// 152// 0 1 2 3 153// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 154// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 155// | SSRC_1 (SSRC of first source) | 156// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 157// | fraction lost | cumulative number of packets lost | 158// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 159// | extended highest sequence number received | 160// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 161// | interarrival jitter | 162// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 163// | last SR (LSR) | 164// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 165// | delay since last SR (DLSR) | 166// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 167 168class ReportBlock { 169 public: 170 ReportBlock() { 171 // TODO(asapersson): Consider adding a constructor to struct. 172 memset(&report_block_, 0, sizeof(report_block_)); 173 } 174 175 ~ReportBlock() {} 176 177 void To(uint32_t ssrc) { 178 report_block_.SSRC = ssrc; 179 } 180 void WithFractionLost(uint8_t fraction_lost) { 181 report_block_.FractionLost = fraction_lost; 182 } 183 void WithCumulativeLost(uint32_t cumulative_lost) { 184 report_block_.CumulativeNumOfPacketsLost = cumulative_lost; 185 } 186 void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) { 187 report_block_.ExtendedHighestSequenceNumber = ext_highest_seq_num; 188 } 189 void WithJitter(uint32_t jitter) { 190 report_block_.Jitter = jitter; 191 } 192 void WithLastSr(uint32_t last_sr) { 193 report_block_.LastSR = last_sr; 194 } 195 void WithDelayLastSr(uint32_t delay_last_sr) { 196 report_block_.DelayLastSR = delay_last_sr; 197 } 198 199 private: 200 friend class SenderReport; 201 friend class ReceiverReport; 202 RTCPUtility::RTCPPacketReportBlockItem report_block_; 203}; 204 205// RTCP sender report (RFC 3550). 206// 207// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 208// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 209// |V=2|P| RC | PT=SR=200 | length | 210// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 211// | SSRC of sender | 212// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 213// | NTP timestamp, most significant word | 214// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 215// | NTP timestamp, least significant word | 216// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 217// | RTP timestamp | 218// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 219// | sender's packet count | 220// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 221// | sender's octet count | 222// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 223// | report block(s) | 224// | .... | 225 226class SenderReport : public RtcpPacket { 227 public: 228 SenderReport() : RtcpPacket() { 229 memset(&sr_, 0, sizeof(sr_)); 230 } 231 232 virtual ~SenderReport() {} 233 234 void From(uint32_t ssrc) { 235 sr_.SenderSSRC = ssrc; 236 } 237 void WithNtpSec(uint32_t sec) { 238 sr_.NTPMostSignificant = sec; 239 } 240 void WithNtpFrac(uint32_t frac) { 241 sr_.NTPLeastSignificant = frac; 242 } 243 void WithRtpTimestamp(uint32_t rtp_timestamp) { 244 sr_.RTPTimestamp = rtp_timestamp; 245 } 246 void WithPacketCount(uint32_t packet_count) { 247 sr_.SenderPacketCount = packet_count; 248 } 249 void WithOctetCount(uint32_t octet_count) { 250 sr_.SenderOctetCount = octet_count; 251 } 252 bool WithReportBlock(const ReportBlock& block); 253 254 protected: 255 bool Create(uint8_t* packet, 256 size_t* index, 257 size_t max_length, 258 RtcpPacket::PacketReadyCallback* callback) const override; 259 260 private: 261 static const int kMaxNumberOfReportBlocks = 0x1f; 262 263 size_t BlockLength() const { 264 const size_t kSrHeaderLength = 8; 265 const size_t kSenderInfoLength = 20; 266 return kSrHeaderLength + kSenderInfoLength + 267 report_blocks_.size() * kReportBlockLength; 268 } 269 270 RTCPUtility::RTCPPacketSR sr_; 271 std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_; 272 273 RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport); 274}; 275 276// 277// RTCP receiver report (RFC 3550). 278// 279// 0 1 2 3 280// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 281// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 282// |V=2|P| RC | PT=RR=201 | length | 283// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 284// | SSRC of packet sender | 285// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 286// | report block(s) | 287// | .... | 288 289class ReceiverReport : public RtcpPacket { 290 public: 291 ReceiverReport() : RtcpPacket() { 292 memset(&rr_, 0, sizeof(rr_)); 293 } 294 295 virtual ~ReceiverReport() {} 296 297 void From(uint32_t ssrc) { 298 rr_.SenderSSRC = ssrc; 299 } 300 bool WithReportBlock(const ReportBlock& block); 301 302 protected: 303 bool Create(uint8_t* packet, 304 size_t* index, 305 size_t max_length, 306 RtcpPacket::PacketReadyCallback* callback) const override; 307 308 private: 309 static const int kMaxNumberOfReportBlocks = 0x1F; 310 311 size_t BlockLength() const { 312 const size_t kRrHeaderLength = 8; 313 return kRrHeaderLength + report_blocks_.size() * kReportBlockLength; 314 } 315 316 RTCPUtility::RTCPPacketRR rr_; 317 std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_; 318 319 RTC_DISALLOW_COPY_AND_ASSIGN(ReceiverReport); 320}; 321 322// Transmission Time Offsets in RTP Streams (RFC 5450). 323// 324// 0 1 2 3 325// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 326// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 327// hdr |V=2|P| RC | PT=IJ=195 | length | 328// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 329// | inter-arrival jitter | 330// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 331// . . 332// . . 333// . . 334// | inter-arrival jitter | 335// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 336// 337// If present, this RTCP packet must be placed after a receiver report 338// (inside a compound RTCP packet), and MUST have the same value for RC 339// (reception report count) as the receiver report. 340 341class Ij : public RtcpPacket { 342 public: 343 Ij() : RtcpPacket() {} 344 345 virtual ~Ij() {} 346 347 bool WithJitterItem(uint32_t jitter); 348 349 protected: 350 bool Create(uint8_t* packet, 351 size_t* index, 352 size_t max_length, 353 RtcpPacket::PacketReadyCallback* callback) const override; 354 355 private: 356 static const int kMaxNumberOfIjItems = 0x1f; 357 358 size_t BlockLength() const { 359 return kHeaderLength + 4 * ij_items_.size(); 360 } 361 362 std::vector<uint32_t> ij_items_; 363 364 RTC_DISALLOW_COPY_AND_ASSIGN(Ij); 365}; 366 367// Source Description (SDES) (RFC 3550). 368// 369// 0 1 2 3 370// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 371// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 372// header |V=2|P| SC | PT=SDES=202 | length | 373// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 374// chunk | SSRC/CSRC_1 | 375// 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 376// | SDES items | 377// | ... | 378// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 379// chunk | SSRC/CSRC_2 | 380// 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 381// | SDES items | 382// | ... | 383// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 384// 385// Canonical End-Point Identifier SDES Item (CNAME) 386// 387// 0 1 2 3 388// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 389// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 390// | CNAME=1 | length | user and domain name ... 391// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 392 393class Sdes : public RtcpPacket { 394 public: 395 Sdes() : RtcpPacket() {} 396 397 virtual ~Sdes() {} 398 399 bool WithCName(uint32_t ssrc, const std::string& cname); 400 401 struct Chunk { 402 uint32_t ssrc; 403 std::string name; 404 int null_octets; 405 }; 406 407 protected: 408 bool Create(uint8_t* packet, 409 size_t* index, 410 size_t max_length, 411 RtcpPacket::PacketReadyCallback* callback) const override; 412 413 private: 414 static const int kMaxNumberOfChunks = 0x1f; 415 416 size_t BlockLength() const; 417 418 std::vector<Chunk> chunks_; 419 420 RTC_DISALLOW_COPY_AND_ASSIGN(Sdes); 421}; 422 423// 424// Bye packet (BYE) (RFC 3550). 425// 426// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 427// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 428// |V=2|P| SC | PT=BYE=203 | length | 429// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 430// | SSRC/CSRC | 431// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 432// : ... : 433// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 434// (opt) | length | reason for leaving ... 435// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 436 437class Bye : public RtcpPacket { 438 public: 439 Bye() : RtcpPacket() { 440 memset(&bye_, 0, sizeof(bye_)); 441 } 442 443 virtual ~Bye() {} 444 445 void From(uint32_t ssrc) { 446 bye_.SenderSSRC = ssrc; 447 } 448 449 bool WithCsrc(uint32_t csrc); 450 451 // TODO(sprang): Add support for reason field? 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 static const int kMaxNumberOfCsrcs = 0x1f - 1; // First item is sender SSRC. 461 462 size_t BlockLength() const { 463 size_t source_count = 1 + csrcs_.size(); 464 return kHeaderLength + 4 * source_count; 465 } 466 467 RTCPUtility::RTCPPacketBYE bye_; 468 std::vector<uint32_t> csrcs_; 469 470 RTC_DISALLOW_COPY_AND_ASSIGN(Bye); 471}; 472 473// Application-Defined packet (APP) (RFC 3550). 474// 475// 0 1 2 3 476// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 477// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 478// |V=2|P| subtype | PT=APP=204 | length | 479// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 480// | SSRC/CSRC | 481// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 482// | name (ASCII) | 483// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 484// | application-dependent data ... 485// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 486 487class App : public RtcpPacket { 488 public: 489 App() 490 : RtcpPacket(), 491 ssrc_(0) { 492 memset(&app_, 0, sizeof(app_)); 493 } 494 495 virtual ~App() {} 496 497 void From(uint32_t ssrc) { 498 ssrc_ = ssrc; 499 } 500 void WithSubType(uint8_t subtype) { 501 assert(subtype <= 0x1f); 502 app_.SubType = subtype; 503 } 504 void WithName(uint32_t name) { 505 app_.Name = name; 506 } 507 void WithData(const uint8_t* data, uint16_t data_length) { 508 assert(data); 509 assert(data_length <= kRtcpAppCode_DATA_SIZE); 510 assert(data_length % 4 == 0); 511 memcpy(app_.Data, data, data_length); 512 app_.Size = data_length; 513 } 514 515 protected: 516 bool Create(uint8_t* packet, 517 size_t* index, 518 size_t max_length, 519 RtcpPacket::PacketReadyCallback* callback) const override; 520 521 private: 522 size_t BlockLength() const { 523 return 12 + app_.Size; 524 } 525 526 uint32_t ssrc_; 527 RTCPUtility::RTCPPacketAPP app_; 528 529 RTC_DISALLOW_COPY_AND_ASSIGN(App); 530}; 531 532// RFC 4585: Feedback format. 533// 534// Common packet format: 535// 536// 0 1 2 3 537// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 538// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 539// |V=2|P| FMT | PT | length | 540// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 541// | SSRC of packet sender | 542// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 543// | SSRC of media source | 544// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 545// : Feedback Control Information (FCI) : 546// : 547 548// Picture loss indication (PLI) (RFC 4585). 549// 550// FCI: no feedback control information. 551 552class Pli : public RtcpPacket { 553 public: 554 Pli() : RtcpPacket() { 555 memset(&pli_, 0, sizeof(pli_)); 556 } 557 558 virtual ~Pli() {} 559 560 void From(uint32_t ssrc) { 561 pli_.SenderSSRC = ssrc; 562 } 563 void To(uint32_t ssrc) { 564 pli_.MediaSSRC = ssrc; 565 } 566 567 protected: 568 bool Create(uint8_t* packet, 569 size_t* index, 570 size_t max_length, 571 RtcpPacket::PacketReadyCallback* callback) const override; 572 573 private: 574 size_t BlockLength() const { 575 return kCommonFbFmtLength; 576 } 577 578 RTCPUtility::RTCPPacketPSFBPLI pli_; 579 580 RTC_DISALLOW_COPY_AND_ASSIGN(Pli); 581}; 582 583// Slice loss indication (SLI) (RFC 4585). 584// 585// FCI: 586// 0 1 2 3 587// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 588// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 589// | First | Number | PictureID | 590// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 591 592class Sli : public RtcpPacket { 593 public: 594 Sli() : RtcpPacket() { 595 memset(&sli_, 0, sizeof(sli_)); 596 memset(&sli_item_, 0, sizeof(sli_item_)); 597 } 598 599 virtual ~Sli() {} 600 601 void From(uint32_t ssrc) { 602 sli_.SenderSSRC = ssrc; 603 } 604 void To(uint32_t ssrc) { 605 sli_.MediaSSRC = ssrc; 606 } 607 void WithFirstMb(uint16_t first_mb) { 608 assert(first_mb <= 0x1fff); 609 sli_item_.FirstMB = first_mb; 610 } 611 void WithNumberOfMb(uint16_t number_mb) { 612 assert(number_mb <= 0x1fff); 613 sli_item_.NumberOfMB = number_mb; 614 } 615 void WithPictureId(uint8_t picture_id) { 616 assert(picture_id <= 0x3f); 617 sli_item_.PictureId = picture_id; 618 } 619 620 protected: 621 bool Create(uint8_t* packet, 622 size_t* index, 623 size_t max_length, 624 RtcpPacket::PacketReadyCallback* callback) const override; 625 626 private: 627 size_t BlockLength() const { 628 const size_t kFciLength = 4; 629 return kCommonFbFmtLength + kFciLength; 630 } 631 632 RTCPUtility::RTCPPacketPSFBSLI sli_; 633 RTCPUtility::RTCPPacketPSFBSLIItem sli_item_; 634 635 RTC_DISALLOW_COPY_AND_ASSIGN(Sli); 636}; 637 638// Generic NACK (RFC 4585). 639// 640// FCI: 641// 0 1 2 3 642// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 643// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 644// | PID | BLP | 645// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 646 647class Nack : public RtcpPacket { 648 public: 649 Nack() : RtcpPacket() { 650 memset(&nack_, 0, sizeof(nack_)); 651 } 652 653 virtual ~Nack() {} 654 655 void From(uint32_t ssrc) { 656 nack_.SenderSSRC = ssrc; 657 } 658 void To(uint32_t ssrc) { 659 nack_.MediaSSRC = ssrc; 660 } 661 void WithList(const uint16_t* nack_list, int length); 662 663 protected: 664 bool Create(uint8_t* packet, 665 size_t* index, 666 size_t max_length, 667 RtcpPacket::PacketReadyCallback* callback) const override; 668 669 size_t BlockLength() const override; 670 671 private: 672 673 RTCPUtility::RTCPPacketRTPFBNACK nack_; 674 std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_; 675 676 RTC_DISALLOW_COPY_AND_ASSIGN(Nack); 677}; 678 679// Reference picture selection indication (RPSI) (RFC 4585). 680// 681// FCI: 682// 683// 0 1 2 3 684// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 685// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 686// | PB |0| Payload Type| Native RPSI bit string | 687// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 688// | defined per codec ... | Padding (0) | 689// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 690 691class Rpsi : public RtcpPacket { 692 public: 693 Rpsi() 694 : RtcpPacket(), 695 padding_bytes_(0) { 696 memset(&rpsi_, 0, sizeof(rpsi_)); 697 } 698 699 virtual ~Rpsi() {} 700 701 void From(uint32_t ssrc) { 702 rpsi_.SenderSSRC = ssrc; 703 } 704 void To(uint32_t ssrc) { 705 rpsi_.MediaSSRC = ssrc; 706 } 707 void WithPayloadType(uint8_t payload) { 708 assert(payload <= 0x7f); 709 rpsi_.PayloadType = payload; 710 } 711 void WithPictureId(uint64_t picture_id); 712 713 protected: 714 bool Create(uint8_t* packet, 715 size_t* index, 716 size_t max_length, 717 RtcpPacket::PacketReadyCallback* callback) const override; 718 719 private: 720 size_t BlockLength() const { 721 size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_; 722 return kCommonFbFmtLength + fci_length; 723 } 724 725 uint8_t padding_bytes_; 726 RTCPUtility::RTCPPacketPSFBRPSI rpsi_; 727 728 RTC_DISALLOW_COPY_AND_ASSIGN(Rpsi); 729}; 730 731// Full intra request (FIR) (RFC 5104). 732// 733// FCI: 734// 735// 0 1 2 3 736// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 737// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 738// | SSRC | 739// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 740// | Seq nr. | Reserved | 741// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 742 743class Fir : public RtcpPacket { 744 public: 745 Fir() : RtcpPacket() { 746 memset(&fir_, 0, sizeof(fir_)); 747 memset(&fir_item_, 0, sizeof(fir_item_)); 748 } 749 750 virtual ~Fir() {} 751 752 void From(uint32_t ssrc) { 753 fir_.SenderSSRC = ssrc; 754 } 755 void To(uint32_t ssrc) { 756 fir_item_.SSRC = ssrc; 757 } 758 void WithCommandSeqNum(uint8_t seq_num) { 759 fir_item_.CommandSequenceNumber = seq_num; 760 } 761 762 protected: 763 bool Create(uint8_t* packet, 764 size_t* index, 765 size_t max_length, 766 RtcpPacket::PacketReadyCallback* callback) const override; 767 768 private: 769 size_t BlockLength() const { 770 const size_t kFciLength = 8; 771 return kCommonFbFmtLength + kFciLength; 772 } 773 774 RTCPUtility::RTCPPacketPSFBFIR fir_; 775 RTCPUtility::RTCPPacketPSFBFIRItem fir_item_; 776}; 777 778// Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104). 779// 780// FCI: 781// 782// 0 1 2 3 783// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 784// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 785// | SSRC | 786// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 787// | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 788// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 789 790class Tmmbr : public RtcpPacket { 791 public: 792 Tmmbr() : RtcpPacket() { 793 memset(&tmmbr_, 0, sizeof(tmmbr_)); 794 memset(&tmmbr_item_, 0, sizeof(tmmbr_item_)); 795 } 796 797 virtual ~Tmmbr() {} 798 799 void From(uint32_t ssrc) { 800 tmmbr_.SenderSSRC = ssrc; 801 } 802 void To(uint32_t ssrc) { 803 tmmbr_item_.SSRC = ssrc; 804 } 805 void WithBitrateKbps(uint32_t bitrate_kbps) { 806 tmmbr_item_.MaxTotalMediaBitRate = bitrate_kbps; 807 } 808 void WithOverhead(uint16_t overhead) { 809 assert(overhead <= 0x1ff); 810 tmmbr_item_.MeasuredOverhead = overhead; 811 } 812 813 protected: 814 bool Create(uint8_t* packet, 815 size_t* index, 816 size_t max_length, 817 RtcpPacket::PacketReadyCallback* callback) const override; 818 819 private: 820 size_t BlockLength() const { 821 const size_t kFciLen = 8; 822 return kCommonFbFmtLength + kFciLen; 823 } 824 825 RTCPUtility::RTCPPacketRTPFBTMMBR tmmbr_; 826 RTCPUtility::RTCPPacketRTPFBTMMBRItem tmmbr_item_; 827 828 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbr); 829}; 830 831// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104). 832// 833// FCI: 834// 835// 0 1 2 3 836// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 837// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 838// | SSRC | 839// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 840// | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 841// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 842 843class Tmmbn : public RtcpPacket { 844 public: 845 Tmmbn() : RtcpPacket() { 846 memset(&tmmbn_, 0, sizeof(tmmbn_)); 847 } 848 849 virtual ~Tmmbn() {} 850 851 void From(uint32_t ssrc) { 852 tmmbn_.SenderSSRC = ssrc; 853 } 854 // Max 50 TMMBR can be added per TMMBN. 855 bool WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead); 856 857 protected: 858 bool Create(uint8_t* packet, 859 size_t* index, 860 size_t max_length, 861 RtcpPacket::PacketReadyCallback* callback) const override; 862 863 private: 864 static const int kMaxNumberOfTmmbrs = 50; 865 866 size_t BlockLength() const { 867 const size_t kFciLen = 8; 868 return kCommonFbFmtLength + kFciLen * tmmbn_items_.size(); 869 } 870 871 RTCPUtility::RTCPPacketRTPFBTMMBN tmmbn_; 872 std::vector<RTCPUtility::RTCPPacketRTPFBTMMBRItem> tmmbn_items_; 873 874 RTC_DISALLOW_COPY_AND_ASSIGN(Tmmbn); 875}; 876 877// Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb). 878// 879// 0 1 2 3 880// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 881// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 882// |V=2|P| FMT=15 | PT=206 | length | 883// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 884// | SSRC of packet sender | 885// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 886// | SSRC of media source | 887// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 888// | Unique identifier 'R' 'E' 'M' 'B' | 889// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 890// | Num SSRC | BR Exp | BR Mantissa | 891// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 892// | SSRC feedback | 893// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 894// | ... 895 896class Remb : public RtcpPacket { 897 public: 898 Remb() : RtcpPacket() { 899 memset(&remb_, 0, sizeof(remb_)); 900 memset(&remb_item_, 0, sizeof(remb_item_)); 901 } 902 903 virtual ~Remb() {} 904 905 void From(uint32_t ssrc) { 906 remb_.SenderSSRC = ssrc; 907 } 908 void AppliesTo(uint32_t ssrc); 909 910 void WithBitrateBps(uint32_t bitrate_bps) { 911 remb_item_.BitRate = bitrate_bps; 912 } 913 914 protected: 915 bool Create(uint8_t* packet, 916 size_t* index, 917 size_t max_length, 918 RtcpPacket::PacketReadyCallback* callback) const override; 919 920 private: 921 static const int kMaxNumberOfSsrcs = 0xff; 922 923 size_t BlockLength() const { 924 return (remb_item_.NumberOfSSRCs + 5) * 4; 925 } 926 927 RTCPUtility::RTCPPacketPSFBAPP remb_; 928 RTCPUtility::RTCPPacketPSFBREMBItem remb_item_; 929 930 RTC_DISALLOW_COPY_AND_ASSIGN(Remb); 931}; 932 933// From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR). 934// 935// Format for XR packets: 936// 937// 0 1 2 3 938// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 939// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 940// |V=2|P|reserved | PT=XR=207 | length | 941// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 942// | SSRC | 943// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 944// : report blocks : 945// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 946 947class Xr : public RtcpPacket { 948 public: 949 typedef std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> DlrrBlock; 950 Xr() : RtcpPacket() { 951 memset(&xr_header_, 0, sizeof(xr_header_)); 952 } 953 954 virtual ~Xr() {} 955 956 void From(uint32_t ssrc) { 957 xr_header_.OriginatorSSRC = ssrc; 958 } 959 960 // Max 50 items of each of {Rrtr, Dlrr, VoipMetric} allowed per Xr. 961 bool WithRrtr(Rrtr* rrtr); 962 bool WithDlrr(Dlrr* dlrr); 963 bool WithVoipMetric(VoipMetric* voip_metric); 964 965 protected: 966 bool Create(uint8_t* packet, 967 size_t* index, 968 size_t max_length, 969 RtcpPacket::PacketReadyCallback* callback) const override; 970 971 private: 972 static const int kMaxNumberOfRrtrBlocks = 50; 973 static const int kMaxNumberOfDlrrBlocks = 50; 974 static const int kMaxNumberOfVoipMetricBlocks = 50; 975 976 size_t BlockLength() const { 977 const size_t kXrHeaderLength = 8; 978 return kXrHeaderLength + RrtrLength() + DlrrLength() + VoipMetricLength(); 979 } 980 981 size_t RrtrLength() const { 982 const size_t kRrtrBlockLength = 12; 983 return kRrtrBlockLength * rrtr_blocks_.size(); 984 } 985 986 size_t DlrrLength() const; 987 988 size_t VoipMetricLength() const { 989 const size_t kVoipMetricBlockLength = 36; 990 return kVoipMetricBlockLength * voip_metric_blocks_.size(); 991 } 992 993 RTCPUtility::RTCPPacketXR xr_header_; 994 std::vector<RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem> rrtr_blocks_; 995 std::vector<DlrrBlock> dlrr_blocks_; 996 std::vector<RTCPUtility::RTCPPacketXRVOIPMetricItem> voip_metric_blocks_; 997 998 RTC_DISALLOW_COPY_AND_ASSIGN(Xr); 999}; 1000 1001// Receiver Reference Time Report Block (RFC 3611). 1002// 1003// 0 1 2 3 1004// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1005// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1006// | BT=4 | reserved | block length = 2 | 1007// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1008// | NTP timestamp, most significant word | 1009// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1010// | NTP timestamp, least significant word | 1011// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1012 1013class Rrtr { 1014 public: 1015 Rrtr() { 1016 memset(&rrtr_block_, 0, sizeof(rrtr_block_)); 1017 } 1018 ~Rrtr() {} 1019 1020 void WithNtpSec(uint32_t sec) { 1021 rrtr_block_.NTPMostSignificant = sec; 1022 } 1023 void WithNtpFrac(uint32_t frac) { 1024 rrtr_block_.NTPLeastSignificant = frac; 1025 } 1026 1027 private: 1028 friend class Xr; 1029 RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem rrtr_block_; 1030 1031 RTC_DISALLOW_COPY_AND_ASSIGN(Rrtr); 1032}; 1033 1034// DLRR Report Block (RFC 3611). 1035// 1036// 0 1 2 3 1037// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1038// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1039// | BT=5 | reserved | block length | 1040// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 1041// | SSRC_1 (SSRC of first receiver) | sub- 1042// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 1043// | last RR (LRR) | 1 1044// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1045// | delay since last RR (DLRR) | 1046// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 1047// | SSRC_2 (SSRC of second receiver) | sub- 1048// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 1049// : ... : 2 1050 1051class Dlrr { 1052 public: 1053 Dlrr() {} 1054 ~Dlrr() {} 1055 1056 // Max 100 DLRR Items can be added per DLRR report block. 1057 bool WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr); 1058 1059 private: 1060 friend class Xr; 1061 static const int kMaxNumberOfDlrrItems = 100; 1062 1063 std::vector<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> dlrr_block_; 1064 1065 RTC_DISALLOW_COPY_AND_ASSIGN(Dlrr); 1066}; 1067 1068// VoIP Metrics Report Block (RFC 3611). 1069// 1070// 0 1 2 3 1071// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1072// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1073// | BT=7 | reserved | block length = 8 | 1074// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1075// | SSRC of source | 1076// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1077// | loss rate | discard rate | burst density | gap density | 1078// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1079// | burst duration | gap duration | 1080// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1081// | round trip delay | end system delay | 1082// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1083// | signal level | noise level | RERL | Gmin | 1084// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1085// | R factor | ext. R factor | MOS-LQ | MOS-CQ | 1086// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1087// | RX config | reserved | JB nominal | 1088// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1089// | JB maximum | JB abs max | 1090// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1091 1092class VoipMetric { 1093 public: 1094 VoipMetric() { 1095 memset(&metric_, 0, sizeof(metric_)); 1096 } 1097 ~VoipMetric() {} 1098 1099 void To(uint32_t ssrc) { metric_.SSRC = ssrc; } 1100 void LossRate(uint8_t loss_rate) { metric_.lossRate = loss_rate; } 1101 void DiscardRate(uint8_t discard_rate) { metric_.discardRate = discard_rate; } 1102 void BurstDensity(uint8_t burst_density) { 1103 metric_.burstDensity = burst_density; 1104 } 1105 void GapDensity(uint8_t gap_density) { metric_.gapDensity = gap_density; } 1106 void BurstDuration(uint16_t burst_duration) { 1107 metric_.burstDuration = burst_duration; 1108 } 1109 void GapDuration(uint16_t gap_duration) { 1110 metric_.gapDuration = gap_duration; 1111 } 1112 void RoundTripDelay(uint16_t round_trip_delay) { 1113 metric_.roundTripDelay = round_trip_delay; 1114 } 1115 void EndSystemDelay(uint16_t end_system_delay) { 1116 metric_.endSystemDelay = end_system_delay; 1117 } 1118 void SignalLevel(uint8_t signal_level) { metric_.signalLevel = signal_level; } 1119 void NoiseLevel(uint8_t noise_level) { metric_.noiseLevel = noise_level; } 1120 void Rerl(uint8_t rerl) { metric_.RERL = rerl; } 1121 void Gmin(uint8_t gmin) { metric_.Gmin = gmin; } 1122 void Rfactor(uint8_t rfactor) { metric_.Rfactor = rfactor; } 1123 void ExtRfactor(uint8_t extrfactor) { metric_.extRfactor = extrfactor; } 1124 void MosLq(uint8_t moslq) { metric_.MOSLQ = moslq; } 1125 void MosCq(uint8_t moscq) { metric_.MOSCQ = moscq; } 1126 void RxConfig(uint8_t rxconfig) { metric_.RXconfig = rxconfig; } 1127 void JbNominal(uint16_t jbnominal) { metric_.JBnominal = jbnominal; } 1128 void JbMax(uint16_t jbmax) { metric_.JBmax = jbmax; } 1129 void JbAbsMax(uint16_t jbabsmax) { metric_.JBabsMax = jbabsmax; } 1130 1131 private: 1132 friend class Xr; 1133 RTCPUtility::RTCPPacketXRVOIPMetricItem metric_; 1134 1135 RTC_DISALLOW_COPY_AND_ASSIGN(VoipMetric); 1136}; 1137 1138// Class holding a RTCP packet. 1139// 1140// Takes a built rtcp packet. 1141// RawPacket raw_packet(buffer, length); 1142// 1143// To access the raw packet: 1144// raw_packet.Buffer(); - pointer to the raw packet 1145// raw_packet.BufferLength(); - the length of the raw packet 1146 1147class RawPacket { 1148 public: 1149 explicit RawPacket(size_t buffer_length); 1150 RawPacket(const uint8_t* packet, size_t packet_length); 1151 1152 const uint8_t* Buffer() const; 1153 uint8_t* MutableBuffer(); 1154 size_t BufferLength() const; 1155 size_t Length() const; 1156 void SetLength(size_t length); 1157 1158 private: 1159 const size_t buffer_length_; 1160 size_t length_; 1161 rtc::scoped_ptr<uint8_t[]> buffer_; 1162}; 1163 1164} // namespace rtcp 1165} // namespace webrtc 1166#endif // WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_ 1167