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