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 "net/base/big_endian.h" | 8 #include "net/base/big_endian.h" |
9 | 9 |
10 namespace media { | 10 namespace media { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 break; | 49 break; |
50 case kStateReportBlock: | 50 case kStateReportBlock: |
51 IterateReportBlockItem(); | 51 IterateReportBlockItem(); |
52 break; | 52 break; |
53 case kStateSdes: | 53 case kStateSdes: |
54 IterateSdesItem(); | 54 IterateSdesItem(); |
55 break; | 55 break; |
56 case kStateBye: | 56 case kStateBye: |
57 IterateByeItem(); | 57 IterateByeItem(); |
58 break; | 58 break; |
| 59 case kStateApplicationSpecificCastReceiverFrameLog: |
| 60 IterateCastReceiverLogFrame(); |
| 61 break; |
| 62 case kStateApplicationSpecificCastReceiverEventLog: |
| 63 IterateCastReceiverLogEvent(); |
| 64 break; |
| 65 case kStateApplicationSpecificCastSenderLog: |
| 66 IterateCastSenderLog(); |
| 67 break; |
59 case kStateExtendedReportBlock: | 68 case kStateExtendedReportBlock: |
60 IterateExtendedReportItem(); | 69 IterateExtendedReportItem(); |
61 break; | 70 break; |
62 case kStateExtendedReportDelaySinceLastReceiverReport: | 71 case kStateExtendedReportDelaySinceLastReceiverReport: |
63 IterateExtendedReportDelaySinceLastReceiverReportItem(); | 72 IterateExtendedReportDelaySinceLastReceiverReportItem(); |
64 break; | 73 break; |
65 case kStateGenericRtpFeedbackNack: | 74 case kStateGenericRtpFeedbackNack: |
66 IterateNackItem(); | 75 IterateNackItem(); |
67 break; | 76 break; |
68 case kStatePayloadSpecificRpsi: | 77 case kStatePayloadSpecificRpsi: |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 break; // Nothing supported found, continue to next block! | 125 break; // Nothing supported found, continue to next block! |
117 } | 126 } |
118 return; | 127 return; |
119 case kPacketTypeBye: | 128 case kPacketTypeBye: |
120 number_of_blocks_ = header.IC; | 129 number_of_blocks_ = header.IC; |
121 if (!ParseBye()) { | 130 if (!ParseBye()) { |
122 // Nothing supported found, continue to next block! | 131 // Nothing supported found, continue to next block! |
123 break; | 132 break; |
124 } | 133 } |
125 return; | 134 return; |
| 135 case kPacketTypeApplicationDefined: |
| 136 if (!ParseApplicationDefined(header.IC)) { |
| 137 // Nothing supported found, continue to next block! |
| 138 break; |
| 139 } |
| 140 return; |
126 case kPacketTypeGenericRtpFeedback: // Fall through! | 141 case kPacketTypeGenericRtpFeedback: // Fall through! |
127 case kPacketTypePayloadSpecific: | 142 case kPacketTypePayloadSpecific: |
128 if (!ParseFeedBackCommon(header)) { | 143 if (!ParseFeedBackCommon(header)) { |
129 // Nothing supported found, continue to next block! | 144 // Nothing supported found, continue to next block! |
130 break; | 145 break; |
131 } | 146 } |
132 return; | 147 return; |
133 case kPacketTypeXr: | 148 case kPacketTypeXr: |
134 if (!ParseExtendedReport()) { | 149 if (!ParseExtendedReport()) { |
135 break; // Nothing supported found, continue to next block! | 150 break; // Nothing supported found, continue to next block! |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 void RtcpParser::IteratePayloadSpecificCastItem() { | 211 void RtcpParser::IteratePayloadSpecificCastItem() { |
197 bool success = ParsePayloadSpecificCastItem(); | 212 bool success = ParsePayloadSpecificCastItem(); |
198 if (!success) Iterate(); | 213 if (!success) Iterate(); |
199 } | 214 } |
200 | 215 |
201 void RtcpParser::IteratePayloadSpecificCastNackItem() { | 216 void RtcpParser::IteratePayloadSpecificCastNackItem() { |
202 bool success = ParsePayloadSpecificCastNackItem(); | 217 bool success = ParsePayloadSpecificCastNackItem(); |
203 if (!success) Iterate(); | 218 if (!success) Iterate(); |
204 } | 219 } |
205 | 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 |
206 void RtcpParser::Validate() { | 236 void RtcpParser::Validate() { |
207 if (rtcp_data_ == NULL) return; // NOT VALID | 237 if (rtcp_data_ == NULL) return; // NOT VALID |
208 | 238 |
209 RtcpCommonHeader header; | 239 RtcpCommonHeader header; |
210 bool success = RtcpParseCommonHeader(rtcp_data_begin_, rtcp_data_end_, | 240 bool success = RtcpParseCommonHeader(rtcp_data_begin_, rtcp_data_end_, |
211 &header); | 241 &header); |
212 | 242 |
213 if (!success) return; // NOT VALID! | 243 if (!success) return; // NOT VALID! |
214 | 244 |
215 valid_packet_ = true; | 245 valid_packet_ = true; |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 rtcp_data_ += 4; | 489 rtcp_data_ += 4; |
460 | 490 |
461 // We can have several CSRCs attached. | 491 // We can have several CSRCs attached. |
462 if (length >= 4 * number_of_blocks_) { | 492 if (length >= 4 * number_of_blocks_) { |
463 rtcp_data_ += (number_of_blocks_ - 1) * 4; | 493 rtcp_data_ += (number_of_blocks_ - 1) * 4; |
464 } | 494 } |
465 number_of_blocks_ = 0; | 495 number_of_blocks_ = 0; |
466 return true; | 496 return true; |
467 } | 497 } |
468 | 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 |
469 bool RtcpParser::ParseFeedBackCommon(const RtcpCommonHeader& header) { | 617 bool RtcpParser::ParseFeedBackCommon(const RtcpCommonHeader& header) { |
470 DCHECK((header.PT == kPacketTypeGenericRtpFeedback) || | 618 DCHECK((header.PT == kPacketTypeGenericRtpFeedback) || |
471 (header.PT == kPacketTypePayloadSpecific)) << "Invalid state"; | 619 (header.PT == kPacketTypePayloadSpecific)) << "Invalid state"; |
472 | 620 |
473 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | 621 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; |
474 | 622 |
475 if (length < 12) { // 4 * 3, RFC4585 section 6.1 | 623 if (length < 12) { // 4 * 3, RFC4585 section 6.1 |
476 EndCurrentBlock(); | 624 EndCurrentBlock(); |
477 return false; | 625 return false; |
478 } | 626 } |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 field_type_ = kRtcpPayloadSpecificRembItemCode; | 827 field_type_ = kRtcpPayloadSpecificRembItemCode; |
680 | 828 |
681 for (int i = 0; i < field_.remb_item.number_of_ssrcs; i++) { | 829 for (int i = 0; i < field_.remb_item.number_of_ssrcs; i++) { |
682 big_endian_reader.ReadU32(&field_.remb_item.ssrcs[i]); | 830 big_endian_reader.ReadU32(&field_.remb_item.ssrcs[i]); |
683 } | 831 } |
684 return true; | 832 return true; |
685 } | 833 } |
686 | 834 |
687 bool RtcpParser::ParsePayloadSpecificCastItem() { | 835 bool RtcpParser::ParsePayloadSpecificCastItem() { |
688 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; | 836 ptrdiff_t length = rtcp_block_end_ - rtcp_data_; |
689 | |
690 if (length < 4) { | 837 if (length < 4) { |
691 state_ = kStateTopLevel; | 838 state_ = kStateTopLevel; |
692 EndCurrentBlock(); | 839 EndCurrentBlock(); |
693 return false; | 840 return false; |
694 } | 841 } |
695 field_type_ = kRtcpPayloadSpecificCastCode; | 842 field_type_ = kRtcpPayloadSpecificCastCode; |
696 | 843 |
697 net::BigEndianReader big_endian_reader(rtcp_data_, length); | 844 net::BigEndianReader big_endian_reader(rtcp_data_, length); |
698 big_endian_reader.ReadU8(&field_.cast_item.last_frame_id); | 845 big_endian_reader.ReadU8(&field_.cast_item.last_frame_id); |
699 big_endian_reader.ReadU8(&field_.cast_item.number_of_lost_fields); | 846 big_endian_reader.ReadU8(&field_.cast_item.number_of_lost_fields); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 | 1000 |
854 rtcp_data_ += 12; | 1001 rtcp_data_ += 12; |
855 | 1002 |
856 number_of_blocks_--; | 1003 number_of_blocks_--; |
857 field_type_ = kRtcpXrDlrrCode; | 1004 field_type_ = kRtcpXrDlrrCode; |
858 return true; | 1005 return true; |
859 } | 1006 } |
860 | 1007 |
861 } // namespace cast | 1008 } // namespace cast |
862 } // namespace media | 1009 } // namespace media |
OLD | NEW |