• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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