| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/rtcp/rtcp_utility.h" | 5 #include "media/cast/rtcp/rtcp_utility.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "media/cast/transport/cast_transport_defines.h" | |
| 9 #include "net/base/big_endian.h" | 8 #include "net/base/big_endian.h" |
| 10 | 9 |
| 11 namespace media { | 10 namespace media { |
| 12 namespace cast { | 11 namespace cast { |
| 13 | 12 |
| 14 RtcpParser::RtcpParser(const uint8* rtcpData, size_t rtcpDataLength) | 13 RtcpParser::RtcpParser(const uint8* rtcpData, size_t rtcpDataLength) |
| 15 : rtcp_data_begin_(rtcpData), | 14 : rtcp_data_begin_(rtcpData), |
| 16 rtcp_data_end_(rtcpData + rtcpDataLength), | 15 rtcp_data_end_(rtcpData + rtcpDataLength), |
| 17 valid_packet_(false), | 16 valid_packet_(false), |
| 18 rtcp_data_(rtcpData), | 17 rtcp_data_(rtcpData), |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 RtcpCommonHeader header; | 102 RtcpCommonHeader header; |
| 104 | 103 |
| 105 bool success = RtcpParseCommonHeader(rtcp_data_, rtcp_data_end_, &header); | 104 bool success = RtcpParseCommonHeader(rtcp_data_, rtcp_data_end_, &header); |
| 106 if (!success) return; | 105 if (!success) return; |
| 107 | 106 |
| 108 rtcp_block_end_ = rtcp_data_ + header.length_in_octets; | 107 rtcp_block_end_ = rtcp_data_ + header.length_in_octets; |
| 109 | 108 |
| 110 if (rtcp_block_end_ > rtcp_data_end_) return; // Bad block! | 109 if (rtcp_block_end_ > rtcp_data_end_) return; // Bad block! |
| 111 | 110 |
| 112 switch (header.PT) { | 111 switch (header.PT) { |
| 113 case transport::kPacketTypeSenderReport: | 112 case kPacketTypeSenderReport: |
| 114 // number of Report blocks | 113 // number of Report blocks |
| 115 number_of_blocks_ = header.IC; | 114 number_of_blocks_ = header.IC; |
| 116 ParseSR(); | 115 ParseSR(); |
| 117 return; | 116 return; |
| 118 case transport::kPacketTypeReceiverReport: | 117 case kPacketTypeReceiverReport: |
| 119 // number of Report blocks | 118 // number of Report blocks |
| 120 number_of_blocks_ = header.IC; | 119 number_of_blocks_ = header.IC; |
| 121 ParseRR(); | 120 ParseRR(); |
| 122 return; | 121 return; |
| 123 case transport::kPacketTypeSdes: | 122 case kPacketTypeSdes: |
| 124 // number of Sdes blocks | 123 // number of Sdes blocks |
| 125 number_of_blocks_ = header.IC; | 124 number_of_blocks_ = header.IC; |
| 126 if (!ParseSdes()) { | 125 if (!ParseSdes()) { |
| 127 break; // Nothing supported found, continue to next block! | 126 break; // Nothing supported found, continue to next block! |
| 128 } | 127 } |
| 129 return; | 128 return; |
| 130 case transport::kPacketTypeBye: | 129 case kPacketTypeBye: |
| 131 number_of_blocks_ = header.IC; | 130 number_of_blocks_ = header.IC; |
| 132 if (!ParseBye()) { | 131 if (!ParseBye()) { |
| 133 // Nothing supported found, continue to next block! | 132 // Nothing supported found, continue to next block! |
| 134 break; | 133 break; |
| 135 } | 134 } |
| 136 return; | 135 return; |
| 137 case transport::kPacketTypeApplicationDefined: | 136 case kPacketTypeApplicationDefined: |
| 138 if (!ParseApplicationDefined(header.IC)) { | 137 if (!ParseApplicationDefined(header.IC)) { |
| 139 // Nothing supported found, continue to next block! | 138 // Nothing supported found, continue to next block! |
| 140 break; | 139 break; |
| 141 } | 140 } |
| 142 return; | 141 return; |
| 143 case transport::kPacketTypeGenericRtpFeedback: // Fall through! | 142 case kPacketTypeGenericRtpFeedback: // Fall through! |
| 144 case transport::kPacketTypePayloadSpecific: | 143 case kPacketTypePayloadSpecific: |
| 145 if (!ParseFeedBackCommon(header)) { | 144 if (!ParseFeedBackCommon(header)) { |
| 146 // Nothing supported found, continue to next block! | 145 // Nothing supported found, continue to next block! |
| 147 break; | 146 break; |
| 148 } | 147 } |
| 149 return; | 148 return; |
| 150 case transport::kPacketTypeXr: | 149 case kPacketTypeXr: |
| 151 if (!ParseExtendedReport()) { | 150 if (!ParseExtendedReport()) { |
| 152 break; // Nothing supported found, continue to next block! | 151 break; // Nothing supported found, continue to next block! |
| 153 } | 152 } |
| 154 return; | 153 return; |
| 155 default: | 154 default: |
| 156 // Not supported! Skip! | 155 // Not supported! Skip! |
| 157 EndCurrentBlock(); | 156 EndCurrentBlock(); |
| 158 break; | 157 break; |
| 159 } | 158 } |
| 160 } | 159 } |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 rtcp_data_ += 4; | 609 rtcp_data_ += 4; |
| 611 | 610 |
| 612 field_.cast_sender_log.status = static_cast<uint8>(data >> 24); | 611 field_.cast_sender_log.status = static_cast<uint8>(data >> 24); |
| 613 // We have 24 LSB of the RTP timestamp on the wire. | 612 // We have 24 LSB of the RTP timestamp on the wire. |
| 614 field_.cast_sender_log.rtp_timestamp = data & 0xffffff; | 613 field_.cast_sender_log.rtp_timestamp = data & 0xffffff; |
| 615 field_type_ = kRtcpApplicationSpecificCastSenderLogCode; | 614 field_type_ = kRtcpApplicationSpecificCastSenderLogCode; |
| 616 return true; | 615 return true; |
| 617 } | 616 } |
| 618 | 617 |
| 619 bool RtcpParser::ParseFeedBackCommon(const RtcpCommonHeader& header) { | 618 bool RtcpParser::ParseFeedBackCommon(const RtcpCommonHeader& header) { |
| 620 DCHECK((header.PT == transport::kPacketTypeGenericRtpFeedback) || | 619 DCHECK((header.PT == kPacketTypeGenericRtpFeedback) || |
| 621 (header.PT == transport::kPacketTypePayloadSpecific)) << | 620 (header.PT == kPacketTypePayloadSpecific)) << "Invalid state"; |
| 622 "Invalid state"; | |
| 623 | 621 |
| 624 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | 622 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; |
| 625 | 623 |
| 626 if (length < 12) { // 4 * 3, RFC4585 section 6.1 | 624 if (length < 12) { // 4 * 3, RFC4585 section 6.1 |
| 627 EndCurrentBlock(); | 625 EndCurrentBlock(); |
| 628 return false; | 626 return false; |
| 629 } | 627 } |
| 630 | 628 |
| 631 uint32 sender_ssrc; | 629 uint32 sender_ssrc; |
| 632 uint32 media_ssrc; | 630 uint32 media_ssrc; |
| 633 net::BigEndianReader big_endian_reader(rtcp_data_, length); | 631 net::BigEndianReader big_endian_reader(rtcp_data_, length); |
| 634 big_endian_reader.Skip(4); // Skip header. | 632 big_endian_reader.Skip(4); // Skip header. |
| 635 big_endian_reader.ReadU32(&sender_ssrc); | 633 big_endian_reader.ReadU32(&sender_ssrc); |
| 636 big_endian_reader.ReadU32(&media_ssrc); | 634 big_endian_reader.ReadU32(&media_ssrc); |
| 637 | 635 |
| 638 rtcp_data_ += 12; | 636 rtcp_data_ += 12; |
| 639 | 637 |
| 640 if (header.PT == transport::kPacketTypeGenericRtpFeedback) { | 638 if (header.PT == kPacketTypeGenericRtpFeedback) { |
| 641 // Transport layer feedback | 639 // Transport layer feedback |
| 642 switch (header.IC) { | 640 switch (header.IC) { |
| 643 case 1: | 641 case 1: |
| 644 // Nack | 642 // Nack |
| 645 field_type_ = kRtcpGenericRtpFeedbackNackCode; | 643 field_type_ = kRtcpGenericRtpFeedbackNackCode; |
| 646 field_.nack.sender_ssrc = sender_ssrc; | 644 field_.nack.sender_ssrc = sender_ssrc; |
| 647 field_.nack.media_ssrc = media_ssrc; | 645 field_.nack.media_ssrc = media_ssrc; |
| 648 state_ = kStateGenericRtpFeedbackNack; | 646 state_ = kStateGenericRtpFeedbackNack; |
| 649 return true; | 647 return true; |
| 650 case 2: | 648 case 2: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 663 field_type_ = kRtcpGenericRtpFeedbackSrReqCode; | 661 field_type_ = kRtcpGenericRtpFeedbackSrReqCode; |
| 664 | 662 |
| 665 // Note: No state transition, sender report REQ is empty! | 663 // Note: No state transition, sender report REQ is empty! |
| 666 return true; | 664 return true; |
| 667 default: | 665 default: |
| 668 break; | 666 break; |
| 669 } | 667 } |
| 670 EndCurrentBlock(); | 668 EndCurrentBlock(); |
| 671 return false; | 669 return false; |
| 672 | 670 |
| 673 } else if (header.PT == transport::kPacketTypePayloadSpecific) { | 671 } else if (header.PT == kPacketTypePayloadSpecific) { |
| 674 // Payload specific feedback | 672 // Payload specific feedback |
| 675 switch (header.IC) { | 673 switch (header.IC) { |
| 676 case 1: | 674 case 1: |
| 677 // PLI | 675 // PLI |
| 678 field_type_ = kRtcpPayloadSpecificPliCode; | 676 field_type_ = kRtcpPayloadSpecificPliCode; |
| 679 field_.pli.sender_ssrc = sender_ssrc; | 677 field_.pli.sender_ssrc = sender_ssrc; |
| 680 field_.pli.media_ssrc = media_ssrc; | 678 field_.pli.media_ssrc = media_ssrc; |
| 681 | 679 |
| 682 // Note: No state transition, PLI FCI is empty! | 680 // Note: No state transition, PLI FCI is empty! |
| 683 return true; | 681 return true; |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 | 1001 |
| 1004 rtcp_data_ += 12; | 1002 rtcp_data_ += 12; |
| 1005 | 1003 |
| 1006 number_of_blocks_--; | 1004 number_of_blocks_--; |
| 1007 field_type_ = kRtcpXrDlrrCode; | 1005 field_type_ = kRtcpXrDlrrCode; |
| 1008 return true; | 1006 return true; |
| 1009 } | 1007 } |
| 1010 | 1008 |
| 1011 } // namespace cast | 1009 } // namespace cast |
| 1012 } // namespace media | 1010 } // namespace media |
| OLD | NEW |