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