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/logging.h"
8 #include "net/base/big_endian.h"
9
10 namespace media {
11 namespace cast {
12
RtcpParser(const uint8 * rtcpData,size_t rtcpDataLength)13 RtcpParser::RtcpParser(const uint8* rtcpData, size_t rtcpDataLength)
14 : rtcp_data_begin_(rtcpData),
15 rtcp_data_end_(rtcpData + rtcpDataLength),
16 valid_packet_(false),
17 rtcp_data_(rtcpData),
18 rtcp_block_end_(NULL),
19 state_(kStateTopLevel),
20 number_of_blocks_(0),
21 field_type_(kRtcpNotValidCode) {
22 Validate();
23 }
24
~RtcpParser()25 RtcpParser::~RtcpParser() {}
26
FieldType() const27 RtcpFieldTypes RtcpParser::FieldType() const {
28 return field_type_;
29 }
30
Field() const31 const RtcpField& RtcpParser::Field() const {
32 return field_;
33 }
34
Begin()35 RtcpFieldTypes RtcpParser::Begin() {
36 rtcp_data_ = rtcp_data_begin_;
37 return Iterate();
38 }
39
Iterate()40 RtcpFieldTypes RtcpParser::Iterate() {
41 // Reset packet type
42 field_type_ = kRtcpNotValidCode;
43
44 if (!IsValid()) return kRtcpNotValidCode;
45
46 switch (state_) {
47 case kStateTopLevel:
48 IterateTopLevel();
49 break;
50 case kStateReportBlock:
51 IterateReportBlockItem();
52 break;
53 case kStateSdes:
54 IterateSdesItem();
55 break;
56 case kStateBye:
57 IterateByeItem();
58 break;
59 case kStateApplicationSpecificCastReceiverFrameLog:
60 IterateCastReceiverLogFrame();
61 break;
62 case kStateApplicationSpecificCastReceiverEventLog:
63 IterateCastReceiverLogEvent();
64 break;
65 case kStateApplicationSpecificCastSenderLog:
66 IterateCastSenderLog();
67 break;
68 case kStateExtendedReportBlock:
69 IterateExtendedReportItem();
70 break;
71 case kStateExtendedReportDelaySinceLastReceiverReport:
72 IterateExtendedReportDelaySinceLastReceiverReportItem();
73 break;
74 case kStateGenericRtpFeedbackNack:
75 IterateNackItem();
76 break;
77 case kStatePayloadSpecificRpsi:
78 IterateRpsiItem();
79 break;
80 case kStatePayloadSpecificFir:
81 IterateFirItem();
82 break;
83 case kStatePayloadSpecificApplication:
84 IteratePayloadSpecificAppItem();
85 break;
86 case kStatePayloadSpecificRemb:
87 IteratePayloadSpecificRembItem();
88 break;
89 case kStatePayloadSpecificCast:
90 IteratePayloadSpecificCastItem();
91 break;
92 case kStatePayloadSpecificCastNack:
93 IteratePayloadSpecificCastNackItem();
94 break;
95 }
96 return field_type_;
97 }
98
IterateTopLevel()99 void RtcpParser::IterateTopLevel() {
100 for (;;) {
101 RtcpCommonHeader header;
102
103 bool success = RtcpParseCommonHeader(rtcp_data_, rtcp_data_end_, &header);
104 if (!success) return;
105
106 rtcp_block_end_ = rtcp_data_ + header.length_in_octets;
107
108 if (rtcp_block_end_ > rtcp_data_end_) return; // Bad block!
109
110 switch (header.PT) {
111 case kPacketTypeSenderReport:
112 // number of Report blocks
113 number_of_blocks_ = header.IC;
114 ParseSR();
115 return;
116 case kPacketTypeReceiverReport:
117 // number of Report blocks
118 number_of_blocks_ = header.IC;
119 ParseRR();
120 return;
121 case kPacketTypeSdes:
122 // number of Sdes blocks
123 number_of_blocks_ = header.IC;
124 if (!ParseSdes()) {
125 break; // Nothing supported found, continue to next block!
126 }
127 return;
128 case kPacketTypeBye:
129 number_of_blocks_ = header.IC;
130 if (!ParseBye()) {
131 // Nothing supported found, continue to next block!
132 break;
133 }
134 return;
135 case kPacketTypeApplicationDefined:
136 if (!ParseApplicationDefined(header.IC)) {
137 // Nothing supported found, continue to next block!
138 break;
139 }
140 return;
141 case kPacketTypeGenericRtpFeedback: // Fall through!
142 case kPacketTypePayloadSpecific:
143 if (!ParseFeedBackCommon(header)) {
144 // Nothing supported found, continue to next block!
145 break;
146 }
147 return;
148 case kPacketTypeXr:
149 if (!ParseExtendedReport()) {
150 break; // Nothing supported found, continue to next block!
151 }
152 return;
153 default:
154 // Not supported! Skip!
155 EndCurrentBlock();
156 break;
157 }
158 }
159 }
160
IterateReportBlockItem()161 void RtcpParser::IterateReportBlockItem() {
162 bool success = ParseReportBlockItem();
163 if (!success) Iterate();
164 }
165
IterateSdesItem()166 void RtcpParser::IterateSdesItem() {
167 bool success = ParseSdesItem();
168 if (!success) Iterate();
169 }
170
IterateByeItem()171 void RtcpParser::IterateByeItem() {
172 bool success = ParseByeItem();
173 if (!success) Iterate();
174 }
175
IterateExtendedReportItem()176 void RtcpParser::IterateExtendedReportItem() {
177 bool success = ParseExtendedReportItem();
178 if (!success) Iterate();
179 }
180
IterateExtendedReportDelaySinceLastReceiverReportItem()181 void RtcpParser::IterateExtendedReportDelaySinceLastReceiverReportItem() {
182 bool success = ParseExtendedReportDelaySinceLastReceiverReport();
183 if (!success) Iterate();
184 }
185
IterateNackItem()186 void RtcpParser::IterateNackItem() {
187 bool success = ParseNackItem();
188 if (!success) Iterate();
189 }
190
IterateRpsiItem()191 void RtcpParser::IterateRpsiItem() {
192 bool success = ParseRpsiItem();
193 if (!success) Iterate();
194 }
195
IterateFirItem()196 void RtcpParser::IterateFirItem() {
197 bool success = ParseFirItem();
198 if (!success) Iterate();
199 }
200
IteratePayloadSpecificAppItem()201 void RtcpParser::IteratePayloadSpecificAppItem() {
202 bool success = ParsePayloadSpecificAppItem();
203 if (!success) Iterate();
204 }
205
IteratePayloadSpecificRembItem()206 void RtcpParser::IteratePayloadSpecificRembItem() {
207 bool success = ParsePayloadSpecificRembItem();
208 if (!success) Iterate();
209 }
210
IteratePayloadSpecificCastItem()211 void RtcpParser::IteratePayloadSpecificCastItem() {
212 bool success = ParsePayloadSpecificCastItem();
213 if (!success) Iterate();
214 }
215
IteratePayloadSpecificCastNackItem()216 void RtcpParser::IteratePayloadSpecificCastNackItem() {
217 bool success = ParsePayloadSpecificCastNackItem();
218 if (!success) Iterate();
219 }
220
IterateCastReceiverLogFrame()221 void RtcpParser::IterateCastReceiverLogFrame() {
222 bool success = ParseCastReceiverLogFrameItem();
223 if (!success) Iterate();
224 }
225
IterateCastReceiverLogEvent()226 void RtcpParser::IterateCastReceiverLogEvent() {
227 bool success = ParseCastReceiverLogEventItem();
228 if (!success) Iterate();
229 }
230
IterateCastSenderLog()231 void RtcpParser::IterateCastSenderLog() {
232 bool success = ParseCastSenderLogItem();
233 if (!success) Iterate();
234 }
235
Validate()236 void RtcpParser::Validate() {
237 if (rtcp_data_ == NULL) return; // NOT VALID
238
239 RtcpCommonHeader header;
240 bool success = RtcpParseCommonHeader(rtcp_data_begin_, rtcp_data_end_,
241 &header);
242
243 if (!success) return; // NOT VALID!
244
245 valid_packet_ = true;
246 }
247
IsValid() const248 bool RtcpParser::IsValid() const {
249 return valid_packet_;
250 }
251
EndCurrentBlock()252 void RtcpParser::EndCurrentBlock() {
253 rtcp_data_ = rtcp_block_end_;
254 }
255
RtcpParseCommonHeader(const uint8 * data_begin,const uint8 * data_end,RtcpCommonHeader * parsed_header) const256 bool RtcpParser::RtcpParseCommonHeader(const uint8* data_begin,
257 const uint8* data_end,
258 RtcpCommonHeader* parsed_header) const {
259 if (!data_begin || !data_end) return false;
260
261 // 0 1 2 3
262 // 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
263 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
264 // |V=2|P| IC | PT | length |
265 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
266 //
267 // Common header for all Rtcp packets, 4 octets.
268
269 if ((data_end - data_begin) < 4) return false;
270
271 parsed_header->V = data_begin[0] >> 6;
272 parsed_header->P = ((data_begin[0] & 0x20) == 0) ? false : true;
273 parsed_header->IC = data_begin[0] & 0x1f;
274 parsed_header->PT = data_begin[1];
275
276 parsed_header->length_in_octets =
277 ((data_begin[2] << 8) + data_begin[3] + 1) * 4;
278
279 if (parsed_header->length_in_octets == 0) return false;
280
281 // Check if RTP version field == 2.
282 if (parsed_header->V != 2) return false;
283
284 return true;
285 }
286
ParseRR()287 bool RtcpParser::ParseRR() {
288 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
289 if (length < 8) return false;
290
291 field_type_ = kRtcpRrCode;
292
293 net::BigEndianReader big_endian_reader(rtcp_data_, length);
294 big_endian_reader.Skip(4); // Skip header
295 big_endian_reader.ReadU32(&field_.receiver_report.sender_ssrc);
296 field_.receiver_report.number_of_report_blocks = number_of_blocks_;
297 rtcp_data_ += 8;
298
299 // State transition
300 state_ = kStateReportBlock;
301 return true;
302 }
303
ParseSR()304 bool RtcpParser::ParseSR() {
305 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
306 if (length < 28) {
307 EndCurrentBlock();
308 return false;
309 }
310 field_type_ = kRtcpSrCode;
311
312 net::BigEndianReader big_endian_reader(rtcp_data_, length);
313 big_endian_reader.Skip(4); // Skip header
314 big_endian_reader.ReadU32(&field_.sender_report.sender_ssrc);
315 big_endian_reader.ReadU32(&field_.sender_report.ntp_most_significant);
316 big_endian_reader.ReadU32(&field_.sender_report.ntp_least_significant);
317 big_endian_reader.ReadU32(&field_.sender_report.rtp_timestamp);
318 big_endian_reader.ReadU32(&field_.sender_report.sender_packet_count);
319 big_endian_reader.ReadU32(&field_.sender_report.sender_octet_count);
320 field_.sender_report.number_of_report_blocks = number_of_blocks_;
321 rtcp_data_ += 28;
322
323 if (number_of_blocks_ != 0) {
324 // State transition.
325 state_ = kStateReportBlock;
326 } else {
327 // Don't go to state report block item if 0 report blocks.
328 state_ = kStateTopLevel;
329 EndCurrentBlock();
330 }
331 return true;
332 }
333
ParseReportBlockItem()334 bool RtcpParser::ParseReportBlockItem() {
335 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
336 if (length < 24 || number_of_blocks_ <= 0) {
337 state_ = kStateTopLevel;
338 EndCurrentBlock();
339 return false;
340 }
341
342 net::BigEndianReader big_endian_reader(rtcp_data_, length);
343 big_endian_reader.ReadU32(&field_.report_block_item.ssrc);
344 big_endian_reader.ReadU8(&field_.report_block_item.fraction_lost);
345
346 uint8 temp_number_of_packets_lost;
347 big_endian_reader.ReadU8(&temp_number_of_packets_lost);
348 field_.report_block_item.cumulative_number_of_packets_lost =
349 temp_number_of_packets_lost << 16;
350 big_endian_reader.ReadU8(&temp_number_of_packets_lost);
351 field_.report_block_item.cumulative_number_of_packets_lost +=
352 temp_number_of_packets_lost << 8;
353 big_endian_reader.ReadU8(&temp_number_of_packets_lost);
354 field_.report_block_item.cumulative_number_of_packets_lost +=
355 temp_number_of_packets_lost;
356
357 big_endian_reader.ReadU32(
358 &field_.report_block_item.extended_highest_sequence_number);
359 big_endian_reader.ReadU32(&field_.report_block_item.jitter);
360 big_endian_reader.ReadU32(&field_.report_block_item.last_sender_report);
361 big_endian_reader.ReadU32(&field_.report_block_item.delay_last_sender_report);
362 rtcp_data_ += 24;
363
364 number_of_blocks_--;
365 field_type_ = kRtcpReportBlockItemCode;
366 return true;
367 }
368
ParseSdes()369 bool RtcpParser::ParseSdes() {
370 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
371
372 if (length < 8) {
373 state_ = kStateTopLevel;
374 EndCurrentBlock();
375 return false;
376 }
377 rtcp_data_ += 4; // Skip header
378
379 state_ = kStateSdes;
380 field_type_ = kRtcpSdesCode;
381 return true;
382 }
383
ParseSdesItem()384 bool RtcpParser::ParseSdesItem() {
385 if (number_of_blocks_ <= 0) {
386 state_ = kStateTopLevel;
387 EndCurrentBlock();
388 return false;
389 }
390 number_of_blocks_--;
391
392 // Find c_name item in a Sdes chunk.
393 while (rtcp_data_ < rtcp_block_end_) {
394 ptrdiff_t data_length = rtcp_block_end_ - rtcp_data_;
395 if (data_length < 4) {
396 state_ = kStateTopLevel;
397 EndCurrentBlock();
398 return false;
399 }
400
401 uint32 ssrc;
402 net::BigEndianReader big_endian_reader(rtcp_data_, data_length);
403 big_endian_reader.ReadU32(&ssrc);
404 rtcp_data_ += 4;
405
406 bool found_c_name = ParseSdesTypes();
407 if (found_c_name) {
408 field_.c_name.sender_ssrc = ssrc;
409 return true;
410 }
411 }
412 state_ = kStateTopLevel;
413 EndCurrentBlock();
414 return false;
415 }
416
ParseSdesTypes()417 bool RtcpParser::ParseSdesTypes() {
418 // Only the c_name item is mandatory. RFC 3550 page 46.
419 bool found_c_name = false;
420 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
421 net::BigEndianReader big_endian_reader(rtcp_data_, length);
422
423 while (big_endian_reader.remaining() > 0) {
424 uint8 tag;
425 big_endian_reader.ReadU8(&tag);
426
427 if (tag == 0) {
428 // End tag! 4 octet aligned.
429 rtcp_data_ = rtcp_block_end_;
430 return found_c_name;
431 }
432
433 if (big_endian_reader.remaining() > 0) {
434 uint8 len;
435 big_endian_reader.ReadU8(&len);
436
437 if (tag == 1) { // c_name.
438 // Sanity check.
439 if (big_endian_reader.remaining() < len) {
440 state_ = kStateTopLevel;
441 EndCurrentBlock();
442 return false;
443 }
444 int i = 0;
445 for (; i < len; ++i) {
446 uint8 c;
447 big_endian_reader.ReadU8(&c);
448 if ((c < ' ') || (c > '{') || (c == '%') || (c == '\\')) {
449 // Illegal char.
450 state_ = kStateTopLevel;
451 EndCurrentBlock();
452 return false;
453 }
454 field_.c_name.name[i] = c;
455 }
456 // Make sure we are null terminated.
457 field_.c_name.name[i] = 0;
458 field_type_ = kRtcpSdesChunkCode;
459 found_c_name = true;
460 } else {
461 big_endian_reader.Skip(len);
462 }
463 }
464 }
465 // No end tag found!
466 state_ = kStateTopLevel;
467 EndCurrentBlock();
468 return false;
469 }
470
ParseBye()471 bool RtcpParser::ParseBye() {
472 rtcp_data_ += 4; // Skip header.
473 state_ = kStateBye;
474 return ParseByeItem();
475 }
476
ParseByeItem()477 bool RtcpParser::ParseByeItem() {
478 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
479 if (length < 4 || number_of_blocks_ == 0) {
480 state_ = kStateTopLevel;
481 EndCurrentBlock();
482 return false;
483 }
484
485 field_type_ = kRtcpByeCode;
486
487 net::BigEndianReader big_endian_reader(rtcp_data_, length);
488 big_endian_reader.ReadU32(&field_.bye.sender_ssrc);
489 rtcp_data_ += 4;
490
491 // We can have several CSRCs attached.
492 if (length >= 4 * number_of_blocks_) {
493 rtcp_data_ += (number_of_blocks_ - 1) * 4;
494 }
495 number_of_blocks_ = 0;
496 return true;
497 }
498
ParseApplicationDefined(uint8 subtype)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
ParseCastReceiverLogFrameItem()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
ParseCastReceiverLogEventItem()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
ParseCastSenderLogItem()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
ParseFeedBackCommon(const RtcpCommonHeader & header)617 bool RtcpParser::ParseFeedBackCommon(const RtcpCommonHeader& header) {
618 DCHECK((header.PT == kPacketTypeGenericRtpFeedback) ||
619 (header.PT == kPacketTypePayloadSpecific)) << "Invalid state";
620
621 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
622
623 if (length < 12) { // 4 * 3, RFC4585 section 6.1
624 EndCurrentBlock();
625 return false;
626 }
627
628 uint32 sender_ssrc;
629 uint32 media_ssrc;
630 net::BigEndianReader big_endian_reader(rtcp_data_, length);
631 big_endian_reader.Skip(4); // Skip header.
632 big_endian_reader.ReadU32(&sender_ssrc);
633 big_endian_reader.ReadU32(&media_ssrc);
634
635 rtcp_data_ += 12;
636
637 if (header.PT == kPacketTypeGenericRtpFeedback) {
638 // Transport layer feedback
639 switch (header.IC) {
640 case 1:
641 // Nack
642 field_type_ = kRtcpGenericRtpFeedbackNackCode;
643 field_.nack.sender_ssrc = sender_ssrc;
644 field_.nack.media_ssrc = media_ssrc;
645 state_ = kStateGenericRtpFeedbackNack;
646 return true;
647 case 2:
648 // Used to be ACK is this code point, which is removed conficts with
649 // http://tools.ietf.org/html/draft-levin-avt-rtcp-burst-00
650 break;
651 case 3:
652 // Tmmbr
653 break;
654 case 4:
655 // Tmmbn
656 break;
657 case 5:
658 // RFC 6051 RTCP-sender_report-REQ Rapid Synchronisation of RTP Flows
659 // Trigger a new Rtcp sender_report
660 field_type_ = kRtcpGenericRtpFeedbackSrReqCode;
661
662 // Note: No state transition, sender report REQ is empty!
663 return true;
664 default:
665 break;
666 }
667 EndCurrentBlock();
668 return false;
669
670 } else if (header.PT == kPacketTypePayloadSpecific) {
671 // Payload specific feedback
672 switch (header.IC) {
673 case 1:
674 // PLI
675 field_type_ = kRtcpPayloadSpecificPliCode;
676 field_.pli.sender_ssrc = sender_ssrc;
677 field_.pli.media_ssrc = media_ssrc;
678
679 // Note: No state transition, PLI FCI is empty!
680 return true;
681 case 2:
682 // Sli
683 break;
684 case 3:
685 field_type_ = kRtcpPayloadSpecificRpsiCode;
686 field_.rpsi.sender_ssrc = sender_ssrc;
687 field_.rpsi.media_ssrc = media_ssrc;
688 state_ = kStatePayloadSpecificRpsi;
689 return true;
690 case 4:
691 // fir
692 break;
693 case 15:
694 field_type_ = kRtcpPayloadSpecificAppCode;
695 field_.application_specific.sender_ssrc = sender_ssrc;
696 field_.application_specific.media_ssrc = media_ssrc;
697 state_ = kStatePayloadSpecificApplication;
698 return true;
699 default:
700 break;
701 }
702
703 EndCurrentBlock();
704 return false;
705 } else {
706 DCHECK(false) << "Invalid state";
707 EndCurrentBlock();
708 return false;
709 }
710 }
711
ParseRpsiItem()712 bool RtcpParser::ParseRpsiItem() {
713 // RFC 4585 6.3.3. Reference Picture Selection Indication (rpsi)
714 /*
715 0 1 2 3
716 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
717 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
718 | PB |0| Payload Type| Native rpsi bit string |
719 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
720 | defined per codec ... | Padding (0) |
721 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
722 */
723 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
724
725 if (length < 4) {
726 state_ = kStateTopLevel;
727 EndCurrentBlock();
728 return false;
729 }
730 if (length > 2 + kRtcpRpsiDataSize) {
731 state_ = kStateTopLevel;
732 EndCurrentBlock();
733 return false;
734 }
735
736 field_type_ = kRtcpPayloadSpecificRpsiCode;
737
738 uint8 padding_bits;
739 net::BigEndianReader big_endian_reader(rtcp_data_, length);
740 big_endian_reader.ReadU8(&padding_bits);
741 big_endian_reader.ReadU8(&field_.rpsi.payload_type);
742 big_endian_reader.ReadBytes(&field_.rpsi.native_bit_string, length - 2);
743 field_.rpsi.number_of_valid_bits =
744 static_cast<uint16>(length - 2) * 8 - padding_bits;
745
746 rtcp_data_ += length;
747 return true;
748 }
749
ParseNackItem()750 bool RtcpParser::ParseNackItem() {
751 // RFC 4585 6.2.1. Generic Nack
752
753 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
754 if (length < 4) {
755 state_ = kStateTopLevel;
756 EndCurrentBlock();
757 return false;
758 }
759
760 field_type_ = kRtcpGenericRtpFeedbackNackItemCode;
761
762 net::BigEndianReader big_endian_reader(rtcp_data_, length);
763 big_endian_reader.ReadU16(&field_.nack_item.packet_id);
764 big_endian_reader.ReadU16(&field_.nack_item.bitmask);
765 rtcp_data_ += 4;
766 return true;
767 }
768
ParsePayloadSpecificAppItem()769 bool RtcpParser::ParsePayloadSpecificAppItem() {
770 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
771
772 if (length < 4) {
773 state_ = kStateTopLevel;
774 EndCurrentBlock();
775 return false;
776 }
777 uint32 name;
778 net::BigEndianReader big_endian_reader(rtcp_data_, length);
779 big_endian_reader.ReadU32(&name);
780 rtcp_data_ += 4;
781
782 if (name == kRemb) {
783 field_type_ = kRtcpPayloadSpecificRembCode;
784 state_ = kStatePayloadSpecificRemb;
785 return true;
786 } else if (name == kCast) {
787 field_type_ = kRtcpPayloadSpecificCastCode;
788 state_ = kStatePayloadSpecificCast;
789 return true;
790 }
791 state_ = kStateTopLevel;
792 EndCurrentBlock();
793 return false;
794 }
795
ParsePayloadSpecificRembItem()796 bool RtcpParser::ParsePayloadSpecificRembItem() {
797 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
798
799 if (length < 4) {
800 state_ = kStateTopLevel;
801 EndCurrentBlock();
802 return false;
803 }
804
805 net::BigEndianReader big_endian_reader(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 net::BigEndianReader big_endian_reader(rtcp_data_, length);
845 big_endian_reader.ReadU8(&field_.cast_item.last_frame_id);
846 big_endian_reader.ReadU8(&field_.cast_item.number_of_lost_fields);
847
848 rtcp_data_ += 4;
849
850 if (field_.cast_item.number_of_lost_fields != 0) {
851 // State transition
852 state_ = kStatePayloadSpecificCastNack;
853 } else {
854 // Don't go to state cast nack item if got 0 fields.
855 state_ = kStateTopLevel;
856 EndCurrentBlock();
857 }
858 return true;
859 }
860
ParsePayloadSpecificCastNackItem()861 bool RtcpParser::ParsePayloadSpecificCastNackItem() {
862 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
863 if (length < 4) {
864 state_ = kStateTopLevel;
865 EndCurrentBlock();
866 return false;
867 }
868 field_type_ = kRtcpPayloadSpecificCastNackItemCode;
869
870 net::BigEndianReader big_endian_reader(rtcp_data_, length);
871 big_endian_reader.ReadU8(&field_.cast_nack_item.frame_id);
872 big_endian_reader.ReadU16(&field_.cast_nack_item.packet_id);
873 big_endian_reader.ReadU8(&field_.cast_nack_item.bitmask);
874
875 rtcp_data_ += 4;
876 return true;
877 }
878
ParseFirItem()879 bool RtcpParser::ParseFirItem() {
880 // RFC 5104 4.3.1. Full Intra Request (fir)
881 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
882
883 if (length < 8) {
884 state_ = kStateTopLevel;
885 EndCurrentBlock();
886 return false;
887 }
888 field_type_ = kRtcpPayloadSpecificFirItemCode;
889
890 net::BigEndianReader big_endian_reader(rtcp_data_, length);
891 big_endian_reader.ReadU32(&field_.fir_item.ssrc);
892 big_endian_reader.ReadU8(&field_.fir_item.command_sequence_number);
893
894 rtcp_data_ += 8;
895 return true;
896 }
897
ParseExtendedReport()898 bool RtcpParser::ParseExtendedReport() {
899 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
900 if (length < 8) return false;
901
902 field_type_ = kRtcpXrCode;
903
904 net::BigEndianReader big_endian_reader(rtcp_data_, length);
905 big_endian_reader.Skip(4); // Skip header.
906 big_endian_reader.ReadU32(&field_.extended_report.sender_ssrc);
907
908 rtcp_data_ += 8;
909
910 state_ = kStateExtendedReportBlock;
911 return true;
912 }
913
ParseExtendedReportItem()914 bool RtcpParser::ParseExtendedReportItem() {
915 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
916 if (length < 4) {
917 state_ = kStateTopLevel;
918 EndCurrentBlock();
919 return false;
920 }
921
922 uint8 block_type;
923 uint16 block_length;
924 net::BigEndianReader big_endian_reader(rtcp_data_, length);
925 big_endian_reader.ReadU8(&block_type);
926 big_endian_reader.Skip(1); // Ignore reserved.
927 big_endian_reader.ReadU16(&block_length);
928
929 rtcp_data_ += 4;
930
931 switch (block_type) {
932 case 4:
933 if (block_length != 2) {
934 // Invalid block length.
935 state_ = kStateTopLevel;
936 EndCurrentBlock();
937 return false;
938 }
939 return ParseExtendedReportReceiverReferenceTimeReport();
940 case 5:
941 if (block_length % 3 != 0) {
942 // Invalid block length.
943 state_ = kStateTopLevel;
944 EndCurrentBlock();
945 return false;
946 }
947 if (block_length >= 3) {
948 number_of_blocks_ = block_length / 3;
949 state_ = kStateExtendedReportDelaySinceLastReceiverReport;
950 return ParseExtendedReportDelaySinceLastReceiverReport();
951 }
952 return true;
953 default:
954 if (length < block_length * 4) {
955 state_ = kStateTopLevel;
956 EndCurrentBlock();
957 return false;
958 }
959 field_type_ = kRtcpXrUnknownItemCode;
960 rtcp_data_ += block_length * 4;
961 return true;
962 }
963 }
964
ParseExtendedReportReceiverReferenceTimeReport()965 bool RtcpParser::ParseExtendedReportReceiverReferenceTimeReport() {
966 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
967 if (length < 8) {
968 state_ = kStateTopLevel;
969 EndCurrentBlock();
970 return false;
971 }
972
973 net::BigEndianReader big_endian_reader(rtcp_data_, length);
974 big_endian_reader.ReadU32(&field_.rrtr.ntp_most_significant);
975 big_endian_reader.ReadU32(&field_.rrtr.ntp_least_significant);
976
977 rtcp_data_ += 8;
978
979 field_type_ = kRtcpXrRrtrCode;
980 return true;
981 }
982
ParseExtendedReportDelaySinceLastReceiverReport()983 bool RtcpParser::ParseExtendedReportDelaySinceLastReceiverReport() {
984 ptrdiff_t length = rtcp_block_end_ - rtcp_data_;
985 if (length < 12) {
986 state_ = kStateTopLevel;
987 EndCurrentBlock();
988 return false;
989 }
990 if (number_of_blocks_ == 0) {
991 // Continue parsing the extended report block.
992 state_ = kStateExtendedReportBlock;
993 return false;
994 }
995
996 net::BigEndianReader big_endian_reader(rtcp_data_, length);
997 big_endian_reader.ReadU32(&field_.dlrr.receivers_ssrc);
998 big_endian_reader.ReadU32(&field_.dlrr.last_receiver_report);
999 big_endian_reader.ReadU32(&field_.dlrr.delay_last_receiver_report);
1000
1001 rtcp_data_ += 12;
1002
1003 number_of_blocks_--;
1004 field_type_ = kRtcpXrDlrrCode;
1005 return true;
1006 }
1007
1008 } // namespace cast
1009 } // namespace media
1010