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 |