1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/cast/rtcp/rtcp_utility.h" 6 7 #include "base/logging.h" 8 #include "net/base/big_endian.h" 9 10 namespace media { 11 namespace cast { 12 13 RtcpParser::RtcpParser(const uint8* rtcpData, size_t rtcpDataLength) 14 : rtcp_data_begin_(rtcpData), 15 rtcp_data_end_(rtcpData + rtcpDataLength), 16 valid_packet_(false), 17 rtcp_data_(rtcpData), 18 rtcp_block_end_(NULL), 19 state_(kStateTopLevel), 20 number_of_blocks_(0), 21 field_type_(kRtcpNotValidCode) { 22 Validate(); 23 } 24 25 RtcpParser::~RtcpParser() {} 26 27 RtcpFieldTypes RtcpParser::FieldType() const { 28 return field_type_; 29 } 30 31 const RtcpField& RtcpParser::Field() const { 32 return field_; 33 } 34 35 RtcpFieldTypes RtcpParser::Begin() { 36 rtcp_data_ = rtcp_data_begin_; 37 return Iterate(); 38 } 39 40 RtcpFieldTypes RtcpParser::Iterate() { 41 // Reset packet type 42 field_type_ = kRtcpNotValidCode; 43 44 if (!IsValid()) return kRtcpNotValidCode; 45 46 switch (state_) { 47 case kStateTopLevel: 48 IterateTopLevel(); 49 break; 50 case kStateReportBlock: 51 IterateReportBlockItem(); 52 break; 53 case kStateSdes: 54 IterateSdesItem(); 55 break; 56 case kStateBye: 57 IterateByeItem(); 58 break; 59 case kStateApplicationSpecificCastReceiverFrameLog: 60 IterateCastReceiverLogFrame(); 61 break; 62 case kStateApplicationSpecificCastReceiverEventLog: 63 IterateCastReceiverLogEvent(); 64 break; 65 case kStateApplicationSpecificCastSenderLog: 66 IterateCastSenderLog(); 67 break; 68 case kStateExtendedReportBlock: 69 IterateExtendedReportItem(); 70 break; 71 case kStateExtendedReportDelaySinceLastReceiverReport: 72 IterateExtendedReportDelaySinceLastReceiverReportItem(); 73 break; 74 case kStateGenericRtpFeedbackNack: 75 IterateNackItem(); 76 break; 77 case kStatePayloadSpecificRpsi: 78 IterateRpsiItem(); 79 break; 80 case kStatePayloadSpecificFir: 81 IterateFirItem(); 82 break; 83 case kStatePayloadSpecificApplication: 84 IteratePayloadSpecificAppItem(); 85 break; 86 case kStatePayloadSpecificRemb: 87 IteratePayloadSpecificRembItem(); 88 break; 89 case kStatePayloadSpecificCast: 90 IteratePayloadSpecificCastItem(); 91 break; 92 case kStatePayloadSpecificCastNack: 93 IteratePayloadSpecificCastNackItem(); 94 break; 95 } 96 return field_type_; 97 } 98 99 void RtcpParser::IterateTopLevel() { 100 for (;;) { 101 RtcpCommonHeader header; 102 103 bool success = RtcpParseCommonHeader(rtcp_data_, rtcp_data_end_, &header); 104 if (!success) return; 105 106 rtcp_block_end_ = rtcp_data_ + header.length_in_octets; 107 108 if (rtcp_block_end_ > rtcp_data_end_) return; // Bad block! 109 110 switch (header.PT) { 111 case kPacketTypeSenderReport: 112 // number of Report blocks 113 number_of_blocks_ = header.IC; 114 ParseSR(); 115 return; 116 case kPacketTypeReceiverReport: 117 // number of Report blocks 118 number_of_blocks_ = header.IC; 119 ParseRR(); 120 return; 121 case kPacketTypeSdes: 122 // number of Sdes blocks 123 number_of_blocks_ = header.IC; 124 if (!ParseSdes()) { 125 break; // Nothing supported found, continue to next block! 126 } 127 return; 128 case kPacketTypeBye: 129 number_of_blocks_ = header.IC; 130 if (!ParseBye()) { 131 // Nothing supported found, continue to next block! 132 break; 133 } 134 return; 135 case kPacketTypeApplicationDefined: 136 if (!ParseApplicationDefined(header.IC)) { 137 // Nothing supported found, continue to next block! 138 break; 139 } 140 return; 141 case kPacketTypeGenericRtpFeedback: // Fall through! 142 case kPacketTypePayloadSpecific: 143 if (!ParseFeedBackCommon(header)) { 144 // Nothing supported found, continue to next block! 145 break; 146 } 147 return; 148 case kPacketTypeXr: 149 if (!ParseExtendedReport()) { 150 break; // Nothing supported found, continue to next block! 151 } 152 return; 153 default: 154 // Not supported! Skip! 155 EndCurrentBlock(); 156 break; 157 } 158 } 159 } 160 161 void RtcpParser::IterateReportBlockItem() { 162 bool success = ParseReportBlockItem(); 163 if (!success) Iterate(); 164 } 165 166 void RtcpParser::IterateSdesItem() { 167 bool success = ParseSdesItem(); 168 if (!success) Iterate(); 169 } 170 171 void RtcpParser::IterateByeItem() { 172 bool success = ParseByeItem(); 173 if (!success) Iterate(); 174 } 175 176 void RtcpParser::IterateExtendedReportItem() { 177 bool success = ParseExtendedReportItem(); 178 if (!success) Iterate(); 179 } 180 181 void RtcpParser::IterateExtendedReportDelaySinceLastReceiverReportItem() { 182 bool success = ParseExtendedReportDelaySinceLastReceiverReport(); 183 if (!success) Iterate(); 184 } 185 186 void RtcpParser::IterateNackItem() { 187 bool success = ParseNackItem(); 188 if (!success) Iterate(); 189 } 190 191 void RtcpParser::IterateRpsiItem() { 192 bool success = ParseRpsiItem(); 193 if (!success) Iterate(); 194 } 195 196 void RtcpParser::IterateFirItem() { 197 bool success = ParseFirItem(); 198 if (!success) Iterate(); 199 } 200 201 void RtcpParser::IteratePayloadSpecificAppItem() { 202 bool success = ParsePayloadSpecificAppItem(); 203 if (!success) Iterate(); 204 } 205 206 void RtcpParser::IteratePayloadSpecificRembItem() { 207 bool success = ParsePayloadSpecificRembItem(); 208 if (!success) Iterate(); 209 } 210 211 void RtcpParser::IteratePayloadSpecificCastItem() { 212 bool success = ParsePayloadSpecificCastItem(); 213 if (!success) Iterate(); 214 } 215 216 void RtcpParser::IteratePayloadSpecificCastNackItem() { 217 bool success = ParsePayloadSpecificCastNackItem(); 218 if (!success) Iterate(); 219 } 220 221 void RtcpParser::IterateCastReceiverLogFrame() { 222 bool success = ParseCastReceiverLogFrameItem(); 223 if (!success) Iterate(); 224 } 225 226 void RtcpParser::IterateCastReceiverLogEvent() { 227 bool success = ParseCastReceiverLogEventItem(); 228 if (!success) Iterate(); 229 } 230 231 void RtcpParser::IterateCastSenderLog() { 232 bool success = ParseCastSenderLogItem(); 233 if (!success) Iterate(); 234 } 235 236 void RtcpParser::Validate() { 237 if (rtcp_data_ == NULL) return; // NOT VALID 238 239 RtcpCommonHeader header; 240 bool success = RtcpParseCommonHeader(rtcp_data_begin_, rtcp_data_end_, 241 &header); 242 243 if (!success) return; // NOT VALID! 244 245 valid_packet_ = true; 246 } 247 248 bool RtcpParser::IsValid() const { 249 return valid_packet_; 250 } 251 252 void RtcpParser::EndCurrentBlock() { 253 rtcp_data_ = rtcp_block_end_; 254 } 255 256 bool RtcpParser::RtcpParseCommonHeader(const uint8* data_begin, 257 const uint8* data_end, 258 RtcpCommonHeader* parsed_header) const { 259 if (!data_begin || !data_end) return false; 260 261 // 0 1 2 3 262 // 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 263 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 264 // |V=2|P| IC | PT | length | 265 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 266 // 267 // Common header for all Rtcp packets, 4 octets. 268 269 if ((data_end - data_begin) < 4) return false; 270 271 parsed_header->V = data_begin[0] >> 6; 272 parsed_header->P = ((data_begin[0] & 0x20) == 0) ? false : true; 273 parsed_header->IC = data_begin[0] & 0x1f; 274 parsed_header->PT = data_begin[1]; 275 276 parsed_header->length_in_octets = 277 ((data_begin[2] << 8) + data_begin[3] + 1) * 4; 278 279 if (parsed_header->length_in_octets == 0) return false; 280 281 // Check if RTP version field == 2. 282 if (parsed_header->V != 2) return false; 283 284 return true; 285 } 286 287 bool RtcpParser::ParseRR() { 288 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 289 if (length < 8) return false; 290 291 field_type_ = kRtcpRrCode; 292 293 net::BigEndianReader big_endian_reader(rtcp_data_, length); 294 big_endian_reader.Skip(4); // Skip header 295 big_endian_reader.ReadU32(&field_.receiver_report.sender_ssrc); 296 field_.receiver_report.number_of_report_blocks = number_of_blocks_; 297 rtcp_data_ += 8; 298 299 // State transition 300 state_ = kStateReportBlock; 301 return true; 302 } 303 304 bool RtcpParser::ParseSR() { 305 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 306 if (length < 28) { 307 EndCurrentBlock(); 308 return false; 309 } 310 field_type_ = kRtcpSrCode; 311 312 net::BigEndianReader big_endian_reader(rtcp_data_, length); 313 big_endian_reader.Skip(4); // Skip header 314 big_endian_reader.ReadU32(&field_.sender_report.sender_ssrc); 315 big_endian_reader.ReadU32(&field_.sender_report.ntp_most_significant); 316 big_endian_reader.ReadU32(&field_.sender_report.ntp_least_significant); 317 big_endian_reader.ReadU32(&field_.sender_report.rtp_timestamp); 318 big_endian_reader.ReadU32(&field_.sender_report.sender_packet_count); 319 big_endian_reader.ReadU32(&field_.sender_report.sender_octet_count); 320 field_.sender_report.number_of_report_blocks = number_of_blocks_; 321 rtcp_data_ += 28; 322 323 if (number_of_blocks_ != 0) { 324 // State transition. 325 state_ = kStateReportBlock; 326 } else { 327 // Don't go to state report block item if 0 report blocks. 328 state_ = kStateTopLevel; 329 EndCurrentBlock(); 330 } 331 return true; 332 } 333 334 bool RtcpParser::ParseReportBlockItem() { 335 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 336 if (length < 24 || number_of_blocks_ <= 0) { 337 state_ = kStateTopLevel; 338 EndCurrentBlock(); 339 return false; 340 } 341 342 net::BigEndianReader big_endian_reader(rtcp_data_, length); 343 big_endian_reader.ReadU32(&field_.report_block_item.ssrc); 344 big_endian_reader.ReadU8(&field_.report_block_item.fraction_lost); 345 346 uint8 temp_number_of_packets_lost; 347 big_endian_reader.ReadU8(&temp_number_of_packets_lost); 348 field_.report_block_item.cumulative_number_of_packets_lost = 349 temp_number_of_packets_lost << 16; 350 big_endian_reader.ReadU8(&temp_number_of_packets_lost); 351 field_.report_block_item.cumulative_number_of_packets_lost += 352 temp_number_of_packets_lost << 8; 353 big_endian_reader.ReadU8(&temp_number_of_packets_lost); 354 field_.report_block_item.cumulative_number_of_packets_lost += 355 temp_number_of_packets_lost; 356 357 big_endian_reader.ReadU32( 358 &field_.report_block_item.extended_highest_sequence_number); 359 big_endian_reader.ReadU32(&field_.report_block_item.jitter); 360 big_endian_reader.ReadU32(&field_.report_block_item.last_sender_report); 361 big_endian_reader.ReadU32(&field_.report_block_item.delay_last_sender_report); 362 rtcp_data_ += 24; 363 364 number_of_blocks_--; 365 field_type_ = kRtcpReportBlockItemCode; 366 return true; 367 } 368 369 bool RtcpParser::ParseSdes() { 370 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 371 372 if (length < 8) { 373 state_ = kStateTopLevel; 374 EndCurrentBlock(); 375 return false; 376 } 377 rtcp_data_ += 4; // Skip header 378 379 state_ = kStateSdes; 380 field_type_ = kRtcpSdesCode; 381 return true; 382 } 383 384 bool RtcpParser::ParseSdesItem() { 385 if (number_of_blocks_ <= 0) { 386 state_ = kStateTopLevel; 387 EndCurrentBlock(); 388 return false; 389 } 390 number_of_blocks_--; 391 392 // Find c_name item in a Sdes chunk. 393 while (rtcp_data_ < rtcp_block_end_) { 394 ptrdiff_t data_length = rtcp_block_end_ - rtcp_data_; 395 if (data_length < 4) { 396 state_ = kStateTopLevel; 397 EndCurrentBlock(); 398 return false; 399 } 400 401 uint32 ssrc; 402 net::BigEndianReader big_endian_reader(rtcp_data_, data_length); 403 big_endian_reader.ReadU32(&ssrc); 404 rtcp_data_ += 4; 405 406 bool found_c_name = ParseSdesTypes(); 407 if (found_c_name) { 408 field_.c_name.sender_ssrc = ssrc; 409 return true; 410 } 411 } 412 state_ = kStateTopLevel; 413 EndCurrentBlock(); 414 return false; 415 } 416 417 bool RtcpParser::ParseSdesTypes() { 418 // Only the c_name item is mandatory. RFC 3550 page 46. 419 bool found_c_name = false; 420 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 421 net::BigEndianReader big_endian_reader(rtcp_data_, length); 422 423 while (big_endian_reader.remaining() > 0) { 424 uint8 tag; 425 big_endian_reader.ReadU8(&tag); 426 427 if (tag == 0) { 428 // End tag! 4 octet aligned. 429 rtcp_data_ = rtcp_block_end_; 430 return found_c_name; 431 } 432 433 if (big_endian_reader.remaining() > 0) { 434 uint8 len; 435 big_endian_reader.ReadU8(&len); 436 437 if (tag == 1) { // c_name. 438 // Sanity check. 439 if (big_endian_reader.remaining() < len) { 440 state_ = kStateTopLevel; 441 EndCurrentBlock(); 442 return false; 443 } 444 int i = 0; 445 for (; i < len; ++i) { 446 uint8 c; 447 big_endian_reader.ReadU8(&c); 448 if ((c < ' ') || (c > '{') || (c == '%') || (c == '\\')) { 449 // Illegal char. 450 state_ = kStateTopLevel; 451 EndCurrentBlock(); 452 return false; 453 } 454 field_.c_name.name[i] = c; 455 } 456 // Make sure we are null terminated. 457 field_.c_name.name[i] = 0; 458 field_type_ = kRtcpSdesChunkCode; 459 found_c_name = true; 460 } else { 461 big_endian_reader.Skip(len); 462 } 463 } 464 } 465 // No end tag found! 466 state_ = kStateTopLevel; 467 EndCurrentBlock(); 468 return false; 469 } 470 471 bool RtcpParser::ParseBye() { 472 rtcp_data_ += 4; // Skip header. 473 state_ = kStateBye; 474 return ParseByeItem(); 475 } 476 477 bool RtcpParser::ParseByeItem() { 478 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 479 if (length < 4 || number_of_blocks_ == 0) { 480 state_ = kStateTopLevel; 481 EndCurrentBlock(); 482 return false; 483 } 484 485 field_type_ = kRtcpByeCode; 486 487 net::BigEndianReader big_endian_reader(rtcp_data_, length); 488 big_endian_reader.ReadU32(&field_.bye.sender_ssrc); 489 rtcp_data_ += 4; 490 491 // We can have several CSRCs attached. 492 if (length >= 4 * number_of_blocks_) { 493 rtcp_data_ += (number_of_blocks_ - 1) * 4; 494 } 495 number_of_blocks_ = 0; 496 return true; 497 } 498 499 bool RtcpParser::ParseApplicationDefined(uint8 subtype) { 500 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 501 if (length < 16 || 502 !(subtype == kSenderLogSubtype || subtype == kReceiverLogSubtype)) { 503 state_ = kStateTopLevel; 504 EndCurrentBlock(); 505 return false; 506 } 507 508 uint32 sender_ssrc; 509 uint32 name; 510 511 net::BigEndianReader big_endian_reader(rtcp_data_, length); 512 big_endian_reader.Skip(4); // Skip header. 513 big_endian_reader.ReadU32(&sender_ssrc); 514 big_endian_reader.ReadU32(&name); 515 516 if (name != kCast) { 517 state_ = kStateTopLevel; 518 EndCurrentBlock(); 519 return false; 520 } 521 rtcp_data_ += 12; 522 switch (subtype) { 523 case kSenderLogSubtype: 524 state_ = kStateApplicationSpecificCastSenderLog; 525 field_type_ = kRtcpApplicationSpecificCastSenderLogCode; 526 field_.cast_sender_log.sender_ssrc = sender_ssrc; 527 break; 528 case kReceiverLogSubtype: 529 state_ = kStateApplicationSpecificCastReceiverFrameLog; 530 field_type_ = kRtcpApplicationSpecificCastReceiverLogCode; 531 field_.cast_receiver_log.sender_ssrc = sender_ssrc; 532 break; 533 default: 534 NOTREACHED(); 535 } 536 return true; 537 } 538 539 bool RtcpParser::ParseCastReceiverLogFrameItem() { 540 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 541 if (length < 12) { 542 state_ = kStateTopLevel; 543 EndCurrentBlock(); 544 return false; 545 } 546 uint32 rtp_timestamp; 547 uint32 data; 548 net::BigEndianReader big_endian_reader(rtcp_data_, length); 549 big_endian_reader.ReadU32(&rtp_timestamp); 550 big_endian_reader.ReadU32(&data); 551 552 rtcp_data_ += 8; 553 554 field_.cast_receiver_log.rtp_timestamp = rtp_timestamp; 555 // We have 24 LSB of the event timestamp base on the wire. 556 field_.cast_receiver_log.event_timestamp_base = data & 0xffffff; 557 558 number_of_blocks_ = 1 + static_cast<uint8>(data >> 24); 559 state_ = kStateApplicationSpecificCastReceiverEventLog; 560 field_type_ = kRtcpApplicationSpecificCastReceiverLogFrameCode; 561 return true; 562 } 563 564 bool RtcpParser::ParseCastReceiverLogEventItem() { 565 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 566 if (length < 4) { 567 state_ = kStateTopLevel; 568 EndCurrentBlock(); 569 return false; 570 } 571 if (number_of_blocks_ == 0) { 572 // Continue parsing the next receiver frame event. 573 state_ = kStateApplicationSpecificCastReceiverFrameLog; 574 return false; 575 } 576 number_of_blocks_--; 577 578 uint16 delay_delta_or_packet_id; 579 uint16 event_type_and_timestamp_delta; 580 net::BigEndianReader big_endian_reader(rtcp_data_, length); 581 big_endian_reader.ReadU16(&delay_delta_or_packet_id); 582 big_endian_reader.ReadU16(&event_type_and_timestamp_delta); 583 584 rtcp_data_ += 4; 585 586 field_.cast_receiver_log.event = 587 static_cast<uint8>(event_type_and_timestamp_delta >> 12); 588 field_.cast_receiver_log.delay_delta_or_packet_id = delay_delta_or_packet_id; 589 field_.cast_receiver_log.event_timestamp_delta = 590 event_type_and_timestamp_delta & 0xfff; 591 592 field_type_ = kRtcpApplicationSpecificCastReceiverLogEventCode; 593 return true; 594 } 595 596 bool RtcpParser::ParseCastSenderLogItem() { 597 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 598 599 if (length < 4) { 600 state_ = kStateTopLevel; 601 EndCurrentBlock(); 602 return false; 603 } 604 uint32 data; 605 net::BigEndianReader big_endian_reader(rtcp_data_, length); 606 big_endian_reader.ReadU32(&data); 607 608 rtcp_data_ += 4; 609 610 field_.cast_sender_log.status = static_cast<uint8>(data >> 24); 611 // We have 24 LSB of the RTP timestamp on the wire. 612 field_.cast_sender_log.rtp_timestamp = data & 0xffffff; 613 field_type_ = kRtcpApplicationSpecificCastSenderLogCode; 614 return true; 615 } 616 617 bool RtcpParser::ParseFeedBackCommon(const RtcpCommonHeader& header) { 618 DCHECK((header.PT == kPacketTypeGenericRtpFeedback) || 619 (header.PT == kPacketTypePayloadSpecific)) << "Invalid state"; 620 621 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 622 623 if (length < 12) { // 4 * 3, RFC4585 section 6.1 624 EndCurrentBlock(); 625 return false; 626 } 627 628 uint32 sender_ssrc; 629 uint32 media_ssrc; 630 net::BigEndianReader big_endian_reader(rtcp_data_, length); 631 big_endian_reader.Skip(4); // Skip header. 632 big_endian_reader.ReadU32(&sender_ssrc); 633 big_endian_reader.ReadU32(&media_ssrc); 634 635 rtcp_data_ += 12; 636 637 if (header.PT == kPacketTypeGenericRtpFeedback) { 638 // Transport layer feedback 639 switch (header.IC) { 640 case 1: 641 // Nack 642 field_type_ = kRtcpGenericRtpFeedbackNackCode; 643 field_.nack.sender_ssrc = sender_ssrc; 644 field_.nack.media_ssrc = media_ssrc; 645 state_ = kStateGenericRtpFeedbackNack; 646 return true; 647 case 2: 648 // Used to be ACK is this code point, which is removed conficts with 649 // http://tools.ietf.org/html/draft-levin-avt-rtcp-burst-00 650 break; 651 case 3: 652 // Tmmbr 653 break; 654 case 4: 655 // Tmmbn 656 break; 657 case 5: 658 // RFC 6051 RTCP-sender_report-REQ Rapid Synchronisation of RTP Flows 659 // Trigger a new Rtcp sender_report 660 field_type_ = kRtcpGenericRtpFeedbackSrReqCode; 661 662 // Note: No state transition, sender report REQ is empty! 663 return true; 664 default: 665 break; 666 } 667 EndCurrentBlock(); 668 return false; 669 670 } else if (header.PT == kPacketTypePayloadSpecific) { 671 // Payload specific feedback 672 switch (header.IC) { 673 case 1: 674 // PLI 675 field_type_ = kRtcpPayloadSpecificPliCode; 676 field_.pli.sender_ssrc = sender_ssrc; 677 field_.pli.media_ssrc = media_ssrc; 678 679 // Note: No state transition, PLI FCI is empty! 680 return true; 681 case 2: 682 // Sli 683 break; 684 case 3: 685 field_type_ = kRtcpPayloadSpecificRpsiCode; 686 field_.rpsi.sender_ssrc = sender_ssrc; 687 field_.rpsi.media_ssrc = media_ssrc; 688 state_ = kStatePayloadSpecificRpsi; 689 return true; 690 case 4: 691 // fir 692 break; 693 case 15: 694 field_type_ = kRtcpPayloadSpecificAppCode; 695 field_.application_specific.sender_ssrc = sender_ssrc; 696 field_.application_specific.media_ssrc = media_ssrc; 697 state_ = kStatePayloadSpecificApplication; 698 return true; 699 default: 700 break; 701 } 702 703 EndCurrentBlock(); 704 return false; 705 } else { 706 DCHECK(false) << "Invalid state"; 707 EndCurrentBlock(); 708 return false; 709 } 710 } 711 712 bool RtcpParser::ParseRpsiItem() { 713 // RFC 4585 6.3.3. Reference Picture Selection Indication (rpsi) 714 /* 715 0 1 2 3 716 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 717 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 718 | PB |0| Payload Type| Native rpsi bit string | 719 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 720 | defined per codec ... | Padding (0) | 721 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 722 */ 723 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 724 725 if (length < 4) { 726 state_ = kStateTopLevel; 727 EndCurrentBlock(); 728 return false; 729 } 730 if (length > 2 + kRtcpRpsiDataSize) { 731 state_ = kStateTopLevel; 732 EndCurrentBlock(); 733 return false; 734 } 735 736 field_type_ = kRtcpPayloadSpecificRpsiCode; 737 738 uint8 padding_bits; 739 net::BigEndianReader big_endian_reader(rtcp_data_, length); 740 big_endian_reader.ReadU8(&padding_bits); 741 big_endian_reader.ReadU8(&field_.rpsi.payload_type); 742 big_endian_reader.ReadBytes(&field_.rpsi.native_bit_string, length - 2); 743 field_.rpsi.number_of_valid_bits = 744 static_cast<uint16>(length - 2) * 8 - padding_bits; 745 746 rtcp_data_ += length; 747 return true; 748 } 749 750 bool RtcpParser::ParseNackItem() { 751 // RFC 4585 6.2.1. Generic Nack 752 753 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 754 if (length < 4) { 755 state_ = kStateTopLevel; 756 EndCurrentBlock(); 757 return false; 758 } 759 760 field_type_ = kRtcpGenericRtpFeedbackNackItemCode; 761 762 net::BigEndianReader big_endian_reader(rtcp_data_, length); 763 big_endian_reader.ReadU16(&field_.nack_item.packet_id); 764 big_endian_reader.ReadU16(&field_.nack_item.bitmask); 765 rtcp_data_ += 4; 766 return true; 767 } 768 769 bool RtcpParser::ParsePayloadSpecificAppItem() { 770 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 771 772 if (length < 4) { 773 state_ = kStateTopLevel; 774 EndCurrentBlock(); 775 return false; 776 } 777 uint32 name; 778 net::BigEndianReader big_endian_reader(rtcp_data_, length); 779 big_endian_reader.ReadU32(&name); 780 rtcp_data_ += 4; 781 782 if (name == kRemb) { 783 field_type_ = kRtcpPayloadSpecificRembCode; 784 state_ = kStatePayloadSpecificRemb; 785 return true; 786 } else if (name == kCast) { 787 field_type_ = kRtcpPayloadSpecificCastCode; 788 state_ = kStatePayloadSpecificCast; 789 return true; 790 } 791 state_ = kStateTopLevel; 792 EndCurrentBlock(); 793 return false; 794 } 795 796 bool RtcpParser::ParsePayloadSpecificRembItem() { 797 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 798 799 if (length < 4) { 800 state_ = kStateTopLevel; 801 EndCurrentBlock(); 802 return false; 803 } 804 805 net::BigEndianReader big_endian_reader(rtcp_data_, length); 806 big_endian_reader.ReadU8(&field_.remb_item.number_of_ssrcs); 807 808 uint8 byte_1; 809 uint8 byte_2; 810 uint8 byte_3; 811 big_endian_reader.ReadU8(&byte_1); 812 big_endian_reader.ReadU8(&byte_2); 813 big_endian_reader.ReadU8(&byte_3); 814 rtcp_data_ += 4; 815 816 uint8 br_exp = (byte_1 >> 2) & 0x3F; 817 uint32 br_mantissa = ((byte_1 & 0x03) << 16) + (byte_2 << 8) + byte_3; 818 field_.remb_item.bitrate = (br_mantissa << br_exp); 819 820 ptrdiff_t length_ssrcs = rtcp_block_end_ - rtcp_data_; 821 if (length_ssrcs < 4 * field_.remb_item.number_of_ssrcs) { 822 state_ = kStateTopLevel; 823 EndCurrentBlock(); 824 return false; 825 } 826 827 field_type_ = kRtcpPayloadSpecificRembItemCode; 828 829 for (int i = 0; i < field_.remb_item.number_of_ssrcs; i++) { 830 big_endian_reader.ReadU32(&field_.remb_item.ssrcs[i]); 831 } 832 return true; 833 } 834 835 bool RtcpParser::ParsePayloadSpecificCastItem() { 836 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 837 if (length < 4) { 838 state_ = kStateTopLevel; 839 EndCurrentBlock(); 840 return false; 841 } 842 field_type_ = kRtcpPayloadSpecificCastCode; 843 844 net::BigEndianReader big_endian_reader(rtcp_data_, length); 845 big_endian_reader.ReadU8(&field_.cast_item.last_frame_id); 846 big_endian_reader.ReadU8(&field_.cast_item.number_of_lost_fields); 847 848 rtcp_data_ += 4; 849 850 if (field_.cast_item.number_of_lost_fields != 0) { 851 // State transition 852 state_ = kStatePayloadSpecificCastNack; 853 } else { 854 // Don't go to state cast nack item if got 0 fields. 855 state_ = kStateTopLevel; 856 EndCurrentBlock(); 857 } 858 return true; 859 } 860 861 bool RtcpParser::ParsePayloadSpecificCastNackItem() { 862 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 863 if (length < 4) { 864 state_ = kStateTopLevel; 865 EndCurrentBlock(); 866 return false; 867 } 868 field_type_ = kRtcpPayloadSpecificCastNackItemCode; 869 870 net::BigEndianReader big_endian_reader(rtcp_data_, length); 871 big_endian_reader.ReadU8(&field_.cast_nack_item.frame_id); 872 big_endian_reader.ReadU16(&field_.cast_nack_item.packet_id); 873 big_endian_reader.ReadU8(&field_.cast_nack_item.bitmask); 874 875 rtcp_data_ += 4; 876 return true; 877 } 878 879 bool RtcpParser::ParseFirItem() { 880 // RFC 5104 4.3.1. Full Intra Request (fir) 881 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 882 883 if (length < 8) { 884 state_ = kStateTopLevel; 885 EndCurrentBlock(); 886 return false; 887 } 888 field_type_ = kRtcpPayloadSpecificFirItemCode; 889 890 net::BigEndianReader big_endian_reader(rtcp_data_, length); 891 big_endian_reader.ReadU32(&field_.fir_item.ssrc); 892 big_endian_reader.ReadU8(&field_.fir_item.command_sequence_number); 893 894 rtcp_data_ += 8; 895 return true; 896 } 897 898 bool RtcpParser::ParseExtendedReport() { 899 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 900 if (length < 8) return false; 901 902 field_type_ = kRtcpXrCode; 903 904 net::BigEndianReader big_endian_reader(rtcp_data_, length); 905 big_endian_reader.Skip(4); // Skip header. 906 big_endian_reader.ReadU32(&field_.extended_report.sender_ssrc); 907 908 rtcp_data_ += 8; 909 910 state_ = kStateExtendedReportBlock; 911 return true; 912 } 913 914 bool RtcpParser::ParseExtendedReportItem() { 915 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 916 if (length < 4) { 917 state_ = kStateTopLevel; 918 EndCurrentBlock(); 919 return false; 920 } 921 922 uint8 block_type; 923 uint16 block_length; 924 net::BigEndianReader big_endian_reader(rtcp_data_, length); 925 big_endian_reader.ReadU8(&block_type); 926 big_endian_reader.Skip(1); // Ignore reserved. 927 big_endian_reader.ReadU16(&block_length); 928 929 rtcp_data_ += 4; 930 931 switch (block_type) { 932 case 4: 933 if (block_length != 2) { 934 // Invalid block length. 935 state_ = kStateTopLevel; 936 EndCurrentBlock(); 937 return false; 938 } 939 return ParseExtendedReportReceiverReferenceTimeReport(); 940 case 5: 941 if (block_length % 3 != 0) { 942 // Invalid block length. 943 state_ = kStateTopLevel; 944 EndCurrentBlock(); 945 return false; 946 } 947 if (block_length >= 3) { 948 number_of_blocks_ = block_length / 3; 949 state_ = kStateExtendedReportDelaySinceLastReceiverReport; 950 return ParseExtendedReportDelaySinceLastReceiverReport(); 951 } 952 return true; 953 default: 954 if (length < block_length * 4) { 955 state_ = kStateTopLevel; 956 EndCurrentBlock(); 957 return false; 958 } 959 field_type_ = kRtcpXrUnknownItemCode; 960 rtcp_data_ += block_length * 4; 961 return true; 962 } 963 } 964 965 bool RtcpParser::ParseExtendedReportReceiverReferenceTimeReport() { 966 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 967 if (length < 8) { 968 state_ = kStateTopLevel; 969 EndCurrentBlock(); 970 return false; 971 } 972 973 net::BigEndianReader big_endian_reader(rtcp_data_, length); 974 big_endian_reader.ReadU32(&field_.rrtr.ntp_most_significant); 975 big_endian_reader.ReadU32(&field_.rrtr.ntp_least_significant); 976 977 rtcp_data_ += 8; 978 979 field_type_ = kRtcpXrRrtrCode; 980 return true; 981 } 982 983 bool RtcpParser::ParseExtendedReportDelaySinceLastReceiverReport() { 984 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; 985 if (length < 12) { 986 state_ = kStateTopLevel; 987 EndCurrentBlock(); 988 return false; 989 } 990 if (number_of_blocks_ == 0) { 991 // Continue parsing the extended report block. 992 state_ = kStateExtendedReportBlock; 993 return false; 994 } 995 996 net::BigEndianReader big_endian_reader(rtcp_data_, length); 997 big_endian_reader.ReadU32(&field_.dlrr.receivers_ssrc); 998 big_endian_reader.ReadU32(&field_.dlrr.last_receiver_report); 999 big_endian_reader.ReadU32(&field_.dlrr.delay_last_receiver_report); 1000 1001 rtcp_data_ += 12; 1002 1003 number_of_blocks_--; 1004 field_type_ = kRtcpXrDlrrCode; 1005 return true; 1006 } 1007 1008 } // namespace cast 1009 } // namespace media 1010