| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2012 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 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" | |
| 12 | |
| 13 #include <assert.h> | |
| 14 #include <math.h> // ceil | |
| 15 #include <string.h> // memcpy | |
| 16 | |
| 17 #include <limits> | |
| 18 | |
| 19 #include "webrtc/base/checks.h" | |
| 20 #include "webrtc/base/logging.h" | |
| 21 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | |
| 22 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | |
| 23 | |
| 24 namespace webrtc { | |
| 25 namespace { | |
| 26 constexpr uint64_t kMaxBitrateBps = std::numeric_limits<uint32_t>::max(); | |
| 27 } // namespace | |
| 28 | |
| 29 namespace RTCPUtility { | |
| 30 | |
| 31 NackStats::NackStats() | |
| 32 : max_sequence_number_(0), | |
| 33 requests_(0), | |
| 34 unique_requests_(0) {} | |
| 35 | |
| 36 NackStats::~NackStats() {} | |
| 37 | |
| 38 void NackStats::ReportRequest(uint16_t sequence_number) { | |
| 39 if (requests_ == 0 || | |
| 40 webrtc::IsNewerSequenceNumber(sequence_number, max_sequence_number_)) { | |
| 41 max_sequence_number_ = sequence_number; | |
| 42 ++unique_requests_; | |
| 43 } | |
| 44 ++requests_; | |
| 45 } | |
| 46 | |
| 47 uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac) { | |
| 48 return (ntp_sec << 16) + (ntp_frac >> 16); | |
| 49 } | |
| 50 } // namespace RTCPUtility | |
| 51 | |
| 52 // RTCPParserV2 : currently read only | |
| 53 RTCPUtility::RTCPParserV2::RTCPParserV2(const uint8_t* rtcpData, | |
| 54 size_t rtcpDataLength, | |
| 55 bool rtcpReducedSizeEnable) | |
| 56 : _ptrRTCPDataBegin(rtcpData), | |
| 57 _RTCPReducedSizeEnable(rtcpReducedSizeEnable), | |
| 58 _ptrRTCPDataEnd(rtcpData + rtcpDataLength), | |
| 59 _validPacket(false), | |
| 60 _ptrRTCPData(rtcpData), | |
| 61 _ptrRTCPBlockEnd(NULL), | |
| 62 _state(ParseState::State_TopLevel), | |
| 63 _numberOfBlocks(0), | |
| 64 num_skipped_blocks_(0), | |
| 65 _packetType(RTCPPacketTypes::kInvalid) { | |
| 66 Validate(); | |
| 67 } | |
| 68 | |
| 69 RTCPUtility::RTCPParserV2::~RTCPParserV2() { | |
| 70 } | |
| 71 | |
| 72 ptrdiff_t | |
| 73 RTCPUtility::RTCPParserV2::LengthLeft() const | |
| 74 { | |
| 75 return (_ptrRTCPDataEnd- _ptrRTCPData); | |
| 76 } | |
| 77 | |
| 78 RTCPUtility::RTCPPacketTypes | |
| 79 RTCPUtility::RTCPParserV2::PacketType() const | |
| 80 { | |
| 81 return _packetType; | |
| 82 } | |
| 83 | |
| 84 const RTCPUtility::RTCPPacket& | |
| 85 RTCPUtility::RTCPParserV2::Packet() const | |
| 86 { | |
| 87 return _packet; | |
| 88 } | |
| 89 | |
| 90 rtcp::RtcpPacket* RTCPUtility::RTCPParserV2::ReleaseRtcpPacket() { | |
| 91 return rtcp_packet_.release(); | |
| 92 } | |
| 93 RTCPUtility::RTCPPacketTypes | |
| 94 RTCPUtility::RTCPParserV2::Begin() | |
| 95 { | |
| 96 _ptrRTCPData = _ptrRTCPDataBegin; | |
| 97 | |
| 98 return Iterate(); | |
| 99 } | |
| 100 | |
| 101 RTCPUtility::RTCPPacketTypes | |
| 102 RTCPUtility::RTCPParserV2::Iterate() | |
| 103 { | |
| 104 // Reset packet type | |
| 105 _packetType = RTCPPacketTypes::kInvalid; | |
| 106 | |
| 107 if (IsValid()) | |
| 108 { | |
| 109 switch (_state) | |
| 110 { | |
| 111 case ParseState::State_TopLevel: | |
| 112 IterateTopLevel(); | |
| 113 break; | |
| 114 case ParseState::State_ReportBlockItem: | |
| 115 IterateReportBlockItem(); | |
| 116 break; | |
| 117 case ParseState::State_SDESChunk: | |
| 118 IterateSDESChunk(); | |
| 119 break; | |
| 120 case ParseState::State_BYEItem: | |
| 121 IterateBYEItem(); | |
| 122 break; | |
| 123 case ParseState::State_ExtendedJitterItem: | |
| 124 IterateExtendedJitterItem(); | |
| 125 break; | |
| 126 case ParseState::State_RTPFB_NACKItem: | |
| 127 IterateNACKItem(); | |
| 128 break; | |
| 129 case ParseState::State_RTPFB_TMMBRItem: | |
| 130 IterateTMMBRItem(); | |
| 131 break; | |
| 132 case ParseState::State_RTPFB_TMMBNItem: | |
| 133 IterateTMMBNItem(); | |
| 134 break; | |
| 135 case ParseState::State_PSFB_SLIItem: | |
| 136 IterateSLIItem(); | |
| 137 break; | |
| 138 case ParseState::State_PSFB_RPSIItem: | |
| 139 IterateRPSIItem(); | |
| 140 break; | |
| 141 case ParseState::State_PSFB_FIRItem: | |
| 142 IterateFIRItem(); | |
| 143 break; | |
| 144 case ParseState::State_PSFB_AppItem: | |
| 145 IteratePsfbAppItem(); | |
| 146 break; | |
| 147 case ParseState::State_PSFB_REMBItem: | |
| 148 IteratePsfbREMBItem(); | |
| 149 break; | |
| 150 case ParseState::State_XRItem: | |
| 151 IterateXrItem(); | |
| 152 break; | |
| 153 case ParseState::State_XR_DLLRItem: | |
| 154 IterateXrDlrrItem(); | |
| 155 break; | |
| 156 case ParseState::State_AppItem: | |
| 157 IterateAppItem(); | |
| 158 break; | |
| 159 default: | |
| 160 RTC_NOTREACHED() << "Invalid state!"; | |
| 161 break; | |
| 162 } | |
| 163 } | |
| 164 return _packetType; | |
| 165 } | |
| 166 | |
| 167 void | |
| 168 RTCPUtility::RTCPParserV2::IterateTopLevel() | |
| 169 { | |
| 170 for (;;) | |
| 171 { | |
| 172 RtcpCommonHeader header; | |
| 173 if (_ptrRTCPDataEnd <= _ptrRTCPData) | |
| 174 return; | |
| 175 | |
| 176 if (!RtcpParseCommonHeader(_ptrRTCPData, _ptrRTCPDataEnd - _ptrRTCPData, | |
| 177 &header)) { | |
| 178 return; | |
| 179 } | |
| 180 _ptrRTCPBlockEnd = _ptrRTCPData + header.BlockSize(); | |
| 181 if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd) | |
| 182 { | |
| 183 ++num_skipped_blocks_; | |
| 184 return; | |
| 185 } | |
| 186 | |
| 187 switch (header.packet_type) { | |
| 188 case PT_SR: | |
| 189 { | |
| 190 // number of Report blocks | |
| 191 _numberOfBlocks = header.count_or_format; | |
| 192 ParseSR(); | |
| 193 return; | |
| 194 } | |
| 195 case PT_RR: | |
| 196 { | |
| 197 // number of Report blocks | |
| 198 _numberOfBlocks = header.count_or_format; | |
| 199 ParseRR(); | |
| 200 return; | |
| 201 } | |
| 202 case PT_SDES: | |
| 203 { | |
| 204 // number of SDES blocks | |
| 205 _numberOfBlocks = header.count_or_format; | |
| 206 const bool ok = ParseSDES(); | |
| 207 if (!ok) | |
| 208 { | |
| 209 // Nothing supported found, continue to next block! | |
| 210 break; | |
| 211 } | |
| 212 return; | |
| 213 } | |
| 214 case PT_BYE: | |
| 215 { | |
| 216 _numberOfBlocks = header.count_or_format; | |
| 217 const bool ok = ParseBYE(); | |
| 218 if (!ok) | |
| 219 { | |
| 220 // Nothing supported found, continue to next block! | |
| 221 break; | |
| 222 } | |
| 223 return; | |
| 224 } | |
| 225 case PT_IJ: | |
| 226 { | |
| 227 // number of Report blocks | |
| 228 _numberOfBlocks = header.count_or_format; | |
| 229 ParseIJ(); | |
| 230 return; | |
| 231 } | |
| 232 case PT_RTPFB: | |
| 233 FALLTHROUGH(); | |
| 234 case PT_PSFB: | |
| 235 { | |
| 236 if (!ParseFBCommon(header)) { | |
| 237 // Nothing supported found, continue to next block! | |
| 238 EndCurrentBlock(); | |
| 239 break; | |
| 240 } | |
| 241 return; | |
| 242 } | |
| 243 case PT_APP: | |
| 244 { | |
| 245 const bool ok = ParseAPP(header); | |
| 246 if (!ok) | |
| 247 { | |
| 248 // Nothing supported found, continue to next block! | |
| 249 break; | |
| 250 } | |
| 251 return; | |
| 252 } | |
| 253 case PT_XR: | |
| 254 { | |
| 255 const bool ok = ParseXr(); | |
| 256 if (!ok) | |
| 257 { | |
| 258 // Nothing supported found, continue to next block! | |
| 259 break; | |
| 260 } | |
| 261 return; | |
| 262 } | |
| 263 default: | |
| 264 // Not supported! Skip! | |
| 265 ++num_skipped_blocks_; | |
| 266 EndCurrentBlock(); | |
| 267 break; | |
| 268 } | |
| 269 } | |
| 270 } | |
| 271 | |
| 272 void | |
| 273 RTCPUtility::RTCPParserV2::IterateXrItem() | |
| 274 { | |
| 275 const bool success = ParseXrItem(); | |
| 276 if (!success) | |
| 277 { | |
| 278 Iterate(); | |
| 279 } | |
| 280 } | |
| 281 | |
| 282 void | |
| 283 RTCPUtility::RTCPParserV2::IterateXrDlrrItem() | |
| 284 { | |
| 285 const bool success = ParseXrDlrrItem(); | |
| 286 if (!success) | |
| 287 { | |
| 288 Iterate(); | |
| 289 } | |
| 290 } | |
| 291 | |
| 292 void | |
| 293 RTCPUtility::RTCPParserV2::IterateReportBlockItem() | |
| 294 { | |
| 295 const bool success = ParseReportBlockItem(); | |
| 296 if (!success) | |
| 297 { | |
| 298 Iterate(); | |
| 299 } | |
| 300 } | |
| 301 | |
| 302 void | |
| 303 RTCPUtility::RTCPParserV2::IterateSDESChunk() | |
| 304 { | |
| 305 const bool success = ParseSDESChunk(); | |
| 306 if (!success) | |
| 307 { | |
| 308 Iterate(); | |
| 309 } | |
| 310 } | |
| 311 | |
| 312 void | |
| 313 RTCPUtility::RTCPParserV2::IterateBYEItem() | |
| 314 { | |
| 315 const bool success = ParseBYEItem(); | |
| 316 if (!success) | |
| 317 { | |
| 318 Iterate(); | |
| 319 } | |
| 320 } | |
| 321 | |
| 322 void | |
| 323 RTCPUtility::RTCPParserV2::IterateExtendedJitterItem() | |
| 324 { | |
| 325 const bool success = ParseIJItem(); | |
| 326 if (!success) | |
| 327 { | |
| 328 Iterate(); | |
| 329 } | |
| 330 } | |
| 331 | |
| 332 void | |
| 333 RTCPUtility::RTCPParserV2::IterateNACKItem() | |
| 334 { | |
| 335 const bool success = ParseNACKItem(); | |
| 336 if (!success) | |
| 337 { | |
| 338 Iterate(); | |
| 339 } | |
| 340 } | |
| 341 | |
| 342 void | |
| 343 RTCPUtility::RTCPParserV2::IterateTMMBRItem() | |
| 344 { | |
| 345 const bool success = ParseTMMBRItem(); | |
| 346 if (!success) | |
| 347 { | |
| 348 Iterate(); | |
| 349 } | |
| 350 } | |
| 351 | |
| 352 void | |
| 353 RTCPUtility::RTCPParserV2::IterateTMMBNItem() | |
| 354 { | |
| 355 const bool success = ParseTMMBNItem(); | |
| 356 if (!success) | |
| 357 { | |
| 358 Iterate(); | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 void | |
| 363 RTCPUtility::RTCPParserV2::IterateSLIItem() | |
| 364 { | |
| 365 const bool success = ParseSLIItem(); | |
| 366 if (!success) | |
| 367 { | |
| 368 Iterate(); | |
| 369 } | |
| 370 } | |
| 371 | |
| 372 void | |
| 373 RTCPUtility::RTCPParserV2::IterateRPSIItem() | |
| 374 { | |
| 375 const bool success = ParseRPSIItem(); | |
| 376 if (!success) | |
| 377 { | |
| 378 Iterate(); | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 void | |
| 383 RTCPUtility::RTCPParserV2::IterateFIRItem() | |
| 384 { | |
| 385 const bool success = ParseFIRItem(); | |
| 386 if (!success) | |
| 387 { | |
| 388 Iterate(); | |
| 389 } | |
| 390 } | |
| 391 | |
| 392 void | |
| 393 RTCPUtility::RTCPParserV2::IteratePsfbAppItem() | |
| 394 { | |
| 395 const bool success = ParsePsfbAppItem(); | |
| 396 if (!success) | |
| 397 { | |
| 398 Iterate(); | |
| 399 } | |
| 400 } | |
| 401 | |
| 402 void | |
| 403 RTCPUtility::RTCPParserV2::IteratePsfbREMBItem() | |
| 404 { | |
| 405 const bool success = ParsePsfbREMBItem(); | |
| 406 if (!success) | |
| 407 { | |
| 408 Iterate(); | |
| 409 } | |
| 410 } | |
| 411 | |
| 412 void | |
| 413 RTCPUtility::RTCPParserV2::IterateAppItem() | |
| 414 { | |
| 415 const bool success = ParseAPPItem(); | |
| 416 if (!success) | |
| 417 { | |
| 418 Iterate(); | |
| 419 } | |
| 420 } | |
| 421 | |
| 422 void | |
| 423 RTCPUtility::RTCPParserV2::Validate() | |
| 424 { | |
| 425 if (_ptrRTCPData == nullptr) | |
| 426 return; // NOT VALID | |
| 427 | |
| 428 RtcpCommonHeader header; | |
| 429 if (_ptrRTCPDataEnd <= _ptrRTCPDataBegin) | |
| 430 return; // NOT VALID | |
| 431 | |
| 432 if (!RtcpParseCommonHeader(_ptrRTCPDataBegin, | |
| 433 _ptrRTCPDataEnd - _ptrRTCPDataBegin, &header)) | |
| 434 return; // NOT VALID! | |
| 435 | |
| 436 // * if (!reducedSize) : first packet must be RR or SR. | |
| 437 // | |
| 438 // * The padding bit (P) should be zero for the first packet of a | |
| 439 // compound RTCP packet because padding should only be applied, | |
| 440 // if it is needed, to the last packet. (NOT CHECKED!) | |
| 441 // | |
| 442 // * The length fields of the individual RTCP packets must add up | |
| 443 // to the overall length of the compound RTCP packet as | |
| 444 // received. This is a fairly strong check. (NOT CHECKED!) | |
| 445 | |
| 446 if (!_RTCPReducedSizeEnable) { | |
| 447 if ((header.packet_type != PT_SR) && (header.packet_type != PT_RR)) | |
| 448 return; // NOT VALID | |
| 449 } | |
| 450 | |
| 451 _validPacket = true; | |
| 452 } | |
| 453 | |
| 454 bool | |
| 455 RTCPUtility::RTCPParserV2::IsValid() const | |
| 456 { | |
| 457 return _validPacket; | |
| 458 } | |
| 459 | |
| 460 void | |
| 461 RTCPUtility::RTCPParserV2::EndCurrentBlock() | |
| 462 { | |
| 463 _ptrRTCPData = _ptrRTCPBlockEnd; | |
| 464 } | |
| 465 | |
| 466 // 0 1 2 3 | |
| 467 // 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 | |
| 468 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 469 // |V=2|P| IC | PT | length | | |
| 470 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 471 // | |
| 472 // Common header for all RTCP packets, 4 octets. | |
| 473 | |
| 474 bool RTCPUtility::RtcpParseCommonHeader(const uint8_t* packet, | |
| 475 size_t size_bytes, | |
| 476 RtcpCommonHeader* parsed_header) { | |
| 477 RTC_DCHECK(parsed_header != nullptr); | |
| 478 if (size_bytes < RtcpCommonHeader::kHeaderSizeBytes) { | |
| 479 LOG(LS_WARNING) << "Too little data (" << size_bytes << " byte" | |
| 480 << (size_bytes != 1 ? "s" : "") | |
| 481 << ") remaining in buffer to parse RTCP header (4 bytes)."; | |
| 482 return false; | |
| 483 } | |
| 484 | |
| 485 const uint8_t kRtcpVersion = 2; | |
| 486 uint8_t version = packet[0] >> 6; | |
| 487 if (version != kRtcpVersion) { | |
| 488 LOG(LS_WARNING) << "Invalid RTCP header: Version must be " | |
| 489 << static_cast<int>(kRtcpVersion) << " but was " | |
| 490 << static_cast<int>(version); | |
| 491 return false; | |
| 492 } | |
| 493 | |
| 494 bool has_padding = (packet[0] & 0x20) != 0; | |
| 495 uint8_t format = packet[0] & 0x1F; | |
| 496 uint8_t packet_type = packet[1]; | |
| 497 size_t packet_size_words = | |
| 498 ByteReader<uint16_t>::ReadBigEndian(&packet[2]) + 1; | |
| 499 | |
| 500 if (size_bytes < packet_size_words * 4) { | |
| 501 LOG(LS_WARNING) << "Buffer too small (" << size_bytes | |
| 502 << " bytes) to fit an RtcpPacket of " << packet_size_words | |
| 503 << " 32bit words."; | |
| 504 return false; | |
| 505 } | |
| 506 | |
| 507 size_t payload_size = packet_size_words * 4; | |
| 508 size_t padding_bytes = 0; | |
| 509 if (has_padding) { | |
| 510 if (payload_size <= RtcpCommonHeader::kHeaderSizeBytes) { | |
| 511 LOG(LS_WARNING) << "Invalid RTCP header: Padding bit set but 0 payload " | |
| 512 "size specified."; | |
| 513 return false; | |
| 514 } | |
| 515 | |
| 516 padding_bytes = packet[payload_size - 1]; | |
| 517 if (RtcpCommonHeader::kHeaderSizeBytes + padding_bytes > payload_size) { | |
| 518 LOG(LS_WARNING) << "Invalid RTCP header: Too many padding bytes (" | |
| 519 << padding_bytes << ") for a packet size of " | |
| 520 << payload_size << "bytes."; | |
| 521 return false; | |
| 522 } | |
| 523 payload_size -= padding_bytes; | |
| 524 } | |
| 525 payload_size -= RtcpCommonHeader::kHeaderSizeBytes; | |
| 526 | |
| 527 parsed_header->version = kRtcpVersion; | |
| 528 parsed_header->count_or_format = format; | |
| 529 parsed_header->packet_type = packet_type; | |
| 530 parsed_header->payload_size_bytes = payload_size; | |
| 531 parsed_header->padding_bytes = padding_bytes; | |
| 532 | |
| 533 return true; | |
| 534 } | |
| 535 | |
| 536 bool | |
| 537 RTCPUtility::RTCPParserV2::ParseRR() | |
| 538 { | |
| 539 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 540 | |
| 541 if (length < 8) | |
| 542 { | |
| 543 return false; | |
| 544 } | |
| 545 | |
| 546 | |
| 547 _ptrRTCPData += 4; // Skip header | |
| 548 | |
| 549 _packetType = RTCPPacketTypes::kRr; | |
| 550 | |
| 551 _packet.RR.SenderSSRC = *_ptrRTCPData++ << 24; | |
| 552 _packet.RR.SenderSSRC += *_ptrRTCPData++ << 16; | |
| 553 _packet.RR.SenderSSRC += *_ptrRTCPData++ << 8; | |
| 554 _packet.RR.SenderSSRC += *_ptrRTCPData++; | |
| 555 | |
| 556 _packet.RR.NumberOfReportBlocks = _numberOfBlocks; | |
| 557 | |
| 558 // State transition | |
| 559 _state = ParseState::State_ReportBlockItem; | |
| 560 | |
| 561 return true; | |
| 562 } | |
| 563 | |
| 564 bool | |
| 565 RTCPUtility::RTCPParserV2::ParseSR() | |
| 566 { | |
| 567 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 568 | |
| 569 if (length < 28) | |
| 570 { | |
| 571 EndCurrentBlock(); | |
| 572 return false; | |
| 573 } | |
| 574 | |
| 575 _ptrRTCPData += 4; // Skip header | |
| 576 | |
| 577 _packetType = RTCPPacketTypes::kSr; | |
| 578 | |
| 579 _packet.SR.SenderSSRC = *_ptrRTCPData++ << 24; | |
| 580 _packet.SR.SenderSSRC += *_ptrRTCPData++ << 16; | |
| 581 _packet.SR.SenderSSRC += *_ptrRTCPData++ << 8; | |
| 582 _packet.SR.SenderSSRC += *_ptrRTCPData++; | |
| 583 | |
| 584 _packet.SR.NTPMostSignificant = *_ptrRTCPData++ << 24; | |
| 585 _packet.SR.NTPMostSignificant += *_ptrRTCPData++ << 16; | |
| 586 _packet.SR.NTPMostSignificant += *_ptrRTCPData++ << 8; | |
| 587 _packet.SR.NTPMostSignificant += *_ptrRTCPData++; | |
| 588 | |
| 589 _packet.SR.NTPLeastSignificant = *_ptrRTCPData++ << 24; | |
| 590 _packet.SR.NTPLeastSignificant += *_ptrRTCPData++ << 16; | |
| 591 _packet.SR.NTPLeastSignificant += *_ptrRTCPData++ << 8; | |
| 592 _packet.SR.NTPLeastSignificant += *_ptrRTCPData++; | |
| 593 | |
| 594 _packet.SR.RTPTimestamp = *_ptrRTCPData++ << 24; | |
| 595 _packet.SR.RTPTimestamp += *_ptrRTCPData++ << 16; | |
| 596 _packet.SR.RTPTimestamp += *_ptrRTCPData++ << 8; | |
| 597 _packet.SR.RTPTimestamp += *_ptrRTCPData++; | |
| 598 | |
| 599 _packet.SR.SenderPacketCount = *_ptrRTCPData++ << 24; | |
| 600 _packet.SR.SenderPacketCount += *_ptrRTCPData++ << 16; | |
| 601 _packet.SR.SenderPacketCount += *_ptrRTCPData++ << 8; | |
| 602 _packet.SR.SenderPacketCount += *_ptrRTCPData++; | |
| 603 | |
| 604 _packet.SR.SenderOctetCount = *_ptrRTCPData++ << 24; | |
| 605 _packet.SR.SenderOctetCount += *_ptrRTCPData++ << 16; | |
| 606 _packet.SR.SenderOctetCount += *_ptrRTCPData++ << 8; | |
| 607 _packet.SR.SenderOctetCount += *_ptrRTCPData++; | |
| 608 | |
| 609 _packet.SR.NumberOfReportBlocks = _numberOfBlocks; | |
| 610 | |
| 611 // State transition | |
| 612 if(_numberOfBlocks != 0) | |
| 613 { | |
| 614 _state = ParseState::State_ReportBlockItem; | |
| 615 }else | |
| 616 { | |
| 617 // don't go to state report block item if 0 report blocks | |
| 618 _state = ParseState::State_TopLevel; | |
| 619 EndCurrentBlock(); | |
| 620 } | |
| 621 return true; | |
| 622 } | |
| 623 | |
| 624 bool | |
| 625 RTCPUtility::RTCPParserV2::ParseReportBlockItem() | |
| 626 { | |
| 627 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 628 | |
| 629 if (length < 24 || _numberOfBlocks <= 0) | |
| 630 { | |
| 631 _state = ParseState::State_TopLevel; | |
| 632 | |
| 633 EndCurrentBlock(); | |
| 634 return false; | |
| 635 } | |
| 636 _packet.ReportBlockItem.SSRC = *_ptrRTCPData++ << 24; | |
| 637 _packet.ReportBlockItem.SSRC += *_ptrRTCPData++ << 16; | |
| 638 _packet.ReportBlockItem.SSRC += *_ptrRTCPData++ << 8; | |
| 639 _packet.ReportBlockItem.SSRC += *_ptrRTCPData++; | |
| 640 | |
| 641 _packet.ReportBlockItem.FractionLost = *_ptrRTCPData++; | |
| 642 | |
| 643 _packet.ReportBlockItem.CumulativeNumOfPacketsLost = *_ptrRTCPData++ << 16; | |
| 644 _packet.ReportBlockItem.CumulativeNumOfPacketsLost += *_ptrRTCPData++ << 8; | |
| 645 _packet.ReportBlockItem.CumulativeNumOfPacketsLost += *_ptrRTCPData++; | |
| 646 | |
| 647 _packet.ReportBlockItem.ExtendedHighestSequenceNumber = *_ptrRTCPData++ << 2
4; | |
| 648 _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++ <<
16; | |
| 649 _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++ <<
8; | |
| 650 _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++; | |
| 651 | |
| 652 _packet.ReportBlockItem.Jitter = *_ptrRTCPData++ << 24; | |
| 653 _packet.ReportBlockItem.Jitter += *_ptrRTCPData++ << 16; | |
| 654 _packet.ReportBlockItem.Jitter += *_ptrRTCPData++ << 8; | |
| 655 _packet.ReportBlockItem.Jitter += *_ptrRTCPData++; | |
| 656 | |
| 657 _packet.ReportBlockItem.LastSR = *_ptrRTCPData++ << 24; | |
| 658 _packet.ReportBlockItem.LastSR += *_ptrRTCPData++ << 16; | |
| 659 _packet.ReportBlockItem.LastSR += *_ptrRTCPData++ << 8; | |
| 660 _packet.ReportBlockItem.LastSR += *_ptrRTCPData++; | |
| 661 | |
| 662 _packet.ReportBlockItem.DelayLastSR = *_ptrRTCPData++ << 24; | |
| 663 _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++ << 16; | |
| 664 _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++ << 8; | |
| 665 _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++; | |
| 666 | |
| 667 _numberOfBlocks--; | |
| 668 _packetType = RTCPPacketTypes::kReportBlockItem; | |
| 669 return true; | |
| 670 } | |
| 671 | |
| 672 /* From RFC 5450: Transmission Time Offsets in RTP Streams. | |
| 673 0 1 2 3 | |
| 674 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 | |
| 675 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 676 hdr |V=2|P| RC | PT=IJ=195 | length | | |
| 677 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 678 | inter-arrival jitter | | |
| 679 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 680 . . | |
| 681 . . | |
| 682 . . | |
| 683 | inter-arrival jitter | | |
| 684 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 685 */ | |
| 686 | |
| 687 bool | |
| 688 RTCPUtility::RTCPParserV2::ParseIJ() | |
| 689 { | |
| 690 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 691 | |
| 692 if (length < 4) | |
| 693 { | |
| 694 return false; | |
| 695 } | |
| 696 | |
| 697 _ptrRTCPData += 4; // Skip header | |
| 698 | |
| 699 _packetType = RTCPPacketTypes::kExtendedIj; | |
| 700 | |
| 701 // State transition | |
| 702 _state = ParseState::State_ExtendedJitterItem; | |
| 703 return true; | |
| 704 } | |
| 705 | |
| 706 bool | |
| 707 RTCPUtility::RTCPParserV2::ParseIJItem() | |
| 708 { | |
| 709 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 710 | |
| 711 if (length < 4 || _numberOfBlocks <= 0) | |
| 712 { | |
| 713 _state = ParseState::State_TopLevel; | |
| 714 EndCurrentBlock(); | |
| 715 return false; | |
| 716 } | |
| 717 | |
| 718 _packet.ExtendedJitterReportItem.Jitter = *_ptrRTCPData++ << 24; | |
| 719 _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++ << 16; | |
| 720 _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++ << 8; | |
| 721 _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++; | |
| 722 | |
| 723 _numberOfBlocks--; | |
| 724 _packetType = RTCPPacketTypes::kExtendedIjItem; | |
| 725 return true; | |
| 726 } | |
| 727 | |
| 728 bool | |
| 729 RTCPUtility::RTCPParserV2::ParseSDES() | |
| 730 { | |
| 731 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 732 | |
| 733 if (length < 8) | |
| 734 { | |
| 735 _state = ParseState::State_TopLevel; | |
| 736 | |
| 737 EndCurrentBlock(); | |
| 738 return false; | |
| 739 } | |
| 740 _ptrRTCPData += 4; // Skip header | |
| 741 | |
| 742 _state = ParseState::State_SDESChunk; | |
| 743 _packetType = RTCPPacketTypes::kSdes; | |
| 744 return true; | |
| 745 } | |
| 746 | |
| 747 bool | |
| 748 RTCPUtility::RTCPParserV2::ParseSDESChunk() | |
| 749 { | |
| 750 if(_numberOfBlocks <= 0) | |
| 751 { | |
| 752 _state = ParseState::State_TopLevel; | |
| 753 | |
| 754 EndCurrentBlock(); | |
| 755 return false; | |
| 756 } | |
| 757 _numberOfBlocks--; | |
| 758 | |
| 759 // Find CName item in a SDES chunk. | |
| 760 while (_ptrRTCPData < _ptrRTCPBlockEnd) | |
| 761 { | |
| 762 const ptrdiff_t dataLen = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 763 if (dataLen < 4) | |
| 764 { | |
| 765 _state = ParseState::State_TopLevel; | |
| 766 | |
| 767 EndCurrentBlock(); | |
| 768 return false; | |
| 769 } | |
| 770 | |
| 771 uint32_t SSRC = *_ptrRTCPData++ << 24; | |
| 772 SSRC += *_ptrRTCPData++ << 16; | |
| 773 SSRC += *_ptrRTCPData++ << 8; | |
| 774 SSRC += *_ptrRTCPData++; | |
| 775 | |
| 776 const bool foundCname = ParseSDESItem(); | |
| 777 if (foundCname) | |
| 778 { | |
| 779 _packet.CName.SenderSSRC = SSRC; // Add SSRC | |
| 780 return true; | |
| 781 } | |
| 782 } | |
| 783 _state = ParseState::State_TopLevel; | |
| 784 | |
| 785 EndCurrentBlock(); | |
| 786 return false; | |
| 787 } | |
| 788 | |
| 789 bool | |
| 790 RTCPUtility::RTCPParserV2::ParseSDESItem() | |
| 791 { | |
| 792 // Find CName | |
| 793 // Only the CNAME item is mandatory. RFC 3550 page 46 | |
| 794 bool foundCName = false; | |
| 795 | |
| 796 size_t itemOctetsRead = 0; | |
| 797 while (_ptrRTCPData < _ptrRTCPBlockEnd) | |
| 798 { | |
| 799 const uint8_t tag = *_ptrRTCPData++; | |
| 800 ++itemOctetsRead; | |
| 801 | |
| 802 if (tag == 0) | |
| 803 { | |
| 804 // End tag! 4 oct aligned | |
| 805 while ((itemOctetsRead++ % 4) != 0) | |
| 806 { | |
| 807 ++_ptrRTCPData; | |
| 808 } | |
| 809 return foundCName; | |
| 810 } | |
| 811 | |
| 812 if (_ptrRTCPData < _ptrRTCPBlockEnd) | |
| 813 { | |
| 814 const uint8_t len = *_ptrRTCPData++; | |
| 815 ++itemOctetsRead; | |
| 816 | |
| 817 if (tag == 1) | |
| 818 { | |
| 819 // CNAME | |
| 820 | |
| 821 // Sanity | |
| 822 if ((_ptrRTCPData + len) >= _ptrRTCPBlockEnd) | |
| 823 { | |
| 824 _state = ParseState::State_TopLevel; | |
| 825 | |
| 826 EndCurrentBlock(); | |
| 827 return false; | |
| 828 } | |
| 829 uint8_t i = 0; | |
| 830 for (; i < len; ++i) | |
| 831 { | |
| 832 const uint8_t c = _ptrRTCPData[i]; | |
| 833 if ((c < ' ') || (c > '{') || (c == '%') || (c == '\\')) | |
| 834 { | |
| 835 // Illegal char | |
| 836 _state = ParseState::State_TopLevel; | |
| 837 | |
| 838 EndCurrentBlock(); | |
| 839 return false; | |
| 840 } | |
| 841 _packet.CName.CName[i] = c; | |
| 842 } | |
| 843 // Make sure we are null terminated. | |
| 844 _packet.CName.CName[i] = 0; | |
| 845 _packetType = RTCPPacketTypes::kSdesChunk; | |
| 846 | |
| 847 foundCName = true; | |
| 848 } | |
| 849 _ptrRTCPData += len; | |
| 850 itemOctetsRead += len; | |
| 851 } | |
| 852 } | |
| 853 | |
| 854 // No end tag found! | |
| 855 _state = ParseState::State_TopLevel; | |
| 856 | |
| 857 EndCurrentBlock(); | |
| 858 return false; | |
| 859 } | |
| 860 | |
| 861 bool | |
| 862 RTCPUtility::RTCPParserV2::ParseBYE() | |
| 863 { | |
| 864 _ptrRTCPData += 4; // Skip header | |
| 865 | |
| 866 _state = ParseState::State_BYEItem; | |
| 867 | |
| 868 return ParseBYEItem(); | |
| 869 } | |
| 870 | |
| 871 bool | |
| 872 RTCPUtility::RTCPParserV2::ParseBYEItem() | |
| 873 { | |
| 874 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 875 if (length < 4 || _numberOfBlocks == 0) | |
| 876 { | |
| 877 _state = ParseState::State_TopLevel; | |
| 878 | |
| 879 EndCurrentBlock(); | |
| 880 return false; | |
| 881 } | |
| 882 | |
| 883 _packetType = RTCPPacketTypes::kBye; | |
| 884 | |
| 885 _packet.BYE.SenderSSRC = *_ptrRTCPData++ << 24; | |
| 886 _packet.BYE.SenderSSRC += *_ptrRTCPData++ << 16; | |
| 887 _packet.BYE.SenderSSRC += *_ptrRTCPData++ << 8; | |
| 888 _packet.BYE.SenderSSRC += *_ptrRTCPData++; | |
| 889 | |
| 890 // we can have several CSRCs attached | |
| 891 | |
| 892 // sanity | |
| 893 if(length >= 4*_numberOfBlocks) | |
| 894 { | |
| 895 _ptrRTCPData += (_numberOfBlocks -1)*4; | |
| 896 } | |
| 897 _numberOfBlocks = 0; | |
| 898 | |
| 899 return true; | |
| 900 } | |
| 901 /* | |
| 902 0 1 2 3 | |
| 903 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 | |
| 904 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 905 |V=2|P|reserved | PT=XR=207 | length | | |
| 906 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 907 | SSRC | | |
| 908 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 909 : report blocks : | |
| 910 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 911 */ | |
| 912 bool RTCPUtility::RTCPParserV2::ParseXr() | |
| 913 { | |
| 914 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 915 if (length < 8) | |
| 916 { | |
| 917 EndCurrentBlock(); | |
| 918 return false; | |
| 919 } | |
| 920 | |
| 921 _ptrRTCPData += 4; // Skip header | |
| 922 | |
| 923 _packet.XR.OriginatorSSRC = *_ptrRTCPData++ << 24; | |
| 924 _packet.XR.OriginatorSSRC += *_ptrRTCPData++ << 16; | |
| 925 _packet.XR.OriginatorSSRC += *_ptrRTCPData++ << 8; | |
| 926 _packet.XR.OriginatorSSRC += *_ptrRTCPData++; | |
| 927 | |
| 928 _packetType = RTCPPacketTypes::kXrHeader; | |
| 929 _state = ParseState::State_XRItem; | |
| 930 return true; | |
| 931 } | |
| 932 | |
| 933 /* Extended report block format (RFC 3611). | |
| 934 BT: block type. | |
| 935 block length: length of report block in 32-bits words minus one (including | |
| 936 the header). | |
| 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 | BT | type-specific | block length | | |
| 941 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 942 : type-specific block contents : | |
| 943 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 944 */ | |
| 945 bool RTCPUtility::RTCPParserV2::ParseXrItem() { | |
| 946 const int kBlockHeaderLengthInBytes = 4; | |
| 947 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 948 if (length < kBlockHeaderLengthInBytes) { | |
| 949 _state = ParseState::State_TopLevel; | |
| 950 EndCurrentBlock(); | |
| 951 return false; | |
| 952 } | |
| 953 | |
| 954 uint8_t block_type = *_ptrRTCPData++; | |
| 955 _ptrRTCPData++; // Ignore reserved. | |
| 956 | |
| 957 uint16_t block_length_in_4bytes = *_ptrRTCPData++ << 8; | |
| 958 block_length_in_4bytes += *_ptrRTCPData++; | |
| 959 | |
| 960 switch (block_type) { | |
| 961 case kBtReceiverReferenceTime: | |
| 962 return ParseXrReceiverReferenceTimeItem(block_length_in_4bytes); | |
| 963 case kBtDlrr: | |
| 964 return ParseXrDlrr(block_length_in_4bytes); | |
| 965 case kBtVoipMetric: | |
| 966 return ParseXrVoipMetricItem(block_length_in_4bytes); | |
| 967 default: | |
| 968 return ParseXrUnsupportedBlockType(block_length_in_4bytes); | |
| 969 } | |
| 970 } | |
| 971 | |
| 972 /* Receiver Reference Time Report Block. | |
| 973 0 1 2 3 | |
| 974 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 | |
| 975 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 976 | BT=4 | reserved | block length = 2 | | |
| 977 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 978 | NTP timestamp, most significant word | | |
| 979 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 980 | NTP timestamp, least significant word | | |
| 981 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 982 */ | |
| 983 bool RTCPUtility::RTCPParserV2::ParseXrReceiverReferenceTimeItem( | |
| 984 int block_length_4bytes) { | |
| 985 const int kBlockLengthIn4Bytes = 2; | |
| 986 const int kBlockLengthInBytes = kBlockLengthIn4Bytes * 4; | |
| 987 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 988 if (block_length_4bytes != kBlockLengthIn4Bytes || | |
| 989 length < kBlockLengthInBytes) { | |
| 990 _state = ParseState::State_TopLevel; | |
| 991 EndCurrentBlock(); | |
| 992 return false; | |
| 993 } | |
| 994 | |
| 995 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant = *_ptrRTCPData++<<24; | |
| 996 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++<<16; | |
| 997 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++<<8; | |
| 998 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++; | |
| 999 | |
| 1000 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant = *_ptrRTCPData++<<24; | |
| 1001 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++<<16; | |
| 1002 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++<<8; | |
| 1003 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++; | |
| 1004 | |
| 1005 _packetType = RTCPPacketTypes::kXrReceiverReferenceTime; | |
| 1006 _state = ParseState::State_XRItem; | |
| 1007 return true; | |
| 1008 } | |
| 1009 | |
| 1010 /* DLRR Report Block. | |
| 1011 0 1 2 3 | |
| 1012 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 | |
| 1013 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1014 | BT=5 | reserved | block length | | |
| 1015 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
| 1016 | SSRC_1 (SSRC of first receiver) | sub- | |
| 1017 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | |
| 1018 | last RR (LRR) | 1 | |
| 1019 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1020 | delay since last RR (DLRR) | | |
| 1021 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
| 1022 | SSRC_2 (SSRC of second receiver) | sub- | |
| 1023 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | |
| 1024 : ... : 2 | |
| 1025 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
| 1026 */ | |
| 1027 bool RTCPUtility::RTCPParserV2::ParseXrDlrr(int block_length_4bytes) { | |
| 1028 const int kSubBlockLengthIn4Bytes = 3; | |
| 1029 if (block_length_4bytes < 0 || | |
| 1030 (block_length_4bytes % kSubBlockLengthIn4Bytes) != 0) { | |
| 1031 _state = ParseState::State_TopLevel; | |
| 1032 EndCurrentBlock(); | |
| 1033 return false; | |
| 1034 } | |
| 1035 _packetType = RTCPPacketTypes::kXrDlrrReportBlock; | |
| 1036 _state = ParseState::State_XR_DLLRItem; | |
| 1037 _numberOfBlocks = block_length_4bytes / kSubBlockLengthIn4Bytes; | |
| 1038 return true; | |
| 1039 } | |
| 1040 | |
| 1041 bool RTCPUtility::RTCPParserV2::ParseXrDlrrItem() { | |
| 1042 if (_numberOfBlocks == 0) { | |
| 1043 _state = ParseState::State_XRItem; | |
| 1044 return false; | |
| 1045 } | |
| 1046 const int kSubBlockLengthInBytes = 12; | |
| 1047 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1048 if (length < kSubBlockLengthInBytes) { | |
| 1049 _state = ParseState::State_TopLevel; | |
| 1050 EndCurrentBlock(); | |
| 1051 return false; | |
| 1052 } | |
| 1053 | |
| 1054 _packet.XRDLRRReportBlockItem.SSRC = *_ptrRTCPData++ << 24; | |
| 1055 _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++ << 16; | |
| 1056 _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++ << 8; | |
| 1057 _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++; | |
| 1058 | |
| 1059 _packet.XRDLRRReportBlockItem.LastRR = *_ptrRTCPData++ << 24; | |
| 1060 _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++ << 16; | |
| 1061 _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++ << 8; | |
| 1062 _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++; | |
| 1063 | |
| 1064 _packet.XRDLRRReportBlockItem.DelayLastRR = *_ptrRTCPData++ << 24; | |
| 1065 _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++ << 16; | |
| 1066 _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++ << 8; | |
| 1067 _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++; | |
| 1068 | |
| 1069 _packetType = RTCPPacketTypes::kXrDlrrReportBlockItem; | |
| 1070 --_numberOfBlocks; | |
| 1071 _state = ParseState::State_XR_DLLRItem; | |
| 1072 return true; | |
| 1073 } | |
| 1074 /* VoIP Metrics Report Block. | |
| 1075 0 1 2 3 | |
| 1076 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 | |
| 1077 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1078 | BT=7 | reserved | block length = 8 | | |
| 1079 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1080 | SSRC of source | | |
| 1081 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1082 | loss rate | discard rate | burst density | gap density | | |
| 1083 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1084 | burst duration | gap duration | | |
| 1085 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1086 | round trip delay | end system delay | | |
| 1087 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1088 | signal level | noise level | RERL | Gmin | | |
| 1089 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1090 | R factor | ext. R factor | MOS-LQ | MOS-CQ | | |
| 1091 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1092 | RX config | reserved | JB nominal | | |
| 1093 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1094 | JB maximum | JB abs max | | |
| 1095 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1096 */ | |
| 1097 | |
| 1098 bool RTCPUtility::RTCPParserV2::ParseXrVoipMetricItem(int block_length_4bytes) { | |
| 1099 const int kBlockLengthIn4Bytes = 8; | |
| 1100 const int kBlockLengthInBytes = kBlockLengthIn4Bytes * 4; | |
| 1101 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1102 if (block_length_4bytes != kBlockLengthIn4Bytes || | |
| 1103 length < kBlockLengthInBytes) { | |
| 1104 _state = ParseState::State_TopLevel; | |
| 1105 EndCurrentBlock(); | |
| 1106 return false; | |
| 1107 } | |
| 1108 | |
| 1109 _packet.XRVOIPMetricItem.SSRC = *_ptrRTCPData++ << 24; | |
| 1110 _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++ << 16; | |
| 1111 _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++ << 8; | |
| 1112 _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++; | |
| 1113 | |
| 1114 _packet.XRVOIPMetricItem.lossRate = *_ptrRTCPData++; | |
| 1115 _packet.XRVOIPMetricItem.discardRate = *_ptrRTCPData++; | |
| 1116 _packet.XRVOIPMetricItem.burstDensity = *_ptrRTCPData++; | |
| 1117 _packet.XRVOIPMetricItem.gapDensity = *_ptrRTCPData++; | |
| 1118 | |
| 1119 _packet.XRVOIPMetricItem.burstDuration = *_ptrRTCPData++ << 8; | |
| 1120 _packet.XRVOIPMetricItem.burstDuration += *_ptrRTCPData++; | |
| 1121 | |
| 1122 _packet.XRVOIPMetricItem.gapDuration = *_ptrRTCPData++ << 8; | |
| 1123 _packet.XRVOIPMetricItem.gapDuration += *_ptrRTCPData++; | |
| 1124 | |
| 1125 _packet.XRVOIPMetricItem.roundTripDelay = *_ptrRTCPData++ << 8; | |
| 1126 _packet.XRVOIPMetricItem.roundTripDelay += *_ptrRTCPData++; | |
| 1127 | |
| 1128 _packet.XRVOIPMetricItem.endSystemDelay = *_ptrRTCPData++ << 8; | |
| 1129 _packet.XRVOIPMetricItem.endSystemDelay += *_ptrRTCPData++; | |
| 1130 | |
| 1131 _packet.XRVOIPMetricItem.signalLevel = *_ptrRTCPData++; | |
| 1132 _packet.XRVOIPMetricItem.noiseLevel = *_ptrRTCPData++; | |
| 1133 _packet.XRVOIPMetricItem.RERL = *_ptrRTCPData++; | |
| 1134 _packet.XRVOIPMetricItem.Gmin = *_ptrRTCPData++; | |
| 1135 _packet.XRVOIPMetricItem.Rfactor = *_ptrRTCPData++; | |
| 1136 _packet.XRVOIPMetricItem.extRfactor = *_ptrRTCPData++; | |
| 1137 _packet.XRVOIPMetricItem.MOSLQ = *_ptrRTCPData++; | |
| 1138 _packet.XRVOIPMetricItem.MOSCQ = *_ptrRTCPData++; | |
| 1139 _packet.XRVOIPMetricItem.RXconfig = *_ptrRTCPData++; | |
| 1140 _ptrRTCPData++; // skip reserved | |
| 1141 | |
| 1142 _packet.XRVOIPMetricItem.JBnominal = *_ptrRTCPData++ << 8; | |
| 1143 _packet.XRVOIPMetricItem.JBnominal += *_ptrRTCPData++; | |
| 1144 | |
| 1145 _packet.XRVOIPMetricItem.JBmax = *_ptrRTCPData++ << 8; | |
| 1146 _packet.XRVOIPMetricItem.JBmax += *_ptrRTCPData++; | |
| 1147 | |
| 1148 _packet.XRVOIPMetricItem.JBabsMax = *_ptrRTCPData++ << 8; | |
| 1149 _packet.XRVOIPMetricItem.JBabsMax += *_ptrRTCPData++; | |
| 1150 | |
| 1151 _packetType = RTCPPacketTypes::kXrVoipMetric; | |
| 1152 _state = ParseState::State_XRItem; | |
| 1153 return true; | |
| 1154 } | |
| 1155 | |
| 1156 bool RTCPUtility::RTCPParserV2::ParseXrUnsupportedBlockType( | |
| 1157 int block_length_4bytes) { | |
| 1158 const int32_t kBlockLengthInBytes = block_length_4bytes * 4; | |
| 1159 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1160 if (length < kBlockLengthInBytes) { | |
| 1161 _state = ParseState::State_TopLevel; | |
| 1162 EndCurrentBlock(); | |
| 1163 return false; | |
| 1164 } | |
| 1165 // Skip block. | |
| 1166 _ptrRTCPData += kBlockLengthInBytes; | |
| 1167 _state = ParseState::State_XRItem; | |
| 1168 return false; | |
| 1169 } | |
| 1170 | |
| 1171 bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { | |
| 1172 RTC_CHECK((header.packet_type == PT_RTPFB) || | |
| 1173 (header.packet_type == PT_PSFB)); // Parser logic check | |
| 1174 | |
| 1175 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1176 | |
| 1177 // 4 * 3, RFC4585 section 6.1 | |
| 1178 if (length < 12) { | |
| 1179 LOG(LS_WARNING) | |
| 1180 << "Invalid RTCP packet: Too little data (" << length | |
| 1181 << " bytes) left in buffer to parse a 12 byte RTPFB/PSFB message."; | |
| 1182 return false; | |
| 1183 } | |
| 1184 | |
| 1185 _ptrRTCPData += 4; // Skip RTCP header | |
| 1186 | |
| 1187 uint32_t senderSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData); | |
| 1188 _ptrRTCPData += 4; | |
| 1189 | |
| 1190 uint32_t mediaSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData); | |
| 1191 _ptrRTCPData += 4; | |
| 1192 | |
| 1193 if (header.packet_type == PT_RTPFB) { | |
| 1194 // Transport layer feedback | |
| 1195 | |
| 1196 switch (header.count_or_format) { | |
| 1197 case 1: | |
| 1198 { | |
| 1199 // NACK | |
| 1200 _packetType = RTCPPacketTypes::kRtpfbNack; | |
| 1201 _packet.NACK.SenderSSRC = senderSSRC; | |
| 1202 _packet.NACK.MediaSSRC = mediaSSRC; | |
| 1203 | |
| 1204 _state = ParseState::State_RTPFB_NACKItem; | |
| 1205 | |
| 1206 return true; | |
| 1207 } | |
| 1208 case 3: | |
| 1209 { | |
| 1210 // TMMBR | |
| 1211 _packetType = RTCPPacketTypes::kRtpfbTmmbr; | |
| 1212 _packet.TMMBR.SenderSSRC = senderSSRC; | |
| 1213 _packet.TMMBR.MediaSSRC = mediaSSRC; | |
| 1214 | |
| 1215 _state = ParseState::State_RTPFB_TMMBRItem; | |
| 1216 | |
| 1217 return true; | |
| 1218 } | |
| 1219 case 4: | |
| 1220 { | |
| 1221 // TMMBN | |
| 1222 _packetType = RTCPPacketTypes::kRtpfbTmmbn; | |
| 1223 _packet.TMMBN.SenderSSRC = senderSSRC; | |
| 1224 _packet.TMMBN.MediaSSRC = mediaSSRC; | |
| 1225 | |
| 1226 _state = ParseState::State_RTPFB_TMMBNItem; | |
| 1227 | |
| 1228 return true; | |
| 1229 } | |
| 1230 case 5: | |
| 1231 { | |
| 1232 // RTCP-SR-REQ Rapid Synchronisation of RTP Flows | |
| 1233 // draft-perkins-avt-rapid-rtp-sync-03.txt | |
| 1234 // trigger a new RTCP SR | |
| 1235 _packetType = RTCPPacketTypes::kRtpfbSrReq; | |
| 1236 | |
| 1237 // Note: No state transition, SR REQ is empty! | |
| 1238 return true; | |
| 1239 } | |
| 1240 case 15: { | |
| 1241 rtcp_packet_ = | |
| 1242 rtcp::TransportFeedback::ParseFrom(_ptrRTCPData - 12, length); | |
| 1243 // Since we parse the whole packet here, keep the TopLevel state and | |
| 1244 // just end the current block. | |
| 1245 EndCurrentBlock(); | |
| 1246 if (rtcp_packet_.get()) { | |
| 1247 _packetType = RTCPPacketTypes::kTransportFeedback; | |
| 1248 return true; | |
| 1249 } | |
| 1250 break; | |
| 1251 } | |
| 1252 default: | |
| 1253 break; | |
| 1254 } | |
| 1255 // Unsupported RTPFB message. Skip and move to next block. | |
| 1256 ++num_skipped_blocks_; | |
| 1257 return false; | |
| 1258 } else if (header.packet_type == PT_PSFB) { | |
| 1259 // Payload specific feedback | |
| 1260 switch (header.count_or_format) { | |
| 1261 case 1: | |
| 1262 // PLI | |
| 1263 _packetType = RTCPPacketTypes::kPsfbPli; | |
| 1264 _packet.PLI.SenderSSRC = senderSSRC; | |
| 1265 _packet.PLI.MediaSSRC = mediaSSRC; | |
| 1266 | |
| 1267 // Note: No state transition, PLI FCI is empty! | |
| 1268 return true; | |
| 1269 case 2: | |
| 1270 // SLI | |
| 1271 _packetType = RTCPPacketTypes::kPsfbSli; | |
| 1272 _packet.SLI.SenderSSRC = senderSSRC; | |
| 1273 _packet.SLI.MediaSSRC = mediaSSRC; | |
| 1274 | |
| 1275 _state = ParseState::State_PSFB_SLIItem; | |
| 1276 | |
| 1277 return true; | |
| 1278 case 3: | |
| 1279 _packetType = RTCPPacketTypes::kPsfbRpsi; | |
| 1280 _packet.RPSI.SenderSSRC = senderSSRC; | |
| 1281 _packet.RPSI.MediaSSRC = mediaSSRC; | |
| 1282 | |
| 1283 _state = ParseState::State_PSFB_RPSIItem; | |
| 1284 return true; | |
| 1285 case 4: | |
| 1286 // FIR | |
| 1287 _packetType = RTCPPacketTypes::kPsfbFir; | |
| 1288 _packet.FIR.SenderSSRC = senderSSRC; | |
| 1289 _packet.FIR.MediaSSRC = mediaSSRC; | |
| 1290 | |
| 1291 _state = ParseState::State_PSFB_FIRItem; | |
| 1292 return true; | |
| 1293 case 15: | |
| 1294 _packetType = RTCPPacketTypes::kPsfbApp; | |
| 1295 _packet.PSFBAPP.SenderSSRC = senderSSRC; | |
| 1296 _packet.PSFBAPP.MediaSSRC = mediaSSRC; | |
| 1297 | |
| 1298 _state = ParseState::State_PSFB_AppItem; | |
| 1299 return true; | |
| 1300 default: | |
| 1301 break; | |
| 1302 } | |
| 1303 | |
| 1304 return false; | |
| 1305 } | |
| 1306 else | |
| 1307 { | |
| 1308 RTC_NOTREACHED(); | |
| 1309 return false; | |
| 1310 } | |
| 1311 } | |
| 1312 | |
| 1313 bool RTCPUtility::RTCPParserV2::ParseRPSIItem() { | |
| 1314 | |
| 1315 // RFC 4585 6.3.3. Reference Picture Selection Indication (RPSI). | |
| 1316 // | |
| 1317 // 0 1 2 3 | |
| 1318 // 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 | |
| 1319 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1320 // | PB |0| Payload Type| Native RPSI bit string | | |
| 1321 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1322 // | defined per codec ... | Padding (0) | | |
| 1323 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1324 | |
| 1325 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1326 | |
| 1327 if (length < 4) { | |
| 1328 _state = ParseState::State_TopLevel; | |
| 1329 | |
| 1330 EndCurrentBlock(); | |
| 1331 return false; | |
| 1332 } | |
| 1333 if (length > 2 + RTCP_RPSI_DATA_SIZE) { | |
| 1334 _state = ParseState::State_TopLevel; | |
| 1335 | |
| 1336 EndCurrentBlock(); | |
| 1337 return false; | |
| 1338 } | |
| 1339 | |
| 1340 | |
| 1341 uint8_t padding_bits = *_ptrRTCPData++; | |
| 1342 _packet.RPSI.PayloadType = *_ptrRTCPData++; | |
| 1343 | |
| 1344 if (padding_bits > static_cast<uint16_t>(length - 2) * 8) { | |
| 1345 _state = ParseState::State_TopLevel; | |
| 1346 | |
| 1347 EndCurrentBlock(); | |
| 1348 return false; | |
| 1349 } | |
| 1350 | |
| 1351 _packetType = RTCPPacketTypes::kPsfbRpsiItem; | |
| 1352 | |
| 1353 memcpy(_packet.RPSI.NativeBitString, _ptrRTCPData, length - 2); | |
| 1354 _ptrRTCPData += length - 2; | |
| 1355 | |
| 1356 _packet.RPSI.NumberOfValidBits = | |
| 1357 static_cast<uint16_t>(length - 2) * 8 - padding_bits; | |
| 1358 return true; | |
| 1359 } | |
| 1360 | |
| 1361 bool | |
| 1362 RTCPUtility::RTCPParserV2::ParseNACKItem() | |
| 1363 { | |
| 1364 // RFC 4585 6.2.1. Generic NACK | |
| 1365 | |
| 1366 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1367 | |
| 1368 if (length < 4) | |
| 1369 { | |
| 1370 _state = ParseState::State_TopLevel; | |
| 1371 | |
| 1372 EndCurrentBlock(); | |
| 1373 return false; | |
| 1374 } | |
| 1375 | |
| 1376 _packetType = RTCPPacketTypes::kRtpfbNackItem; | |
| 1377 | |
| 1378 _packet.NACKItem.PacketID = *_ptrRTCPData++ << 8; | |
| 1379 _packet.NACKItem.PacketID += *_ptrRTCPData++; | |
| 1380 | |
| 1381 _packet.NACKItem.BitMask = *_ptrRTCPData++ << 8; | |
| 1382 _packet.NACKItem.BitMask += *_ptrRTCPData++; | |
| 1383 | |
| 1384 return true; | |
| 1385 } | |
| 1386 | |
| 1387 bool | |
| 1388 RTCPUtility::RTCPParserV2::ParsePsfbAppItem() | |
| 1389 { | |
| 1390 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1391 | |
| 1392 if (length < 4) | |
| 1393 { | |
| 1394 _state = ParseState::State_TopLevel; | |
| 1395 | |
| 1396 EndCurrentBlock(); | |
| 1397 return false; | |
| 1398 } | |
| 1399 if(*_ptrRTCPData++ != 'R') | |
| 1400 { | |
| 1401 _state = ParseState::State_TopLevel; | |
| 1402 | |
| 1403 EndCurrentBlock(); | |
| 1404 return false; | |
| 1405 } | |
| 1406 if(*_ptrRTCPData++ != 'E') | |
| 1407 { | |
| 1408 _state = ParseState::State_TopLevel; | |
| 1409 | |
| 1410 EndCurrentBlock(); | |
| 1411 return false; | |
| 1412 } | |
| 1413 if(*_ptrRTCPData++ != 'M') | |
| 1414 { | |
| 1415 _state = ParseState::State_TopLevel; | |
| 1416 | |
| 1417 EndCurrentBlock(); | |
| 1418 return false; | |
| 1419 } | |
| 1420 if(*_ptrRTCPData++ != 'B') | |
| 1421 { | |
| 1422 _state = ParseState::State_TopLevel; | |
| 1423 | |
| 1424 EndCurrentBlock(); | |
| 1425 return false; | |
| 1426 } | |
| 1427 _packetType = RTCPPacketTypes::kPsfbRemb; | |
| 1428 _state = ParseState::State_PSFB_REMBItem; | |
| 1429 return true; | |
| 1430 } | |
| 1431 | |
| 1432 bool | |
| 1433 RTCPUtility::RTCPParserV2::ParsePsfbREMBItem() | |
| 1434 { | |
| 1435 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1436 | |
| 1437 if (length < 4) | |
| 1438 { | |
| 1439 _state = ParseState::State_TopLevel; | |
| 1440 | |
| 1441 EndCurrentBlock(); | |
| 1442 return false; | |
| 1443 } | |
| 1444 | |
| 1445 _packet.REMBItem.NumberOfSSRCs = *_ptrRTCPData++; | |
| 1446 const uint8_t exp = (_ptrRTCPData[0] >> 2) & 0x3F; | |
| 1447 | |
| 1448 uint64_t mantissa = (_ptrRTCPData[0] & 0x03) << 16; | |
| 1449 mantissa += (_ptrRTCPData[1] << 8); | |
| 1450 mantissa += (_ptrRTCPData[2]); | |
| 1451 | |
| 1452 _ptrRTCPData += 3; // Fwd read data | |
| 1453 uint64_t bitrate_bps = (mantissa << exp); | |
| 1454 bool shift_overflow = exp > 0 && (mantissa >> (64 - exp)) != 0; | |
| 1455 if (shift_overflow || bitrate_bps > kMaxBitrateBps) { | |
| 1456 LOG(LS_ERROR) << "Unhandled remb bitrate value : " << mantissa | |
| 1457 << "*2^" << static_cast<int>(exp); | |
| 1458 _state = ParseState::State_TopLevel; | |
| 1459 EndCurrentBlock(); | |
| 1460 return false; | |
| 1461 } | |
| 1462 _packet.REMBItem.BitRate = bitrate_bps; | |
| 1463 | |
| 1464 const ptrdiff_t length_ssrcs = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1465 if (length_ssrcs < 4 * _packet.REMBItem.NumberOfSSRCs) | |
| 1466 { | |
| 1467 _state = ParseState::State_TopLevel; | |
| 1468 | |
| 1469 EndCurrentBlock(); | |
| 1470 return false; | |
| 1471 } | |
| 1472 | |
| 1473 _packetType = RTCPPacketTypes::kPsfbRembItem; | |
| 1474 | |
| 1475 for (int i = 0; i < _packet.REMBItem.NumberOfSSRCs; i++) | |
| 1476 { | |
| 1477 _packet.REMBItem.SSRCs[i] = *_ptrRTCPData++ << 24; | |
| 1478 _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++ << 16; | |
| 1479 _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++ << 8; | |
| 1480 _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++; | |
| 1481 } | |
| 1482 return true; | |
| 1483 } | |
| 1484 | |
| 1485 bool | |
| 1486 RTCPUtility::RTCPParserV2::ParseTMMBRItem() | |
| 1487 { | |
| 1488 // RFC 5104 4.2.1. Temporary Maximum Media Stream Bit Rate Request (TMMBR) | |
| 1489 | |
| 1490 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1491 | |
| 1492 if (length < 8) | |
| 1493 { | |
| 1494 _state = ParseState::State_TopLevel; | |
| 1495 | |
| 1496 EndCurrentBlock(); | |
| 1497 return false; | |
| 1498 } | |
| 1499 | |
| 1500 _packetType = RTCPPacketTypes::kRtpfbTmmbrItem; | |
| 1501 | |
| 1502 _packet.TMMBRItem.SSRC = *_ptrRTCPData++ << 24; | |
| 1503 _packet.TMMBRItem.SSRC += *_ptrRTCPData++ << 16; | |
| 1504 _packet.TMMBRItem.SSRC += *_ptrRTCPData++ << 8; | |
| 1505 _packet.TMMBRItem.SSRC += *_ptrRTCPData++; | |
| 1506 | |
| 1507 uint8_t exp = (_ptrRTCPData[0] >> 2) & 0x3F; | |
| 1508 | |
| 1509 uint64_t mantissa = (_ptrRTCPData[0] & 0x03) << 15; | |
| 1510 mantissa += (_ptrRTCPData[1] << 7); | |
| 1511 mantissa += (_ptrRTCPData[2] >> 1) & 0x7F; | |
| 1512 | |
| 1513 uint32_t measuredOH = (_ptrRTCPData[2] & 0x01) << 8; | |
| 1514 measuredOH += _ptrRTCPData[3]; | |
| 1515 | |
| 1516 _ptrRTCPData += 4; // Fwd read data | |
| 1517 | |
| 1518 uint64_t bitrate_bps = (mantissa << exp); | |
| 1519 bool shift_overflow = exp > 0 && (mantissa >> (64 - exp)) != 0; | |
| 1520 if (shift_overflow || bitrate_bps > kMaxBitrateBps) { | |
| 1521 LOG(LS_ERROR) << "Unhandled tmmbr bitrate value : " << mantissa | |
| 1522 << "*2^" << static_cast<int>(exp); | |
| 1523 _state = ParseState::State_TopLevel; | |
| 1524 EndCurrentBlock(); | |
| 1525 return false; | |
| 1526 } | |
| 1527 | |
| 1528 _packet.TMMBRItem.MaxTotalMediaBitRate = bitrate_bps / 1000; | |
| 1529 _packet.TMMBRItem.MeasuredOverhead = measuredOH; | |
| 1530 | |
| 1531 return true; | |
| 1532 } | |
| 1533 | |
| 1534 bool | |
| 1535 RTCPUtility::RTCPParserV2::ParseTMMBNItem() | |
| 1536 { | |
| 1537 // RFC 5104 4.2.2. Temporary Maximum Media Stream Bit Rate Notification (TMM
BN) | |
| 1538 | |
| 1539 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1540 | |
| 1541 if (length < 8) | |
| 1542 { | |
| 1543 _state = ParseState::State_TopLevel; | |
| 1544 | |
| 1545 EndCurrentBlock(); | |
| 1546 return false; | |
| 1547 } | |
| 1548 | |
| 1549 _packetType = RTCPPacketTypes::kRtpfbTmmbnItem; | |
| 1550 | |
| 1551 _packet.TMMBNItem.SSRC = *_ptrRTCPData++ << 24; | |
| 1552 _packet.TMMBNItem.SSRC += *_ptrRTCPData++ << 16; | |
| 1553 _packet.TMMBNItem.SSRC += *_ptrRTCPData++ << 8; | |
| 1554 _packet.TMMBNItem.SSRC += *_ptrRTCPData++; | |
| 1555 | |
| 1556 uint8_t exp = (_ptrRTCPData[0] >> 2) & 0x3F; | |
| 1557 | |
| 1558 uint64_t mantissa = (_ptrRTCPData[0] & 0x03) << 15; | |
| 1559 mantissa += (_ptrRTCPData[1] << 7); | |
| 1560 mantissa += (_ptrRTCPData[2] >> 1) & 0x7F; | |
| 1561 | |
| 1562 uint32_t measuredOH = (_ptrRTCPData[2] & 0x01) << 8; | |
| 1563 measuredOH += _ptrRTCPData[3]; | |
| 1564 | |
| 1565 _ptrRTCPData += 4; // Fwd read data | |
| 1566 | |
| 1567 uint64_t bitrate_bps = (mantissa << exp); | |
| 1568 bool shift_overflow = exp > 0 && (mantissa >> (64 - exp)) != 0; | |
| 1569 if (shift_overflow || bitrate_bps > kMaxBitrateBps) { | |
| 1570 LOG(LS_ERROR) << "Unhandled tmmbn bitrate value : " << mantissa | |
| 1571 << "*2^" << static_cast<int>(exp); | |
| 1572 _state = ParseState::State_TopLevel; | |
| 1573 EndCurrentBlock(); | |
| 1574 return false; | |
| 1575 } | |
| 1576 | |
| 1577 _packet.TMMBNItem.MaxTotalMediaBitRate = bitrate_bps / 1000; | |
| 1578 _packet.TMMBNItem.MeasuredOverhead = measuredOH; | |
| 1579 | |
| 1580 return true; | |
| 1581 } | |
| 1582 | |
| 1583 bool | |
| 1584 RTCPUtility::RTCPParserV2::ParseSLIItem() | |
| 1585 { | |
| 1586 // RFC 5104 6.3.2. Slice Loss Indication (SLI) | |
| 1587 /* | |
| 1588 0 1 2 3 | |
| 1589 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 | |
| 1590 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1591 | First | Number | PictureID | | |
| 1592 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 1593 */ | |
| 1594 | |
| 1595 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1596 | |
| 1597 if (length < 4) | |
| 1598 { | |
| 1599 _state = ParseState::State_TopLevel; | |
| 1600 | |
| 1601 EndCurrentBlock(); | |
| 1602 return false; | |
| 1603 } | |
| 1604 _packetType = RTCPPacketTypes::kPsfbSliItem; | |
| 1605 | |
| 1606 uint32_t buffer; | |
| 1607 buffer = *_ptrRTCPData++ << 24; | |
| 1608 buffer += *_ptrRTCPData++ << 16; | |
| 1609 buffer += *_ptrRTCPData++ << 8; | |
| 1610 buffer += *_ptrRTCPData++; | |
| 1611 | |
| 1612 _packet.SLIItem.FirstMB = uint16_t((buffer>>19) & 0x1fff); | |
| 1613 _packet.SLIItem.NumberOfMB = uint16_t((buffer>>6) & 0x1fff); | |
| 1614 _packet.SLIItem.PictureId = uint8_t(buffer & 0x3f); | |
| 1615 | |
| 1616 return true; | |
| 1617 } | |
| 1618 | |
| 1619 bool | |
| 1620 RTCPUtility::RTCPParserV2::ParseFIRItem() | |
| 1621 { | |
| 1622 // RFC 5104 4.3.1. Full Intra Request (FIR) | |
| 1623 | |
| 1624 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1625 | |
| 1626 if (length < 8) | |
| 1627 { | |
| 1628 _state = ParseState::State_TopLevel; | |
| 1629 | |
| 1630 EndCurrentBlock(); | |
| 1631 return false; | |
| 1632 } | |
| 1633 | |
| 1634 _packetType = RTCPPacketTypes::kPsfbFirItem; | |
| 1635 | |
| 1636 _packet.FIRItem.SSRC = *_ptrRTCPData++ << 24; | |
| 1637 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 16; | |
| 1638 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 8; | |
| 1639 _packet.FIRItem.SSRC += *_ptrRTCPData++; | |
| 1640 | |
| 1641 _packet.FIRItem.CommandSequenceNumber = *_ptrRTCPData++; | |
| 1642 _ptrRTCPData += 3; // Skip "Reserved" bytes. | |
| 1643 return true; | |
| 1644 } | |
| 1645 | |
| 1646 bool RTCPUtility::RTCPParserV2::ParseAPP(const RtcpCommonHeader& header) { | |
| 1647 ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1648 | |
| 1649 if (length < 12) // 4 * 3, RFC 3550 6.7 APP: Application-Defined RTCP Packet | |
| 1650 { | |
| 1651 EndCurrentBlock(); | |
| 1652 return false; | |
| 1653 } | |
| 1654 | |
| 1655 _ptrRTCPData += 4; // Skip RTCP header | |
| 1656 | |
| 1657 uint32_t senderSSRC = *_ptrRTCPData++ << 24; | |
| 1658 senderSSRC += *_ptrRTCPData++ << 16; | |
| 1659 senderSSRC += *_ptrRTCPData++ << 8; | |
| 1660 senderSSRC += *_ptrRTCPData++; | |
| 1661 | |
| 1662 uint32_t name = *_ptrRTCPData++ << 24; | |
| 1663 name += *_ptrRTCPData++ << 16; | |
| 1664 name += *_ptrRTCPData++ << 8; | |
| 1665 name += *_ptrRTCPData++; | |
| 1666 | |
| 1667 length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1668 | |
| 1669 _packetType = RTCPPacketTypes::kApp; | |
| 1670 | |
| 1671 _packet.APP.SubType = header.count_or_format; | |
| 1672 _packet.APP.Name = name; | |
| 1673 | |
| 1674 _state = ParseState::State_AppItem; | |
| 1675 return true; | |
| 1676 } | |
| 1677 | |
| 1678 bool | |
| 1679 RTCPUtility::RTCPParserV2::ParseAPPItem() | |
| 1680 { | |
| 1681 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | |
| 1682 if (length < 4) | |
| 1683 { | |
| 1684 _state = ParseState::State_TopLevel; | |
| 1685 | |
| 1686 EndCurrentBlock(); | |
| 1687 return false; | |
| 1688 } | |
| 1689 _packetType = RTCPPacketTypes::kAppItem; | |
| 1690 | |
| 1691 if(length > kRtcpAppCode_DATA_SIZE) | |
| 1692 { | |
| 1693 memcpy(_packet.APP.Data, _ptrRTCPData, kRtcpAppCode_DATA_SIZE); | |
| 1694 _packet.APP.Size = kRtcpAppCode_DATA_SIZE; | |
| 1695 _ptrRTCPData += kRtcpAppCode_DATA_SIZE; | |
| 1696 }else | |
| 1697 { | |
| 1698 memcpy(_packet.APP.Data, _ptrRTCPData, length); | |
| 1699 _packet.APP.Size = (uint16_t)length; | |
| 1700 _ptrRTCPData += length; | |
| 1701 } | |
| 1702 return true; | |
| 1703 } | |
| 1704 | |
| 1705 size_t RTCPUtility::RTCPParserV2::NumSkippedBlocks() const { | |
| 1706 return num_skipped_blocks_; | |
| 1707 } | |
| 1708 | |
| 1709 RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData, | |
| 1710 size_t rtcpDataLength) | |
| 1711 : _ptrBegin(rtcpData), | |
| 1712 _ptrEnd(rtcpData + rtcpDataLength), | |
| 1713 _ptrBlock(NULL) { | |
| 1714 memset(&_header, 0, sizeof(_header)); | |
| 1715 } | |
| 1716 | |
| 1717 RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() { | |
| 1718 } | |
| 1719 | |
| 1720 const RTCPUtility::RtcpCommonHeader* RTCPUtility::RTCPPacketIterator::Begin() { | |
| 1721 _ptrBlock = _ptrBegin; | |
| 1722 | |
| 1723 return Iterate(); | |
| 1724 } | |
| 1725 | |
| 1726 const RTCPUtility::RtcpCommonHeader* | |
| 1727 RTCPUtility::RTCPPacketIterator::Iterate() { | |
| 1728 if ((_ptrEnd <= _ptrBlock) || | |
| 1729 !RtcpParseCommonHeader(_ptrBlock, _ptrEnd - _ptrBlock, &_header)) { | |
| 1730 _ptrBlock = nullptr; | |
| 1731 return nullptr; | |
| 1732 } | |
| 1733 _ptrBlock += _header.BlockSize(); | |
| 1734 | |
| 1735 if (_ptrBlock > _ptrEnd) { | |
| 1736 _ptrBlock = nullptr; | |
| 1737 return nullptr; | |
| 1738 } | |
| 1739 | |
| 1740 return &_header; | |
| 1741 } | |
| 1742 | |
| 1743 const RTCPUtility::RtcpCommonHeader* | |
| 1744 RTCPUtility::RTCPPacketIterator::Current() { | |
| 1745 if (!_ptrBlock) | |
| 1746 { | |
| 1747 return NULL; | |
| 1748 } | |
| 1749 | |
| 1750 return &_header; | |
| 1751 } | |
| 1752 } // namespace webrtc | |
| OLD | NEW |