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 |