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