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