Home | History | Annotate | Download | only in rtcp
      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 
     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 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 
     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 
    159 void RtcpParser::IterateReportBlockItem() {
    160   bool success = ParseReportBlockItem();
    161   if (!success)
    162     Iterate();
    163 }
    164 
    165 void RtcpParser::IterateSdesItem() {
    166   bool success = ParseSdesItem();
    167   if (!success)
    168     Iterate();
    169 }
    170 
    171 void RtcpParser::IterateByeItem() {
    172   bool success = ParseByeItem();
    173   if (!success)
    174     Iterate();
    175 }
    176 
    177 void RtcpParser::IterateExtendedReportItem() {
    178   bool success = ParseExtendedReportItem();
    179   if (!success)
    180     Iterate();
    181 }
    182 
    183 void RtcpParser::IterateExtendedReportDelaySinceLastReceiverReportItem() {
    184   bool success = ParseExtendedReportDelaySinceLastReceiverReport();
    185   if (!success)
    186     Iterate();
    187 }
    188 
    189 void RtcpParser::IterateNackItem() {
    190   bool success = ParseNackItem();
    191   if (!success)
    192     Iterate();
    193 }
    194 
    195 void RtcpParser::IterateRpsiItem() {
    196   bool success = ParseRpsiItem();
    197   if (!success)
    198     Iterate();
    199 }
    200 
    201 void RtcpParser::IterateFirItem() {
    202   bool success = ParseFirItem();
    203   if (!success)
    204     Iterate();
    205 }
    206 
    207 void RtcpParser::IteratePayloadSpecificAppItem() {
    208   bool success = ParsePayloadSpecificAppItem();
    209   if (!success)
    210     Iterate();
    211 }
    212 
    213 void RtcpParser::IteratePayloadSpecificRembItem() {
    214   bool success = ParsePayloadSpecificRembItem();
    215   if (!success)
    216     Iterate();
    217 }
    218 
    219 void RtcpParser::IteratePayloadSpecificCastItem() {
    220   bool success = ParsePayloadSpecificCastItem();
    221   if (!success)
    222     Iterate();
    223 }
    224 
    225 void RtcpParser::IteratePayloadSpecificCastNackItem() {
    226   bool success = ParsePayloadSpecificCastNackItem();
    227   if (!success)
    228     Iterate();
    229 }
    230 
    231 void RtcpParser::IterateCastReceiverLogFrame() {
    232   bool success = ParseCastReceiverLogFrameItem();
    233   if (!success)
    234     Iterate();
    235 }
    236 
    237 void RtcpParser::IterateCastReceiverLogEvent() {
    238   bool success = ParseCastReceiverLogEventItem();
    239   if (!success)
    240     Iterate();
    241 }
    242 
    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 
    257 bool RtcpParser::IsValid() const { return valid_packet_; }
    258 
    259 void RtcpParser::EndCurrentBlock() { rtcp_data_ = rtcp_block_end_; }
    260 
    261 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 
    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 
    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 
    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 
    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 
    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 
    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 
    486 bool RtcpParser::ParseBye() {
    487   rtcp_data_ += 4;  // Skip header.
    488   state_ = kStateBye;
    489   return ParseByeItem();
    490 }
    491 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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.
   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 
   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