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