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