| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/cast/net/rtcp/rtcp_utility.h" | 5 #include "media/cast/net/rtcp/rtcp_utility.h" |
| 6 | 6 |
| 7 #include "base/big_endian.h" | 7 #include "base/big_endian.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "media/cast/net/cast_transport_defines.h" | 9 #include "media/cast/net/cast_transport_defines.h" |
| 10 | 10 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 if (!IsValid()) | 42 if (!IsValid()) |
| 43 return kRtcpNotValidCode; | 43 return kRtcpNotValidCode; |
| 44 | 44 |
| 45 switch (state_) { | 45 switch (state_) { |
| 46 case kStateTopLevel: | 46 case kStateTopLevel: |
| 47 IterateTopLevel(); | 47 IterateTopLevel(); |
| 48 break; | 48 break; |
| 49 case kStateReportBlock: | 49 case kStateReportBlock: |
| 50 IterateReportBlockItem(); | 50 IterateReportBlockItem(); |
| 51 break; | 51 break; |
| 52 case kStateSdes: | |
| 53 IterateSdesItem(); | |
| 54 break; | |
| 55 case kStateBye: | |
| 56 IterateByeItem(); | |
| 57 break; | |
| 58 case kStateApplicationSpecificCastReceiverFrameLog: | 52 case kStateApplicationSpecificCastReceiverFrameLog: |
| 59 IterateCastReceiverLogFrame(); | 53 IterateCastReceiverLogFrame(); |
| 60 break; | 54 break; |
| 61 case kStateApplicationSpecificCastReceiverEventLog: | 55 case kStateApplicationSpecificCastReceiverEventLog: |
| 62 IterateCastReceiverLogEvent(); | 56 IterateCastReceiverLogEvent(); |
| 63 break; | 57 break; |
| 64 case kStateExtendedReportBlock: | 58 case kStateExtendedReportBlock: |
| 65 IterateExtendedReportItem(); | 59 IterateExtendedReportItem(); |
| 66 break; | 60 break; |
| 67 case kStateExtendedReportDelaySinceLastReceiverReport: | 61 case kStateExtendedReportDelaySinceLastReceiverReport: |
| 68 IterateExtendedReportDelaySinceLastReceiverReportItem(); | 62 IterateExtendedReportDelaySinceLastReceiverReportItem(); |
| 69 break; | 63 break; |
| 70 case kStateGenericRtpFeedbackNack: | |
| 71 IterateNackItem(); | |
| 72 break; | |
| 73 case kStatePayloadSpecificRpsi: | |
| 74 IterateRpsiItem(); | |
| 75 break; | |
| 76 case kStatePayloadSpecificFir: | |
| 77 IterateFirItem(); | |
| 78 break; | |
| 79 case kStatePayloadSpecificApplication: | 64 case kStatePayloadSpecificApplication: |
| 80 IteratePayloadSpecificAppItem(); | 65 IteratePayloadSpecificAppItem(); |
| 81 break; | 66 break; |
| 82 case kStatePayloadSpecificRemb: | |
| 83 IteratePayloadSpecificRembItem(); | |
| 84 break; | |
| 85 case kStatePayloadSpecificCast: | 67 case kStatePayloadSpecificCast: |
| 86 IteratePayloadSpecificCastItem(); | 68 IteratePayloadSpecificCastItem(); |
| 87 break; | 69 break; |
| 88 case kStatePayloadSpecificCastNack: | 70 case kStatePayloadSpecificCastNack: |
| 89 IteratePayloadSpecificCastNackItem(); | 71 IteratePayloadSpecificCastNackItem(); |
| 90 break; | 72 break; |
| 91 } | 73 } |
| 92 return field_type_; | 74 return field_type_; |
| 93 } | 75 } |
| 94 | 76 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 109 case kPacketTypeSenderReport: | 91 case kPacketTypeSenderReport: |
| 110 // number of Report blocks | 92 // number of Report blocks |
| 111 number_of_blocks_ = header.IC; | 93 number_of_blocks_ = header.IC; |
| 112 ParseSR(); | 94 ParseSR(); |
| 113 return; | 95 return; |
| 114 case kPacketTypeReceiverReport: | 96 case kPacketTypeReceiverReport: |
| 115 // number of Report blocks | 97 // number of Report blocks |
| 116 number_of_blocks_ = header.IC; | 98 number_of_blocks_ = header.IC; |
| 117 ParseRR(); | 99 ParseRR(); |
| 118 return; | 100 return; |
| 119 case kPacketTypeSdes: | |
| 120 // number of Sdes blocks | |
| 121 number_of_blocks_ = header.IC; | |
| 122 if (!ParseSdes()) { | |
| 123 break; // Nothing supported found, continue to next block! | |
| 124 } | |
| 125 return; | |
| 126 case kPacketTypeBye: | |
| 127 number_of_blocks_ = header.IC; | |
| 128 if (!ParseBye()) { | |
| 129 // Nothing supported found, continue to next block! | |
| 130 break; | |
| 131 } | |
| 132 return; | |
| 133 case kPacketTypeApplicationDefined: | 101 case kPacketTypeApplicationDefined: |
| 134 if (!ParseApplicationDefined(header.IC)) { | 102 if (!ParseApplicationDefined(header.IC)) { |
| 135 // Nothing supported found, continue to next block! | 103 // Nothing supported found, continue to next block! |
| 136 break; | 104 break; |
| 137 } | 105 } |
| 138 return; | 106 return; |
| 139 case kPacketTypeGenericRtpFeedback: // Fall through! | 107 case kPacketTypeGenericRtpFeedback: // Fall through! |
| 140 case kPacketTypePayloadSpecific: | 108 case kPacketTypePayloadSpecific: |
| 141 if (!ParseFeedBackCommon(header)) { | 109 if (!ParseFeedBackCommon(header)) { |
| 142 // Nothing supported found, continue to next block! | 110 // Nothing supported found, continue to next block! |
| (...skipping 12 matching lines...) Expand all Loading... |
| 155 } | 123 } |
| 156 } | 124 } |
| 157 } | 125 } |
| 158 | 126 |
| 159 void RtcpParser::IterateReportBlockItem() { | 127 void RtcpParser::IterateReportBlockItem() { |
| 160 bool success = ParseReportBlockItem(); | 128 bool success = ParseReportBlockItem(); |
| 161 if (!success) | 129 if (!success) |
| 162 Iterate(); | 130 Iterate(); |
| 163 } | 131 } |
| 164 | 132 |
| 165 void RtcpParser::IterateSdesItem() { | |
| 166 bool success = ParseSdesItem(); | |
| 167 if (!success) | |
| 168 Iterate(); | |
| 169 } | |
| 170 | |
| 171 void RtcpParser::IterateByeItem() { | |
| 172 bool success = ParseByeItem(); | |
| 173 if (!success) | |
| 174 Iterate(); | |
| 175 } | |
| 176 | |
| 177 void RtcpParser::IterateExtendedReportItem() { | 133 void RtcpParser::IterateExtendedReportItem() { |
| 178 bool success = ParseExtendedReportItem(); | 134 bool success = ParseExtendedReportItem(); |
| 179 if (!success) | 135 if (!success) |
| 180 Iterate(); | 136 Iterate(); |
| 181 } | 137 } |
| 182 | 138 |
| 183 void RtcpParser::IterateExtendedReportDelaySinceLastReceiverReportItem() { | 139 void RtcpParser::IterateExtendedReportDelaySinceLastReceiverReportItem() { |
| 184 bool success = ParseExtendedReportDelaySinceLastReceiverReport(); | 140 bool success = ParseExtendedReportDelaySinceLastReceiverReport(); |
| 185 if (!success) | 141 if (!success) |
| 186 Iterate(); | 142 Iterate(); |
| 187 } | 143 } |
| 188 | 144 |
| 189 void RtcpParser::IterateNackItem() { | |
| 190 bool success = ParseNackItem(); | |
| 191 if (!success) | |
| 192 Iterate(); | |
| 193 } | |
| 194 | |
| 195 void RtcpParser::IterateRpsiItem() { | |
| 196 bool success = ParseRpsiItem(); | |
| 197 if (!success) | |
| 198 Iterate(); | |
| 199 } | |
| 200 | |
| 201 void RtcpParser::IterateFirItem() { | |
| 202 bool success = ParseFirItem(); | |
| 203 if (!success) | |
| 204 Iterate(); | |
| 205 } | |
| 206 | |
| 207 void RtcpParser::IteratePayloadSpecificAppItem() { | 145 void RtcpParser::IteratePayloadSpecificAppItem() { |
| 208 bool success = ParsePayloadSpecificAppItem(); | 146 bool success = ParsePayloadSpecificAppItem(); |
| 209 if (!success) | 147 if (!success) |
| 210 Iterate(); | 148 Iterate(); |
| 211 } | 149 } |
| 212 | 150 |
| 213 void RtcpParser::IteratePayloadSpecificRembItem() { | |
| 214 bool success = ParsePayloadSpecificRembItem(); | |
| 215 if (!success) | |
| 216 Iterate(); | |
| 217 } | |
| 218 | |
| 219 void RtcpParser::IteratePayloadSpecificCastItem() { | 151 void RtcpParser::IteratePayloadSpecificCastItem() { |
| 220 bool success = ParsePayloadSpecificCastItem(); | 152 bool success = ParsePayloadSpecificCastItem(); |
| 221 if (!success) | 153 if (!success) |
| 222 Iterate(); | 154 Iterate(); |
| 223 } | 155 } |
| 224 | 156 |
| 225 void RtcpParser::IteratePayloadSpecificCastNackItem() { | 157 void RtcpParser::IteratePayloadSpecificCastNackItem() { |
| 226 bool success = ParsePayloadSpecificCastNackItem(); | 158 bool success = ParsePayloadSpecificCastNackItem(); |
| 227 if (!success) | 159 if (!success) |
| 228 Iterate(); | 160 Iterate(); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 big_endian_reader.ReadU32(&field_.report_block_item.jitter); | 304 big_endian_reader.ReadU32(&field_.report_block_item.jitter); |
| 373 big_endian_reader.ReadU32(&field_.report_block_item.last_sender_report); | 305 big_endian_reader.ReadU32(&field_.report_block_item.last_sender_report); |
| 374 big_endian_reader.ReadU32(&field_.report_block_item.delay_last_sender_report); | 306 big_endian_reader.ReadU32(&field_.report_block_item.delay_last_sender_report); |
| 375 rtcp_data_ += 24; | 307 rtcp_data_ += 24; |
| 376 | 308 |
| 377 number_of_blocks_--; | 309 number_of_blocks_--; |
| 378 field_type_ = kRtcpReportBlockItemCode; | 310 field_type_ = kRtcpReportBlockItemCode; |
| 379 return true; | 311 return true; |
| 380 } | 312 } |
| 381 | 313 |
| 382 bool RtcpParser::ParseSdes() { | |
| 383 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | |
| 384 | |
| 385 if (length < 8) { | |
| 386 state_ = kStateTopLevel; | |
| 387 EndCurrentBlock(); | |
| 388 return false; | |
| 389 } | |
| 390 rtcp_data_ += 4; // Skip header | |
| 391 | |
| 392 state_ = kStateSdes; | |
| 393 field_type_ = kRtcpSdesCode; | |
| 394 return true; | |
| 395 } | |
| 396 | |
| 397 bool RtcpParser::ParseSdesItem() { | |
| 398 if (number_of_blocks_ <= 0) { | |
| 399 state_ = kStateTopLevel; | |
| 400 EndCurrentBlock(); | |
| 401 return false; | |
| 402 } | |
| 403 number_of_blocks_--; | |
| 404 | |
| 405 // Find c_name item in a Sdes chunk. | |
| 406 while (rtcp_data_ < rtcp_block_end_) { | |
| 407 ptrdiff_t data_length = rtcp_block_end_ - rtcp_data_; | |
| 408 if (data_length < 4) { | |
| 409 state_ = kStateTopLevel; | |
| 410 EndCurrentBlock(); | |
| 411 return false; | |
| 412 } | |
| 413 | |
| 414 uint32 ssrc; | |
| 415 base::BigEndianReader big_endian_reader( | |
| 416 reinterpret_cast<const char*>(rtcp_data_), data_length); | |
| 417 big_endian_reader.ReadU32(&ssrc); | |
| 418 rtcp_data_ += 4; | |
| 419 | |
| 420 bool found_c_name = ParseSdesTypes(); | |
| 421 if (found_c_name) { | |
| 422 field_.c_name.sender_ssrc = ssrc; | |
| 423 return true; | |
| 424 } | |
| 425 } | |
| 426 state_ = kStateTopLevel; | |
| 427 EndCurrentBlock(); | |
| 428 return false; | |
| 429 } | |
| 430 | |
| 431 bool RtcpParser::ParseSdesTypes() { | |
| 432 // Only the c_name item is mandatory. RFC 3550 page 46. | |
| 433 bool found_c_name = false; | |
| 434 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | |
| 435 base::BigEndianReader big_endian_reader( | |
| 436 reinterpret_cast<const char*>(rtcp_data_), length); | |
| 437 | |
| 438 while (big_endian_reader.remaining() > 0) { | |
| 439 uint8 tag; | |
| 440 big_endian_reader.ReadU8(&tag); | |
| 441 | |
| 442 if (tag == 0) { | |
| 443 // End tag! 4 octet aligned. | |
| 444 rtcp_data_ = rtcp_block_end_; | |
| 445 return found_c_name; | |
| 446 } | |
| 447 | |
| 448 if (big_endian_reader.remaining() > 0) { | |
| 449 uint8 len; | |
| 450 big_endian_reader.ReadU8(&len); | |
| 451 | |
| 452 if (tag == 1) { // c_name. | |
| 453 // Sanity check. | |
| 454 if (big_endian_reader.remaining() < len) { | |
| 455 state_ = kStateTopLevel; | |
| 456 EndCurrentBlock(); | |
| 457 return false; | |
| 458 } | |
| 459 int i = 0; | |
| 460 for (; i < len; ++i) { | |
| 461 uint8 c; | |
| 462 big_endian_reader.ReadU8(&c); | |
| 463 if ((c < ' ') || (c > '{') || (c == '%') || (c == '\\')) { | |
| 464 // Illegal char. | |
| 465 state_ = kStateTopLevel; | |
| 466 EndCurrentBlock(); | |
| 467 return false; | |
| 468 } | |
| 469 field_.c_name.name[i] = c; | |
| 470 } | |
| 471 // Make sure we are null terminated. | |
| 472 field_.c_name.name[i] = 0; | |
| 473 field_type_ = kRtcpSdesChunkCode; | |
| 474 found_c_name = true; | |
| 475 } else { | |
| 476 big_endian_reader.Skip(len); | |
| 477 } | |
| 478 } | |
| 479 } | |
| 480 // No end tag found! | |
| 481 state_ = kStateTopLevel; | |
| 482 EndCurrentBlock(); | |
| 483 return false; | |
| 484 } | |
| 485 | |
| 486 bool RtcpParser::ParseBye() { | |
| 487 rtcp_data_ += 4; // Skip header. | |
| 488 state_ = kStateBye; | |
| 489 return ParseByeItem(); | |
| 490 } | |
| 491 | |
| 492 bool RtcpParser::ParseByeItem() { | |
| 493 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | |
| 494 if (length < 4 || number_of_blocks_ == 0) { | |
| 495 state_ = kStateTopLevel; | |
| 496 EndCurrentBlock(); | |
| 497 return false; | |
| 498 } | |
| 499 | |
| 500 field_type_ = kRtcpByeCode; | |
| 501 | |
| 502 base::BigEndianReader big_endian_reader( | |
| 503 reinterpret_cast<const char*>(rtcp_data_), length); | |
| 504 big_endian_reader.ReadU32(&field_.bye.sender_ssrc); | |
| 505 rtcp_data_ += 4; | |
| 506 | |
| 507 // We can have several CSRCs attached. | |
| 508 if (length >= 4 * number_of_blocks_) { | |
| 509 rtcp_data_ += (number_of_blocks_ - 1) * 4; | |
| 510 } | |
| 511 number_of_blocks_ = 0; | |
| 512 return true; | |
| 513 } | |
| 514 | |
| 515 bool RtcpParser::ParseApplicationDefined(uint8 subtype) { | 314 bool RtcpParser::ParseApplicationDefined(uint8 subtype) { |
| 516 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | 315 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; |
| 517 if (length < 16 || subtype != kReceiverLogSubtype) { | 316 if (length < 16 || subtype != kReceiverLogSubtype) { |
| 518 state_ = kStateTopLevel; | 317 state_ = kStateTopLevel; |
| 519 EndCurrentBlock(); | 318 EndCurrentBlock(); |
| 520 return false; | 319 return false; |
| 521 } | 320 } |
| 522 | 321 |
| 523 uint32 sender_ssrc; | 322 uint32 sender_ssrc; |
| 524 uint32 name; | 323 uint32 name; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 uint32 sender_ssrc; | 422 uint32 sender_ssrc; |
| 624 uint32 media_ssrc; | 423 uint32 media_ssrc; |
| 625 base::BigEndianReader big_endian_reader( | 424 base::BigEndianReader big_endian_reader( |
| 626 reinterpret_cast<const char*>(rtcp_data_), length); | 425 reinterpret_cast<const char*>(rtcp_data_), length); |
| 627 big_endian_reader.Skip(4); // Skip header. | 426 big_endian_reader.Skip(4); // Skip header. |
| 628 big_endian_reader.ReadU32(&sender_ssrc); | 427 big_endian_reader.ReadU32(&sender_ssrc); |
| 629 big_endian_reader.ReadU32(&media_ssrc); | 428 big_endian_reader.ReadU32(&media_ssrc); |
| 630 | 429 |
| 631 rtcp_data_ += 12; | 430 rtcp_data_ += 12; |
| 632 | 431 |
| 633 if (header.PT == kPacketTypeGenericRtpFeedback) { | 432 if (header.PT == kPacketTypePayloadSpecific) { |
| 634 // Transport layer feedback | |
| 635 switch (header.IC) { | |
| 636 case 1: | |
| 637 // Nack | |
| 638 field_type_ = kRtcpGenericRtpFeedbackNackCode; | |
| 639 field_.nack.sender_ssrc = sender_ssrc; | |
| 640 field_.nack.media_ssrc = media_ssrc; | |
| 641 state_ = kStateGenericRtpFeedbackNack; | |
| 642 return true; | |
| 643 case 2: | |
| 644 // Used to be ACK is this code point, which is removed conficts with | |
| 645 // http://tools.ietf.org/html/draft-levin-avt-rtcp-burst-00 | |
| 646 break; | |
| 647 case 3: | |
| 648 // Tmmbr | |
| 649 break; | |
| 650 case 4: | |
| 651 // Tmmbn | |
| 652 break; | |
| 653 case 5: | |
| 654 // RFC 6051 RTCP-sender_report-REQ Rapid Synchronisation of RTP Flows | |
| 655 // Trigger a new Rtcp sender_report | |
| 656 field_type_ = kRtcpGenericRtpFeedbackSrReqCode; | |
| 657 | |
| 658 // Note: No state transition, sender report REQ is empty! | |
| 659 return true; | |
| 660 default: | |
| 661 break; | |
| 662 } | |
| 663 EndCurrentBlock(); | |
| 664 return false; | |
| 665 | |
| 666 } else if (header.PT == kPacketTypePayloadSpecific) { | |
| 667 // Payload specific feedback | 433 // Payload specific feedback |
| 668 switch (header.IC) { | 434 switch (header.IC) { |
| 669 case 1: | 435 case 1: |
| 670 // PLI | 436 // PLI |
| 671 field_type_ = kRtcpPayloadSpecificPliCode; | 437 break; |
| 672 field_.pli.sender_ssrc = sender_ssrc; | |
| 673 field_.pli.media_ssrc = media_ssrc; | |
| 674 | |
| 675 // Note: No state transition, PLI FCI is empty! | |
| 676 return true; | |
| 677 case 2: | 438 case 2: |
| 678 // Sli | 439 // SLI. |
| 679 break; | 440 break; |
| 680 case 3: | 441 case 3: |
| 681 field_type_ = kRtcpPayloadSpecificRpsiCode; | 442 // RPSI. |
| 682 field_.rpsi.sender_ssrc = sender_ssrc; | 443 break; |
| 683 field_.rpsi.media_ssrc = media_ssrc; | |
| 684 state_ = kStatePayloadSpecificRpsi; | |
| 685 return true; | |
| 686 case 4: | 444 case 4: |
| 687 // fir | 445 // FIR. |
| 688 break; | 446 break; |
| 689 case 15: | 447 case 15: |
| 690 field_type_ = kRtcpPayloadSpecificAppCode; | 448 field_type_ = kRtcpPayloadSpecificAppCode; |
| 691 field_.application_specific.sender_ssrc = sender_ssrc; | 449 field_.application_specific.sender_ssrc = sender_ssrc; |
| 692 field_.application_specific.media_ssrc = media_ssrc; | 450 field_.application_specific.media_ssrc = media_ssrc; |
| 693 state_ = kStatePayloadSpecificApplication; | 451 state_ = kStatePayloadSpecificApplication; |
| 694 return true; | 452 return true; |
| 695 default: | 453 default: |
| 696 break; | 454 break; |
| 697 } | 455 } |
| 698 | 456 |
| 699 EndCurrentBlock(); | 457 EndCurrentBlock(); |
| 700 return false; | 458 return false; |
| 701 } else { | 459 } else { |
| 702 DCHECK(false) << "Invalid state"; | 460 DCHECK(false) << "Invalid state"; |
| 703 EndCurrentBlock(); | 461 EndCurrentBlock(); |
| 704 return false; | 462 return false; |
| 705 } | 463 } |
| 706 } | 464 } |
| 707 | 465 |
| 708 bool RtcpParser::ParseRpsiItem() { | |
| 709 // RFC 4585 6.3.3. Reference Picture Selection Indication (rpsi) | |
| 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 | PB |0| Payload Type| Native rpsi bit string | | |
| 715 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 716 | defined per codec ... | Padding (0) | | |
| 717 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 718 */ | |
| 719 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | |
| 720 | |
| 721 if (length < 4) { | |
| 722 state_ = kStateTopLevel; | |
| 723 EndCurrentBlock(); | |
| 724 return false; | |
| 725 } | |
| 726 if (length > 2 + kRtcpRpsiDataSize) { | |
| 727 state_ = kStateTopLevel; | |
| 728 EndCurrentBlock(); | |
| 729 return false; | |
| 730 } | |
| 731 | |
| 732 field_type_ = kRtcpPayloadSpecificRpsiCode; | |
| 733 | |
| 734 uint8 padding_bits; | |
| 735 base::BigEndianReader big_endian_reader( | |
| 736 reinterpret_cast<const char*>(rtcp_data_), length); | |
| 737 big_endian_reader.ReadU8(&padding_bits); | |
| 738 big_endian_reader.ReadU8(&field_.rpsi.payload_type); | |
| 739 big_endian_reader.ReadBytes(&field_.rpsi.native_bit_string, length - 2); | |
| 740 field_.rpsi.number_of_valid_bits = | |
| 741 static_cast<uint16>(length - 2) * 8 - padding_bits; | |
| 742 | |
| 743 rtcp_data_ += length; | |
| 744 return true; | |
| 745 } | |
| 746 | |
| 747 bool RtcpParser::ParseNackItem() { | |
| 748 // RFC 4585 6.2.1. Generic Nack | |
| 749 | |
| 750 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | |
| 751 if (length < 4) { | |
| 752 state_ = kStateTopLevel; | |
| 753 EndCurrentBlock(); | |
| 754 return false; | |
| 755 } | |
| 756 | |
| 757 field_type_ = kRtcpGenericRtpFeedbackNackItemCode; | |
| 758 | |
| 759 base::BigEndianReader big_endian_reader( | |
| 760 reinterpret_cast<const char*>(rtcp_data_), length); | |
| 761 big_endian_reader.ReadU16(&field_.nack_item.packet_id); | |
| 762 big_endian_reader.ReadU16(&field_.nack_item.bitmask); | |
| 763 rtcp_data_ += 4; | |
| 764 return true; | |
| 765 } | |
| 766 | |
| 767 bool RtcpParser::ParsePayloadSpecificAppItem() { | 466 bool RtcpParser::ParsePayloadSpecificAppItem() { |
| 768 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | 467 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; |
| 769 | 468 |
| 770 if (length < 4) { | 469 if (length < 4) { |
| 771 state_ = kStateTopLevel; | 470 state_ = kStateTopLevel; |
| 772 EndCurrentBlock(); | 471 EndCurrentBlock(); |
| 773 return false; | 472 return false; |
| 774 } | 473 } |
| 775 uint32 name; | 474 uint32 name; |
| 776 base::BigEndianReader big_endian_reader( | 475 base::BigEndianReader big_endian_reader( |
| 777 reinterpret_cast<const char*>(rtcp_data_), length); | 476 reinterpret_cast<const char*>(rtcp_data_), length); |
| 778 big_endian_reader.ReadU32(&name); | 477 big_endian_reader.ReadU32(&name); |
| 779 rtcp_data_ += 4; | 478 rtcp_data_ += 4; |
| 780 | 479 |
| 781 if (name == kRemb) { | 480 if (name == kCast) { |
| 782 field_type_ = kRtcpPayloadSpecificRembCode; | |
| 783 state_ = kStatePayloadSpecificRemb; | |
| 784 return true; | |
| 785 } else if (name == kCast) { | |
| 786 field_type_ = kRtcpPayloadSpecificCastCode; | 481 field_type_ = kRtcpPayloadSpecificCastCode; |
| 787 state_ = kStatePayloadSpecificCast; | 482 state_ = kStatePayloadSpecificCast; |
| 788 return true; | 483 return true; |
| 789 } | 484 } |
| 790 state_ = kStateTopLevel; | 485 state_ = kStateTopLevel; |
| 791 EndCurrentBlock(); | 486 EndCurrentBlock(); |
| 792 return false; | 487 return false; |
| 793 } | 488 } |
| 794 | 489 |
| 795 bool RtcpParser::ParsePayloadSpecificRembItem() { | |
| 796 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | |
| 797 | |
| 798 if (length < 4) { | |
| 799 state_ = kStateTopLevel; | |
| 800 EndCurrentBlock(); | |
| 801 return false; | |
| 802 } | |
| 803 | |
| 804 base::BigEndianReader big_endian_reader( | |
| 805 reinterpret_cast<const char*>(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() { | 490 bool RtcpParser::ParsePayloadSpecificCastItem() { |
| 836 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | 491 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; |
| 837 if (length < 4) { | 492 if (length < 4) { |
| 838 state_ = kStateTopLevel; | 493 state_ = kStateTopLevel; |
| 839 EndCurrentBlock(); | 494 EndCurrentBlock(); |
| 840 return false; | 495 return false; |
| 841 } | 496 } |
| 842 field_type_ = kRtcpPayloadSpecificCastCode; | 497 field_type_ = kRtcpPayloadSpecificCastCode; |
| 843 | 498 |
| 844 base::BigEndianReader big_endian_reader( | 499 base::BigEndianReader big_endian_reader( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 872 base::BigEndianReader big_endian_reader( | 527 base::BigEndianReader big_endian_reader( |
| 873 reinterpret_cast<const char*>(rtcp_data_), length); | 528 reinterpret_cast<const char*>(rtcp_data_), length); |
| 874 big_endian_reader.ReadU8(&field_.cast_nack_item.frame_id); | 529 big_endian_reader.ReadU8(&field_.cast_nack_item.frame_id); |
| 875 big_endian_reader.ReadU16(&field_.cast_nack_item.packet_id); | 530 big_endian_reader.ReadU16(&field_.cast_nack_item.packet_id); |
| 876 big_endian_reader.ReadU8(&field_.cast_nack_item.bitmask); | 531 big_endian_reader.ReadU8(&field_.cast_nack_item.bitmask); |
| 877 | 532 |
| 878 rtcp_data_ += 4; | 533 rtcp_data_ += 4; |
| 879 return true; | 534 return true; |
| 880 } | 535 } |
| 881 | 536 |
| 882 bool RtcpParser::ParseFirItem() { | |
| 883 // RFC 5104 4.3.1. Full Intra Request (fir) | |
| 884 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | |
| 885 | |
| 886 if (length < 8) { | |
| 887 state_ = kStateTopLevel; | |
| 888 EndCurrentBlock(); | |
| 889 return false; | |
| 890 } | |
| 891 field_type_ = kRtcpPayloadSpecificFirItemCode; | |
| 892 | |
| 893 base::BigEndianReader big_endian_reader( | |
| 894 reinterpret_cast<const char*>(rtcp_data_), length); | |
| 895 big_endian_reader.ReadU32(&field_.fir_item.ssrc); | |
| 896 big_endian_reader.ReadU8(&field_.fir_item.command_sequence_number); | |
| 897 | |
| 898 rtcp_data_ += 8; | |
| 899 return true; | |
| 900 } | |
| 901 | |
| 902 bool RtcpParser::ParseExtendedReport() { | 537 bool RtcpParser::ParseExtendedReport() { |
| 903 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | 538 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; |
| 904 if (length < 8) | 539 if (length < 8) |
| 905 return false; | 540 return false; |
| 906 | 541 |
| 907 field_type_ = kRtcpXrCode; | 542 field_type_ = kRtcpXrCode; |
| 908 | 543 |
| 909 base::BigEndianReader big_endian_reader( | 544 base::BigEndianReader big_endian_reader( |
| 910 reinterpret_cast<const char*>(rtcp_data_), length); | 545 reinterpret_cast<const char*>(rtcp_data_), length); |
| 911 big_endian_reader.Skip(4); // Skip header. | 546 big_endian_reader.Skip(4); // Skip header. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 929 uint16 block_length; | 564 uint16 block_length; |
| 930 base::BigEndianReader big_endian_reader( | 565 base::BigEndianReader big_endian_reader( |
| 931 reinterpret_cast<const char*>(rtcp_data_), length); | 566 reinterpret_cast<const char*>(rtcp_data_), length); |
| 932 big_endian_reader.ReadU8(&block_type); | 567 big_endian_reader.ReadU8(&block_type); |
| 933 big_endian_reader.Skip(1); // Ignore reserved. | 568 big_endian_reader.Skip(1); // Ignore reserved. |
| 934 big_endian_reader.ReadU16(&block_length); | 569 big_endian_reader.ReadU16(&block_length); |
| 935 | 570 |
| 936 rtcp_data_ += 4; | 571 rtcp_data_ += 4; |
| 937 | 572 |
| 938 switch (block_type) { | 573 switch (block_type) { |
| 939 case 4: | 574 case 4: // RRTR. RFC3611 Section 4.4. |
| 940 if (block_length != 2) { | 575 if (block_length != 2) { |
| 941 // Invalid block length. | 576 // Invalid block length. |
| 942 state_ = kStateTopLevel; | 577 state_ = kStateTopLevel; |
| 943 EndCurrentBlock(); | 578 EndCurrentBlock(); |
| 944 return false; | 579 return false; |
| 945 } | 580 } |
| 946 return ParseExtendedReportReceiverReferenceTimeReport(); | 581 return ParseExtendedReportReceiverReferenceTimeReport(); |
| 947 case 5: | 582 case 5: // DLRR. RFC3611 Section 4.5. |
| 948 if (block_length % 3 != 0) { | 583 if (block_length % 3 != 0) { |
| 949 // Invalid block length. | 584 // Invalid block length. |
| 950 state_ = kStateTopLevel; | 585 state_ = kStateTopLevel; |
| 951 EndCurrentBlock(); | 586 EndCurrentBlock(); |
| 952 return false; | 587 return false; |
| 953 } | 588 } |
| 954 if (block_length >= 3) { | 589 if (block_length >= 3) { |
| 955 number_of_blocks_ = block_length / 3; | 590 number_of_blocks_ = block_length / 3; |
| 956 state_ = kStateExtendedReportDelaySinceLastReceiverReport; | 591 state_ = kStateExtendedReportDelaySinceLastReceiverReport; |
| 957 return ParseExtendedReportDelaySinceLastReceiverReport(); | 592 return ParseExtendedReportDelaySinceLastReceiverReport(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 // If the sender adds new log messages we will end up here until we add | 692 // If the sender adds new log messages we will end up here until we add |
| 1058 // the new messages in the receiver. | 693 // the new messages in the receiver. |
| 1059 VLOG(1) << "Unexpected log message received: " << static_cast<int>(event); | 694 VLOG(1) << "Unexpected log message received: " << static_cast<int>(event); |
| 1060 NOTREACHED(); | 695 NOTREACHED(); |
| 1061 return UNKNOWN; | 696 return UNKNOWN; |
| 1062 } | 697 } |
| 1063 } | 698 } |
| 1064 | 699 |
| 1065 } // namespace cast | 700 } // namespace cast |
| 1066 } // namespace media | 701 } // namespace media |
| OLD | NEW |