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
3 // found in the LICENSE file.
4
5 #include "media/cast/rtcp/rtcp_utility.h"
6
7 #include "base/big_endian.h"
8 #include "base/logging.h"
9 #include "media/cast/transport/cast_transport_defines.h"
10
11 namespace media {
12 namespace cast {
13
RtcpParser(const uint8 * rtcpData,size_t rtcpDataLength)14 RtcpParser::RtcpParser(const uint8* rtcpData, size_t rtcpDataLength)
15 : rtcp_data_begin_(rtcpData),
16 rtcp_data_end_(rtcpData + rtcpDataLength),
17 valid_packet_(false),
18 rtcp_data_(rtcpData),
19 rtcp_block_end_(NULL),
20 state_(kStateTopLevel),
21 number_of_blocks_(0),
22 field_type_(kRtcpNotValidCode) {
23 memset(&field_, 0, sizeof(field_));
24 Validate();
25 }
26
~RtcpParser()27 RtcpParser::~RtcpParser() {}
28
FieldType() const29 RtcpFieldTypes RtcpParser::FieldType() const { return field_type_; }
30
Field() const31 const RtcpField& RtcpParser::Field() const { return field_; }
32
Begin()33 RtcpFieldTypes RtcpParser::Begin() {
34 rtcp_data_ = rtcp_data_begin_;
35 return Iterate();
36 }
37
Iterate()38 RtcpFieldTypes RtcpParser::Iterate() {
39 // Reset packet type
40 field_type_ = kRtcpNotValidCode;
41
42 if (!IsValid())
43 return kRtcpNotValidCode;
44
45 switch (state_) {
46 case kStateTopLevel:
47 IterateTopLevel();
48 break;
49 case kStateReportBlock:
50 IterateReportBlockItem();
51 break;
52 case kStateSdes:
53 IterateSdesItem();
54 break;
55 case kStateBye:
56 IterateByeItem();
57 break;
58 case kStateApplicationSpecificCastReceiverFrameLog:
59 IterateCastReceiverLogFrame();
60 break;
61 case kStateApplicationSpecificCastReceiverEventLog:
62 IterateCastReceiverLogEvent();
63 break;
64 case kStateExtendedReportBlock:
65 IterateExtendedReportItem();
66 break;
67 case kStateExtendedReportDelaySinceLastReceiverReport:
68 IterateExtendedReportDelaySinceLastReceiverReportItem();
69 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:
80 IteratePayloadSpecificAppItem();
81 break;
82 case kStatePayloadSpecificRemb:
83 IteratePayloadSpecificRembItem();
84 break;
85 case kStatePayloadSpecificCast:
86 IteratePayloadSpecificCastItem();
87 break;
88 case kStatePayloadSpecificCastNack:
89 IteratePayloadSpecificCastNackItem();
90 break;
91 }
92 return field_type_;
93 }
94
IterateTopLevel()95 void RtcpParser::IterateTopLevel() {
96 for (;;) {
97 RtcpCommonHeader header;
98
99 bool success = RtcpParseCommonHeader(rtcp_data_, rtcp_data_end_, &header);
100 if (!success)
101 return;
102
103 rtcp_block_end_ = rtcp_data_ + header.length_in_octets;
104
105 if (rtcp_block_end_ > rtcp_data_end_)
106 return; // Bad block!
107
108 switch (header.PT) {
109 case transport::kPacketTypeSenderReport:
110 // number of Report blocks
111 number_of_blocks_ = header.IC;
112 ParseSR();
113 return;
114 case transport::kPacketTypeReceiverReport:
115 // number of Report blocks
116 number_of_blocks_ = header.IC;
117 ParseRR();
118 return;
119 case transport::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 transport::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 transport::kPacketTypeApplicationDefined:
134 if (!ParseApplicationDefined(header.IC)) {
135 // Nothing supported found, continue to next block!
136 break;
137 }
138 return;
139 case transport::kPacketTypeGenericRtpFeedback: // Fall through!
140 case transport::kPacketTypePayloadSpecific:
141 if (!ParseFeedBackCommon(header)) {
142 // Nothing supported found, continue to next block!
143 break;
144 }
145 return;
146 case transport::kPacketTypeXr:
147 if (!ParseExtendedReport()) {
148 break; // Nothing supported found, continue to next block!
149 }
150 return;
151 default:
152 // Not supported! Skip!
153 EndCurrentBlock();
154 break;
155 }
156 }
157 }
158
IterateReportBlockItem()159 void RtcpParser::IterateReportBlockItem() {
160 bool success = ParseReportBlockItem();
161 if (!success)
162 Iterate();
163 }
164
IterateSdesItem()165 void RtcpParser::IterateSdesItem() {
166 bool success = ParseSdesItem();
167 if (!success)
168 Iterate();
169 }
170
IterateByeItem()171 void RtcpParser::IterateByeItem() {
172 bool success = ParseByeItem();
173 if (!success)
174 Iterate();
175 }
176
IterateExtendedReportItem()177 void RtcpParser::IterateExtendedReportItem() {
178 bool success = ParseExtendedReportItem();
179 if (!success)
180 Iterate();
181 }
182
IterateExtendedReportDelaySinceLastReceiverReportItem()183 void RtcpParser::IterateExtendedReportDelaySinceLastReceiverReportItem() {
184 bool success = ParseExtendedReportDelaySinceLastReceiverReport();
185 if (!success)
186 Iterate();
187 }
188
IterateNackItem()189 void RtcpParser::IterateNackItem() {
190 bool success = ParseNackItem();
191 if (!success)
192 Iterate();
193 }
194
IterateRpsiItem()195 void RtcpParser::IterateRpsiItem() {
196 bool success = ParseRpsiItem();
197 if (!success)
198 Iterate();
199 }
200
IterateFirItem()201 void RtcpParser::IterateFirItem() {
202 bool success = ParseFirItem();
203 if (!success)
204 Iterate();
205 }
206
IteratePayloadSpecificAppItem()207 void RtcpParser::IteratePayloadSpecificAppItem() {
208 bool success = ParsePayloadSpecificAppItem();
209 if (!success)
210 Iterate();
211 }
212
IteratePayloadSpecificRembItem()213 void RtcpParser::IteratePayloadSpecificRembItem() {
214 bool success = ParsePayloadSpecificRembItem();
215 if (!success)
216 Iterate();
217 }
218
IteratePayloadSpecificCastItem()219 void RtcpParser::IteratePayloadSpecificCastItem() {
220 bool success = ParsePayloadSpecificCastItem();
221 if (!success)
222 Iterate();
223 }
224
IteratePayloadSpecificCastNackItem()225 void RtcpParser::IteratePayloadSpecificCastNackItem() {
226 bool success = ParsePayloadSpecificCastNackItem();
227 if (!success)
228 Iterate();
229 }
230
IterateCastReceiverLogFrame()231 void RtcpParser::IterateCastReceiverLogFrame() {
232 bool success = ParseCastReceiverLogFrameItem();
233 if (!success)
234 Iterate();
235 }
236
IterateCastReceiverLogEvent()237 void RtcpParser::IterateCastReceiverLogEvent() {
238 bool success = ParseCastReceiverLogEventItem();
239 if (!success)
240 Iterate();
241 }
242
Validate()243 void RtcpParser::Validate() {
244 if (rtcp_data_ == NULL)
245 return; // NOT VALID
246
247 RtcpCommonHeader header;
248 bool success =
249 RtcpParseCommonHeader(rtcp_data_begin_, rtcp_data_end_, &header);
250
251 if (!success)
252 return; // NOT VALID!
253
254 valid_packet_ = true;
255 }
256
IsValid() const257 bool RtcpParser::IsValid() const { return valid_packet_; }
258
EndCurrentBlock()259 void RtcpParser::EndCurrentBlock() { rtcp_data_ = rtcp_block_end_; }
260
RtcpParseCommonHeader(const uint8 * data_begin,const uint8 * data_end,RtcpCommonHeader * parsed_header) const261 bool RtcpParser::RtcpParseCommonHeader(const uint8* data_begin,
262 const uint8* data_end,
263 RtcpCommonHeader* parsed_header) const {
264 if (!data_begin || !data_end)
265 return false;
266
267 // 0 1 2 3
268 // 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
269 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
270 // |V=2|P| IC | PT | length |
271 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
272 //
273 // Common header for all Rtcp packets, 4 octets.
274
275 if ((data_end - data_begin) < 4)
276 return false;
277
278 parsed_header->V = data_begin[0] >> 6;
279 parsed_header->P = ((data_begin[0] & 0x20) == 0) ? false : true;
280 parsed_header->IC = data_begin[0] & 0x1f;
281 parsed_header->PT = data_begin[1];
282
283 parsed_header->length_in_octets =
284 ((data_begin[2] << 8) + data_begin[3] + 1) * 4;
285
286 if (parsed_header->length_in_octets == 0)
287 return false;
288
289 // Check if RTP version field == 2.
290 if (parsed_header->V != 2)
291 return false;
292
293 return true;
294 }
295
ParseRR()296 bool RtcpParser::ParseRR() {
297 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
298 if (length < 8)
299 return false;
300
301 field_type_ = kRtcpRrCode;
302
303 base::BigEndianReader big_endian_reader(
304 reinterpret_cast<const char*>(rtcp_data_), length);
305 big_endian_reader.Skip(4); // Skip header
306 big_endian_reader.ReadU32(&field_.receiver_report.sender_ssrc);
307 field_.receiver_report.number_of_report_blocks = number_of_blocks_;
308 rtcp_data_ += 8;
309
310 // State transition
311 state_ = kStateReportBlock;
312 return true;
313 }
314
ParseSR()315 bool RtcpParser::ParseSR() {
316 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
317 if (length < 28) {
318 EndCurrentBlock();
319 return false;
320 }
321 field_type_ = kRtcpSrCode;
322
323 base::BigEndianReader big_endian_reader(
324 reinterpret_cast<const char*>(rtcp_data_), length);
325 big_endian_reader.Skip(4); // Skip header
326 big_endian_reader.ReadU32(&field_.sender_report.sender_ssrc);
327 big_endian_reader.ReadU32(&field_.sender_report.ntp_most_significant);
328 big_endian_reader.ReadU32(&field_.sender_report.ntp_least_significant);
329 big_endian_reader.ReadU32(&field_.sender_report.rtp_timestamp);
330 big_endian_reader.ReadU32(&field_.sender_report.sender_packet_count);
331 big_endian_reader.ReadU32(&field_.sender_report.sender_octet_count);
332 field_.sender_report.number_of_report_blocks = number_of_blocks_;
333 rtcp_data_ += 28;
334
335 if (number_of_blocks_ != 0) {
336 // State transition.
337 state_ = kStateReportBlock;
338 } else {
339 // Don't go to state report block item if 0 report blocks.
340 state_ = kStateTopLevel;
341 EndCurrentBlock();
342 }
343 return true;
344 }
345
ParseReportBlockItem()346 bool RtcpParser::ParseReportBlockItem() {
347 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
348 if (length < 24 || number_of_blocks_ <= 0) {
349 state_ = kStateTopLevel;
350 EndCurrentBlock();
351 return false;
352 }
353
354 base::BigEndianReader big_endian_reader(
355 reinterpret_cast<const char*>(rtcp_data_), length);
356 big_endian_reader.ReadU32(&field_.report_block_item.ssrc);
357 big_endian_reader.ReadU8(&field_.report_block_item.fraction_lost);
358
359 uint8 temp_number_of_packets_lost;
360 big_endian_reader.ReadU8(&temp_number_of_packets_lost);
361 field_.report_block_item.cumulative_number_of_packets_lost =
362 temp_number_of_packets_lost << 16;
363 big_endian_reader.ReadU8(&temp_number_of_packets_lost);
364 field_.report_block_item.cumulative_number_of_packets_lost +=
365 temp_number_of_packets_lost << 8;
366 big_endian_reader.ReadU8(&temp_number_of_packets_lost);
367 field_.report_block_item.cumulative_number_of_packets_lost +=
368 temp_number_of_packets_lost;
369
370 big_endian_reader.ReadU32(
371 &field_.report_block_item.extended_highest_sequence_number);
372 big_endian_reader.ReadU32(&field_.report_block_item.jitter);
373 big_endian_reader.ReadU32(&field_.report_block_item.last_sender_report);
374 big_endian_reader.ReadU32(&field_.report_block_item.delay_last_sender_report);
375 rtcp_data_ += 24;
376
377 number_of_blocks_--;
378 field_type_ = kRtcpReportBlockItemCode;
379 return true;
380 }
381
ParseSdes()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
ParseSdesItem()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
ParseSdesTypes()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
ParseBye()486 bool RtcpParser::ParseBye() {
487 rtcp_data_ += 4; // Skip header.
488 state_ = kStateBye;
489 return ParseByeItem();
490 }
491
ParseByeItem()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
ParseApplicationDefined(uint8 subtype)515 bool RtcpParser::ParseApplicationDefined(uint8 subtype) {
516 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
517 if (length < 16 || subtype != kReceiverLogSubtype) {
518 state_ = kStateTopLevel;
519 EndCurrentBlock();
520 return false;
521 }
522
523 uint32 sender_ssrc;
524 uint32 name;
525
526 base::BigEndianReader big_endian_reader(
527 reinterpret_cast<const char*>(rtcp_data_), length);
528 big_endian_reader.Skip(4); // Skip header.
529 big_endian_reader.ReadU32(&sender_ssrc);
530 big_endian_reader.ReadU32(&name);
531
532 if (name != kCast) {
533 state_ = kStateTopLevel;
534 EndCurrentBlock();
535 return false;
536 }
537 rtcp_data_ += 12;
538 switch (subtype) {
539 case kReceiverLogSubtype:
540 state_ = kStateApplicationSpecificCastReceiverFrameLog;
541 field_type_ = kRtcpApplicationSpecificCastReceiverLogCode;
542 field_.cast_receiver_log.sender_ssrc = sender_ssrc;
543 break;
544 default:
545 NOTREACHED();
546 }
547 return true;
548 }
549
ParseCastReceiverLogFrameItem()550 bool RtcpParser::ParseCastReceiverLogFrameItem() {
551 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
552 if (length < 12) {
553 state_ = kStateTopLevel;
554 EndCurrentBlock();
555 return false;
556 }
557 uint32 rtp_timestamp;
558 uint32 data;
559 base::BigEndianReader big_endian_reader(
560 reinterpret_cast<const char*>(rtcp_data_), length);
561 big_endian_reader.ReadU32(&rtp_timestamp);
562 big_endian_reader.ReadU32(&data);
563
564 rtcp_data_ += 8;
565
566 field_.cast_receiver_log.rtp_timestamp = rtp_timestamp;
567 // We have 24 LSB of the event timestamp base on the wire.
568 field_.cast_receiver_log.event_timestamp_base = data & 0xffffff;
569
570 number_of_blocks_ = 1 + static_cast<uint8>(data >> 24);
571 state_ = kStateApplicationSpecificCastReceiverEventLog;
572 field_type_ = kRtcpApplicationSpecificCastReceiverLogFrameCode;
573 return true;
574 }
575
ParseCastReceiverLogEventItem()576 bool RtcpParser::ParseCastReceiverLogEventItem() {
577 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
578 if (length < 4) {
579 state_ = kStateTopLevel;
580 EndCurrentBlock();
581 return false;
582 }
583 if (number_of_blocks_ == 0) {
584 // Continue parsing the next receiver frame event.
585 state_ = kStateApplicationSpecificCastReceiverFrameLog;
586 return false;
587 }
588 number_of_blocks_--;
589
590 uint16 delay_delta_or_packet_id;
591 uint16 event_type_and_timestamp_delta;
592 base::BigEndianReader big_endian_reader(
593 reinterpret_cast<const char*>(rtcp_data_), length);
594 big_endian_reader.ReadU16(&delay_delta_or_packet_id);
595 big_endian_reader.ReadU16(&event_type_and_timestamp_delta);
596
597 rtcp_data_ += 4;
598
599 field_.cast_receiver_log.event =
600 static_cast<uint8>(event_type_and_timestamp_delta >> 12);
601 // delay_delta is in union'ed with packet_id.
602 field_.cast_receiver_log.delay_delta_or_packet_id.packet_id =
603 delay_delta_or_packet_id;
604 field_.cast_receiver_log.event_timestamp_delta =
605 event_type_and_timestamp_delta & 0xfff;
606
607 field_type_ = kRtcpApplicationSpecificCastReceiverLogEventCode;
608 return true;
609 }
610
ParseFeedBackCommon(const RtcpCommonHeader & header)611 bool RtcpParser::ParseFeedBackCommon(const RtcpCommonHeader& header) {
612 DCHECK((header.PT == transport::kPacketTypeGenericRtpFeedback) ||
613 (header.PT == transport::kPacketTypePayloadSpecific))
614 << "Invalid state";
615
616 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
617
618 if (length < 12) { // 4 * 3, RFC4585 section 6.1
619 EndCurrentBlock();
620 return false;
621 }
622
623 uint32 sender_ssrc;
624 uint32 media_ssrc;
625 base::BigEndianReader big_endian_reader(
626 reinterpret_cast<const char*>(rtcp_data_), length);
627 big_endian_reader.Skip(4); // Skip header.
628 big_endian_reader.ReadU32(&sender_ssrc);
629 big_endian_reader.ReadU32(&media_ssrc);
630
631 rtcp_data_ += 12;
632
633 if (header.PT == transport::kPacketTypeGenericRtpFeedback) {
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 == transport::kPacketTypePayloadSpecific) {
667 // Payload specific feedback
668 switch (header.IC) {
669 case 1:
670 // PLI
671 field_type_ = kRtcpPayloadSpecificPliCode;
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:
678 // Sli
679 break;
680 case 3:
681 field_type_ = kRtcpPayloadSpecificRpsiCode;
682 field_.rpsi.sender_ssrc = sender_ssrc;
683 field_.rpsi.media_ssrc = media_ssrc;
684 state_ = kStatePayloadSpecificRpsi;
685 return true;
686 case 4:
687 // fir
688 break;
689 case 15:
690 field_type_ = kRtcpPayloadSpecificAppCode;
691 field_.application_specific.sender_ssrc = sender_ssrc;
692 field_.application_specific.media_ssrc = media_ssrc;
693 state_ = kStatePayloadSpecificApplication;
694 return true;
695 default:
696 break;
697 }
698
699 EndCurrentBlock();
700 return false;
701 } else {
702 DCHECK(false) << "Invalid state";
703 EndCurrentBlock();
704 return false;
705 }
706 }
707
ParseRpsiItem()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
ParseNackItem()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
ParsePayloadSpecificAppItem()767 bool RtcpParser::ParsePayloadSpecificAppItem() {
768 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
769
770 if (length < 4) {
771 state_ = kStateTopLevel;
772 EndCurrentBlock();
773 return false;
774 }
775 uint32 name;
776 base::BigEndianReader big_endian_reader(
777 reinterpret_cast<const char*>(rtcp_data_), length);
778 big_endian_reader.ReadU32(&name);
779 rtcp_data_ += 4;
780
781 if (name == kRemb) {
782 field_type_ = kRtcpPayloadSpecificRembCode;
783 state_ = kStatePayloadSpecificRemb;
784 return true;
785 } else if (name == kCast) {
786 field_type_ = kRtcpPayloadSpecificCastCode;
787 state_ = kStatePayloadSpecificCast;
788 return true;
789 }
790 state_ = kStateTopLevel;
791 EndCurrentBlock();
792 return false;
793 }
794
ParsePayloadSpecificRembItem()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
ParsePayloadSpecificCastItem()835 bool RtcpParser::ParsePayloadSpecificCastItem() {
836 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
837 if (length < 4) {
838 state_ = kStateTopLevel;
839 EndCurrentBlock();
840 return false;
841 }
842 field_type_ = kRtcpPayloadSpecificCastCode;
843
844 base::BigEndianReader big_endian_reader(
845 reinterpret_cast<const char*>(rtcp_data_), length);
846 big_endian_reader.ReadU8(&field_.cast_item.last_frame_id);
847 big_endian_reader.ReadU8(&field_.cast_item.number_of_lost_fields);
848 big_endian_reader.ReadU16(&field_.cast_item.target_delay_ms);
849
850 rtcp_data_ += 4;
851
852 if (field_.cast_item.number_of_lost_fields != 0) {
853 // State transition
854 state_ = kStatePayloadSpecificCastNack;
855 } else {
856 // Don't go to state cast nack item if got 0 fields.
857 state_ = kStateTopLevel;
858 EndCurrentBlock();
859 }
860 return true;
861 }
862
ParsePayloadSpecificCastNackItem()863 bool RtcpParser::ParsePayloadSpecificCastNackItem() {
864 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
865 if (length < 4) {
866 state_ = kStateTopLevel;
867 EndCurrentBlock();
868 return false;
869 }
870 field_type_ = kRtcpPayloadSpecificCastNackItemCode;
871
872 base::BigEndianReader big_endian_reader(
873 reinterpret_cast<const char*>(rtcp_data_), length);
874 big_endian_reader.ReadU8(&field_.cast_nack_item.frame_id);
875 big_endian_reader.ReadU16(&field_.cast_nack_item.packet_id);
876 big_endian_reader.ReadU8(&field_.cast_nack_item.bitmask);
877
878 rtcp_data_ += 4;
879 return true;
880 }
881
ParseFirItem()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
ParseExtendedReport()902 bool RtcpParser::ParseExtendedReport() {
903 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
904 if (length < 8)
905 return false;
906
907 field_type_ = kRtcpXrCode;
908
909 base::BigEndianReader big_endian_reader(
910 reinterpret_cast<const char*>(rtcp_data_), length);
911 big_endian_reader.Skip(4); // Skip header.
912 big_endian_reader.ReadU32(&field_.extended_report.sender_ssrc);
913
914 rtcp_data_ += 8;
915
916 state_ = kStateExtendedReportBlock;
917 return true;
918 }
919
ParseExtendedReportItem()920 bool RtcpParser::ParseExtendedReportItem() {
921 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
922 if (length < 4) {
923 state_ = kStateTopLevel;
924 EndCurrentBlock();
925 return false;
926 }
927
928 uint8 block_type;
929 uint16 block_length;
930 base::BigEndianReader big_endian_reader(
931 reinterpret_cast<const char*>(rtcp_data_), length);
932 big_endian_reader.ReadU8(&block_type);
933 big_endian_reader.Skip(1); // Ignore reserved.
934 big_endian_reader.ReadU16(&block_length);
935
936 rtcp_data_ += 4;
937
938 switch (block_type) {
939 case 4:
940 if (block_length != 2) {
941 // Invalid block length.
942 state_ = kStateTopLevel;
943 EndCurrentBlock();
944 return false;
945 }
946 return ParseExtendedReportReceiverReferenceTimeReport();
947 case 5:
948 if (block_length % 3 != 0) {
949 // Invalid block length.
950 state_ = kStateTopLevel;
951 EndCurrentBlock();
952 return false;
953 }
954 if (block_length >= 3) {
955 number_of_blocks_ = block_length / 3;
956 state_ = kStateExtendedReportDelaySinceLastReceiverReport;
957 return ParseExtendedReportDelaySinceLastReceiverReport();
958 }
959 return true;
960 default:
961 if (length < block_length * 4) {
962 state_ = kStateTopLevel;
963 EndCurrentBlock();
964 return false;
965 }
966 field_type_ = kRtcpXrUnknownItemCode;
967 rtcp_data_ += block_length * 4;
968 return true;
969 }
970 }
971
ParseExtendedReportReceiverReferenceTimeReport()972 bool RtcpParser::ParseExtendedReportReceiverReferenceTimeReport() {
973 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
974 if (length < 8) {
975 state_ = kStateTopLevel;
976 EndCurrentBlock();
977 return false;
978 }
979
980 base::BigEndianReader big_endian_reader(
981 reinterpret_cast<const char*>(rtcp_data_), length);
982 big_endian_reader.ReadU32(&field_.rrtr.ntp_most_significant);
983 big_endian_reader.ReadU32(&field_.rrtr.ntp_least_significant);
984
985 rtcp_data_ += 8;
986
987 field_type_ = kRtcpXrRrtrCode;
988 return true;
989 }
990
ParseExtendedReportDelaySinceLastReceiverReport()991 bool RtcpParser::ParseExtendedReportDelaySinceLastReceiverReport() {
992 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
993 if (length < 12) {
994 state_ = kStateTopLevel;
995 EndCurrentBlock();
996 return false;
997 }
998 if (number_of_blocks_ == 0) {
999 // Continue parsing the extended report block.
1000 state_ = kStateExtendedReportBlock;
1001 return false;
1002 }
1003
1004 base::BigEndianReader big_endian_reader(
1005 reinterpret_cast<const char*>(rtcp_data_), length);
1006 big_endian_reader.ReadU32(&field_.dlrr.receivers_ssrc);
1007 big_endian_reader.ReadU32(&field_.dlrr.last_receiver_report);
1008 big_endian_reader.ReadU32(&field_.dlrr.delay_last_receiver_report);
1009
1010 rtcp_data_ += 12;
1011
1012 number_of_blocks_--;
1013 field_type_ = kRtcpXrDlrrCode;
1014 return true;
1015 }
1016
1017 // Converts a log event type to an integer value.
1018 // NOTE: We have only allocated 4 bits to represent the type of event over the
1019 // wire. Therefore, this function can only return values from 0 to 15.
ConvertEventTypeToWireFormat(CastLoggingEvent event)1020 uint8 ConvertEventTypeToWireFormat(CastLoggingEvent event) {
1021 switch (event) {
1022 case FRAME_ACK_SENT:
1023 return 11;
1024 case FRAME_PLAYOUT:
1025 return 12;
1026 case FRAME_DECODED:
1027 return 13;
1028 case PACKET_RECEIVED:
1029 return 14;
1030 default:
1031 return 0; // Not an interesting event.
1032 }
1033 }
1034
TranslateToLogEventFromWireFormat(uint8 event)1035 CastLoggingEvent TranslateToLogEventFromWireFormat(uint8 event) {
1036 // TODO(imcheng): Remove the old mappings once they are no longer used.
1037 switch (event) {
1038 case 1: // AudioAckSent
1039 case 5: // VideoAckSent
1040 case 11: // Unified
1041 return FRAME_ACK_SENT;
1042 case 2: // AudioPlayoutDelay
1043 case 7: // VideoRenderDelay
1044 case 12: // Unified
1045 return FRAME_PLAYOUT;
1046 case 3: // AudioFrameDecoded
1047 case 6: // VideoFrameDecoded
1048 case 13: // Unified
1049 return FRAME_DECODED;
1050 case 4: // AudioPacketReceived
1051 case 8: // VideoPacketReceived
1052 case 14: // Unified
1053 return PACKET_RECEIVED;
1054 case 9: // DuplicateAudioPacketReceived
1055 case 10: // DuplicateVideoPacketReceived
1056 default:
1057 // If the sender adds new log messages we will end up here until we add
1058 // the new messages in the receiver.
1059 VLOG(1) << "Unexpected log message received: " << static_cast<int>(event);
1060 NOTREACHED();
1061 return UNKNOWN;
1062 }
1063 }
1064
1065 } // namespace cast
1066 } // namespace media
1067