• 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_receiver.h"
6 
7 #include "base/logging.h"
8 #include "media/cast/rtcp/rtcp_utility.h"
9 
10 namespace {
11 
TranslateToLogEventFromWireFormat(uint8 event)12 media::cast::CastLoggingEvent TranslateToLogEventFromWireFormat(uint8 event) {
13   switch (event) {
14     case 1:
15       return media::cast::kAckSent;
16     case 2:
17       return media::cast::kAudioPlayoutDelay;
18     case 3:
19       return media::cast::kAudioFrameDecoded;
20     case 4:
21       return media::cast::kVideoFrameDecoded;
22     case 5:
23       return media::cast::kVideoRenderDelay;
24     case 6:
25       return media::cast::kPacketReceived;
26     default:
27       // If the sender adds new log messages we will end up here until we add
28       // the new messages in the receiver.
29       VLOG(1) << "Unexpected log message received: " << static_cast<int>(event);
30       NOTREACHED();
31       return media::cast::kUnknown;
32   }
33 }
34 
TranslateToFrameStatusFromWireFormat(uint8 status)35 media::cast::RtcpSenderFrameStatus TranslateToFrameStatusFromWireFormat(
36     uint8 status) {
37   switch (status) {
38     case 0:
39       return media::cast::kRtcpSenderFrameStatusUnknown;
40     case 1:
41       return media::cast::kRtcpSenderFrameStatusDroppedByEncoder;
42     case 2:
43       return media::cast::kRtcpSenderFrameStatusDroppedByFlowControl;
44     case 3:
45       return media::cast::kRtcpSenderFrameStatusSentToNetwork;
46     default:
47       // If the sender adds new log messages we will end up here until we add
48       // the new messages in the receiver.
49       NOTREACHED();
50       VLOG(1) << "Unexpected status received: " << static_cast<int>(status);
51       return media::cast::kRtcpSenderFrameStatusUnknown;
52   }
53 }
54 
55 }  // namespace
56 
57 namespace media {
58 namespace cast {
59 
RtcpReceiver(scoped_refptr<CastEnvironment> cast_environment,RtcpSenderFeedback * sender_feedback,RtcpReceiverFeedback * receiver_feedback,RtcpRttFeedback * rtt_feedback,uint32 local_ssrc)60 RtcpReceiver::RtcpReceiver(scoped_refptr<CastEnvironment> cast_environment,
61                            RtcpSenderFeedback* sender_feedback,
62                            RtcpReceiverFeedback* receiver_feedback,
63                            RtcpRttFeedback* rtt_feedback,
64                            uint32 local_ssrc)
65     : ssrc_(local_ssrc),
66       remote_ssrc_(0),
67       sender_feedback_(sender_feedback),
68       receiver_feedback_(receiver_feedback),
69       rtt_feedback_(rtt_feedback),
70       cast_environment_(cast_environment) {}
71 
~RtcpReceiver()72 RtcpReceiver::~RtcpReceiver() {}
73 
SetRemoteSSRC(uint32 ssrc)74 void RtcpReceiver::SetRemoteSSRC(uint32 ssrc) {
75   remote_ssrc_ = ssrc;
76 }
77 
IncomingRtcpPacket(RtcpParser * rtcp_parser)78 void RtcpReceiver::IncomingRtcpPacket(RtcpParser* rtcp_parser) {
79   RtcpFieldTypes field_type = rtcp_parser->Begin();
80   while (field_type != kRtcpNotValidCode) {
81     // Each "case" is responsible for iterate the parser to the next top
82     // level packet.
83     switch (field_type) {
84       case kRtcpSrCode:
85         HandleSenderReport(rtcp_parser);
86         break;
87       case kRtcpRrCode:
88         HandleReceiverReport(rtcp_parser);
89         break;
90       case kRtcpSdesCode:
91         HandleSDES(rtcp_parser);
92         break;
93       case kRtcpByeCode:
94         HandleBYE(rtcp_parser);
95         break;
96       case kRtcpXrCode:
97         HandleXr(rtcp_parser);
98         break;
99       case kRtcpGenericRtpFeedbackNackCode:
100         HandleNACK(rtcp_parser);
101         break;
102       case kRtcpGenericRtpFeedbackSrReqCode:
103         HandleSendReportRequest(rtcp_parser);
104         break;
105       case kRtcpPayloadSpecificPliCode:
106         HandlePLI(rtcp_parser);
107         break;
108       case kRtcpPayloadSpecificRpsiCode:
109         HandleRpsi(rtcp_parser);
110         break;
111       case kRtcpPayloadSpecificFirCode:
112         HandleFIR(rtcp_parser);
113         break;
114       case kRtcpPayloadSpecificAppCode:
115         HandlePayloadSpecificApp(rtcp_parser);
116         break;
117       case kRtcpApplicationSpecificCastReceiverLogCode:
118         HandleApplicationSpecificCastReceiverLog(rtcp_parser);
119         break;
120       case kRtcpApplicationSpecificCastSenderLogCode:
121         HandleApplicationSpecificCastSenderLog(rtcp_parser);
122         break;
123       case kRtcpPayloadSpecificRembCode:
124       case kRtcpPayloadSpecificRembItemCode:
125       case kRtcpPayloadSpecificCastCode:
126       case kRtcpPayloadSpecificCastNackItemCode:
127       case kRtcpApplicationSpecificCastReceiverLogFrameCode:
128       case kRtcpApplicationSpecificCastReceiverLogEventCode:
129       case kRtcpNotValidCode:
130       case kRtcpReportBlockItemCode:
131       case kRtcpSdesChunkCode:
132       case kRtcpGenericRtpFeedbackNackItemCode:
133       case kRtcpPayloadSpecificFirItemCode:
134       case kRtcpXrRrtrCode:
135       case kRtcpXrDlrrCode:
136       case kRtcpXrUnknownItemCode:
137         rtcp_parser->Iterate();
138         NOTREACHED() << "Invalid state";
139         break;
140     }
141     field_type = rtcp_parser->FieldType();
142   }
143 }
144 
HandleSenderReport(RtcpParser * rtcp_parser)145 void RtcpReceiver::HandleSenderReport(RtcpParser* rtcp_parser) {
146   RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
147   const RtcpField& rtcp_field = rtcp_parser->Field();
148 
149   DCHECK(rtcp_field_type == kRtcpSrCode) << "Invalid state";
150 
151   // Synchronization source identifier for the originator of this SR packet.
152   uint32 remote_ssrc = rtcp_field.sender_report.sender_ssrc;
153 
154   VLOG(1) << "Cast RTCP received SR from SSRC " << remote_ssrc;
155 
156   if (remote_ssrc_ == remote_ssrc) {
157     RtcpSenderInfo remote_sender_info;
158     remote_sender_info.ntp_seconds =
159         rtcp_field.sender_report.ntp_most_significant;
160     remote_sender_info.ntp_fraction =
161         rtcp_field.sender_report.ntp_least_significant;
162     remote_sender_info.rtp_timestamp =
163         rtcp_field.sender_report.rtp_timestamp;
164     remote_sender_info.send_packet_count =
165         rtcp_field.sender_report.sender_packet_count;
166     remote_sender_info.send_octet_count =
167         rtcp_field.sender_report.sender_octet_count;
168     if (receiver_feedback_) {
169       receiver_feedback_->OnReceivedSenderReport(remote_sender_info);
170     }
171   }
172   rtcp_field_type = rtcp_parser->Iterate();
173   while (rtcp_field_type == kRtcpReportBlockItemCode) {
174     HandleReportBlock(&rtcp_field, remote_ssrc);
175     rtcp_field_type = rtcp_parser->Iterate();
176   }
177 }
178 
HandleReceiverReport(RtcpParser * rtcp_parser)179 void RtcpReceiver::HandleReceiverReport(RtcpParser* rtcp_parser) {
180   RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
181   const RtcpField& rtcp_field = rtcp_parser->Field();
182 
183   DCHECK(rtcp_field_type == kRtcpRrCode) << "Invalid state";
184 
185   uint32 remote_ssrc = rtcp_field.receiver_report.sender_ssrc;
186 
187   VLOG(1) << "Cast RTCP received RR from SSRC " << remote_ssrc;
188 
189   rtcp_field_type = rtcp_parser->Iterate();
190   while (rtcp_field_type == kRtcpReportBlockItemCode) {
191     HandleReportBlock(&rtcp_field, remote_ssrc);
192     rtcp_field_type = rtcp_parser->Iterate();
193   }
194 }
195 
HandleReportBlock(const RtcpField * rtcp_field,uint32 remote_ssrc)196 void RtcpReceiver::HandleReportBlock(const RtcpField* rtcp_field,
197                                      uint32 remote_ssrc) {
198   // This will be called once per report block in the Rtcp packet.
199   // We filter out all report blocks that are not for us.
200   // Each packet has max 31 RR blocks.
201   //
202   // We can calculate RTT if we send a send report and get a report block back.
203 
204   // |rtcp_field.ReportBlockItem.ssrc| is the ssrc identifier of the source to
205   // which the information in this reception report block pertains.
206 
207   const RtcpFieldReportBlockItem& rb = rtcp_field->report_block_item;
208 
209   // Filter out all report blocks that are not for us.
210   if (rb.ssrc != ssrc_) {
211     // This block is not for us ignore it.
212     return;
213   }
214   VLOG(1) << "Cast RTCP received RB from SSRC " << remote_ssrc;
215   cast_environment_->Logging()->InsertGenericEvent(kPacketLoss,
216                                                    rb.fraction_lost);
217   cast_environment_->Logging()->InsertGenericEvent(kJitterMs,
218                                                    rb.jitter);
219 
220   RtcpReportBlock report_block;
221   report_block.remote_ssrc = remote_ssrc;
222   report_block.media_ssrc = rb.ssrc;
223   report_block.fraction_lost = rb.fraction_lost;
224   report_block.cumulative_lost = rb.cumulative_number_of_packets_lost;
225   report_block.extended_high_sequence_number =
226       rb.extended_highest_sequence_number;
227   report_block.jitter = rb.jitter;
228   report_block.last_sr = rb.last_sender_report;
229   report_block.delay_since_last_sr = rb.delay_last_sender_report;
230 
231   if (rtt_feedback_) {
232     rtt_feedback_->OnReceivedDelaySinceLastReport(rb.ssrc,
233                                                   rb.last_sender_report,
234                                                   rb.delay_last_sender_report);
235   }
236 }
237 
HandleSDES(RtcpParser * rtcp_parser)238 void RtcpReceiver::HandleSDES(RtcpParser* rtcp_parser) {
239   RtcpFieldTypes field_type = rtcp_parser->Iterate();
240   while (field_type == kRtcpSdesChunkCode) {
241     HandleSDESChunk(rtcp_parser);
242     field_type = rtcp_parser->Iterate();
243   }
244 }
245 
HandleSDESChunk(RtcpParser * rtcp_parser)246 void RtcpReceiver::HandleSDESChunk(RtcpParser* rtcp_parser) {
247   const RtcpField& rtcp_field = rtcp_parser->Field();
248   VLOG(1) << "Cast RTCP received SDES with cname " << rtcp_field.c_name.name;
249 }
250 
HandleXr(RtcpParser * rtcp_parser)251 void RtcpReceiver::HandleXr(RtcpParser* rtcp_parser) {
252   RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
253   const RtcpField& rtcp_field = rtcp_parser->Field();
254 
255   DCHECK(rtcp_field_type == kRtcpXrCode) << "Invalid state";
256 
257   uint32 remote_ssrc = rtcp_field.extended_report.sender_ssrc;
258   rtcp_field_type = rtcp_parser->Iterate();
259 
260   while (rtcp_field_type == kRtcpXrDlrrCode ||
261          rtcp_field_type == kRtcpXrRrtrCode ||
262          rtcp_field_type == kRtcpXrUnknownItemCode) {
263     if (rtcp_field_type == kRtcpXrRrtrCode) {
264       HandleRrtr(rtcp_parser, remote_ssrc);
265     } else if (rtcp_field_type == kRtcpXrDlrrCode) {
266       HandleDlrr(rtcp_parser);
267     }
268     rtcp_field_type = rtcp_parser->Iterate();
269   }
270 }
271 
HandleRrtr(RtcpParser * rtcp_parser,uint32 remote_ssrc)272 void RtcpReceiver::HandleRrtr(RtcpParser* rtcp_parser, uint32 remote_ssrc) {
273   if (remote_ssrc_ != remote_ssrc) {
274     // Not to us.
275     return;
276   }
277   const RtcpField& rtcp_field = rtcp_parser->Field();
278   RtcpReceiverReferenceTimeReport remote_time_report;
279   remote_time_report.remote_ssrc = remote_ssrc;
280   remote_time_report.ntp_seconds = rtcp_field.rrtr.ntp_most_significant;
281   remote_time_report.ntp_fraction = rtcp_field.rrtr.ntp_least_significant;
282 
283   if (receiver_feedback_) {
284     receiver_feedback_->OnReceiverReferenceTimeReport(remote_time_report);
285   }
286 }
287 
HandleDlrr(RtcpParser * rtcp_parser)288 void RtcpReceiver::HandleDlrr(RtcpParser* rtcp_parser) {
289   const RtcpField& rtcp_field = rtcp_parser->Field();
290   if (remote_ssrc_ != rtcp_field.dlrr.receivers_ssrc) {
291     // Not to us.
292     return;
293   }
294   if (rtt_feedback_) {
295     rtt_feedback_->OnReceivedDelaySinceLastReport(
296         rtcp_field.dlrr.receivers_ssrc,
297         rtcp_field.dlrr.last_receiver_report,
298         rtcp_field.dlrr.delay_last_receiver_report);
299   }
300 }
301 
HandleNACK(RtcpParser * rtcp_parser)302 void RtcpReceiver::HandleNACK(RtcpParser* rtcp_parser) {
303   const RtcpField& rtcp_field = rtcp_parser->Field();
304   if (ssrc_ != rtcp_field.nack.media_ssrc) {
305     RtcpFieldTypes field_type;
306     // Message not to us. Iterate until we have passed this message.
307     do {
308       field_type = rtcp_parser->Iterate();
309     } while (field_type == kRtcpGenericRtpFeedbackNackItemCode);
310     return;
311   }
312   std::list<uint16> nackSequenceNumbers;
313 
314   RtcpFieldTypes field_type = rtcp_parser->Iterate();
315   while (field_type == kRtcpGenericRtpFeedbackNackItemCode) {
316     HandleNACKItem(&rtcp_field, &nackSequenceNumbers);
317     field_type = rtcp_parser->Iterate();
318   }
319 }
320 
HandleNACKItem(const RtcpField * rtcp_field,std::list<uint16> * nack_sequence_numbers)321 void RtcpReceiver::HandleNACKItem(const RtcpField* rtcp_field,
322                                   std::list<uint16>* nack_sequence_numbers) {
323   nack_sequence_numbers->push_back(rtcp_field->nack_item.packet_id);
324 
325   uint16 bitmask = rtcp_field->nack_item.bitmask;
326   if (bitmask) {
327     for (int i = 1; i <= 16; ++i) {
328       if (bitmask & 1) {
329         nack_sequence_numbers->push_back(rtcp_field->nack_item.packet_id + i);
330       }
331       bitmask = bitmask >> 1;
332     }
333   }
334 }
335 
HandleBYE(RtcpParser * rtcp_parser)336 void RtcpReceiver::HandleBYE(RtcpParser* rtcp_parser) {
337   const RtcpField& rtcp_field = rtcp_parser->Field();
338   uint32 remote_ssrc = rtcp_field.bye.sender_ssrc;
339   if (remote_ssrc_ == remote_ssrc) {
340     VLOG(1) << "Cast RTCP received BYE from SSRC " << remote_ssrc;
341   }
342   rtcp_parser->Iterate();
343 }
344 
HandlePLI(RtcpParser * rtcp_parser)345 void RtcpReceiver::HandlePLI(RtcpParser* rtcp_parser) {
346   const RtcpField& rtcp_field = rtcp_parser->Field();
347   if (ssrc_ == rtcp_field.pli.media_ssrc) {
348     // Received a signal that we need to send a new key frame.
349     VLOG(1) << "Cast RTCP received PLI on our SSRC " << ssrc_;
350   }
351   rtcp_parser->Iterate();
352 }
353 
HandleSendReportRequest(RtcpParser * rtcp_parser)354 void RtcpReceiver::HandleSendReportRequest(RtcpParser* rtcp_parser) {
355   if (receiver_feedback_) {
356     receiver_feedback_->OnReceivedSendReportRequest();
357   }
358   rtcp_parser->Iterate();
359 }
360 
HandleRpsi(RtcpParser * rtcp_parser)361 void RtcpReceiver::HandleRpsi(RtcpParser* rtcp_parser) {
362   const RtcpField& rtcp_field = rtcp_parser->Field();
363   if (rtcp_parser->Iterate() != kRtcpPayloadSpecificRpsiCode) {
364     return;
365   }
366   if (rtcp_field.rpsi.number_of_valid_bits % 8 != 0) {
367     // Continue
368     return;
369   }
370   uint64 rpsi_picture_id = 0;
371 
372   // Convert native_bit_string to rpsi_picture_id
373   uint8 bytes = rtcp_field.rpsi.number_of_valid_bits / 8;
374   for (uint8 n = 0; n < (bytes - 1); ++n) {
375     rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[n] & 0x7f);
376     rpsi_picture_id <<= 7;  // Prepare next.
377   }
378   rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[bytes - 1] & 0x7f);
379 
380   VLOG(1) << "Cast RTCP received RPSI with picture_id " << rpsi_picture_id;
381 }
382 
HandlePayloadSpecificApp(RtcpParser * rtcp_parser)383 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) {
384   const RtcpField& rtcp_field = rtcp_parser->Field();
385   uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc;
386   if (remote_ssrc_ != remote_ssrc) {
387     // Message not to us. Iterate until we have passed this message.
388     RtcpFieldTypes field_type;
389     do {
390       field_type = rtcp_parser->Iterate();
391     } while (field_type == kRtcpPayloadSpecificRembCode ||
392              field_type == kRtcpPayloadSpecificRembItemCode ||
393              field_type == kRtcpPayloadSpecificCastCode ||
394              field_type == kRtcpPayloadSpecificCastNackItemCode);
395     return;
396   }
397 
398   RtcpFieldTypes packet_type = rtcp_parser->Iterate();
399   switch (packet_type) {
400     case kRtcpPayloadSpecificRembCode:
401       packet_type = rtcp_parser->Iterate();
402       if (packet_type == kRtcpPayloadSpecificRembItemCode) {
403         HandlePayloadSpecificRembItem(rtcp_parser);
404         rtcp_parser->Iterate();
405       }
406       break;
407     case kRtcpPayloadSpecificCastCode:
408       packet_type = rtcp_parser->Iterate();
409       if (packet_type == kRtcpPayloadSpecificCastCode) {
410         HandlePayloadSpecificCastItem(rtcp_parser);
411       }
412       break;
413     default:
414       return;
415   }
416 }
417 
HandlePayloadSpecificRembItem(RtcpParser * rtcp_parser)418 void RtcpReceiver::HandlePayloadSpecificRembItem(RtcpParser* rtcp_parser) {
419   const RtcpField& rtcp_field = rtcp_parser->Field();
420 
421   for (int i = 0; i < rtcp_field.remb_item.number_of_ssrcs; ++i) {
422     if (rtcp_field.remb_item.ssrcs[i] == ssrc_) {
423       // Found matching ssrc.
424       VLOG(1) << "Cast RTCP received REMB with received_bitrate "
425               << rtcp_field.remb_item.bitrate;
426       return;
427     }
428   }
429 }
430 
HandleApplicationSpecificCastReceiverLog(RtcpParser * rtcp_parser)431 void RtcpReceiver::HandleApplicationSpecificCastReceiverLog(
432     RtcpParser* rtcp_parser) {
433   const RtcpField& rtcp_field = rtcp_parser->Field();
434 
435   uint32 remote_ssrc = rtcp_field.cast_receiver_log.sender_ssrc;
436   if (remote_ssrc_ != remote_ssrc) {
437     // Message not to us. Iterate until we have passed this message.
438     RtcpFieldTypes field_type;
439     do {
440       field_type = rtcp_parser->Iterate();
441     } while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode ||
442              field_type == kRtcpApplicationSpecificCastReceiverLogEventCode);
443     return;
444   }
445   RtcpReceiverLogMessage receiver_log;
446   RtcpFieldTypes field_type = rtcp_parser->Iterate();
447   while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode) {
448     RtcpReceiverFrameLogMessage frame_log(
449         rtcp_field.cast_receiver_log.rtp_timestamp);
450 
451     field_type = rtcp_parser->Iterate();
452     while (field_type == kRtcpApplicationSpecificCastReceiverLogEventCode) {
453       HandleApplicationSpecificCastReceiverEventLog(rtcp_parser,
454           &frame_log.event_log_messages_);
455       field_type = rtcp_parser->Iterate();
456     }
457     receiver_log.push_back(frame_log);
458   }
459 
460   if (receiver_feedback_ && !receiver_log.empty()) {
461     receiver_feedback_->OnReceivedReceiverLog(receiver_log);
462   }
463 }
464 
HandleApplicationSpecificCastReceiverEventLog(RtcpParser * rtcp_parser,RtcpReceiverEventLogMessages * event_log_messages)465 void RtcpReceiver::HandleApplicationSpecificCastReceiverEventLog(
466     RtcpParser* rtcp_parser,
467     RtcpReceiverEventLogMessages* event_log_messages) {
468   const RtcpField& rtcp_field = rtcp_parser->Field();
469 
470   RtcpReceiverEventLogMessage event_log;
471   event_log.type = TranslateToLogEventFromWireFormat(
472       rtcp_field.cast_receiver_log.event);
473   event_log.event_timestamp = base::TimeTicks() +
474       base::TimeDelta::FromMilliseconds(
475           rtcp_field.cast_receiver_log.event_timestamp_base +
476           rtcp_field.cast_receiver_log.event_timestamp_delta);
477   event_log.delay_delta = base::TimeDelta::FromMilliseconds(
478       rtcp_field.cast_receiver_log.delay_delta_or_packet_id);
479   event_log.packet_id =
480       rtcp_field.cast_receiver_log.delay_delta_or_packet_id;
481   event_log_messages->push_back(event_log);
482 }
483 
HandleApplicationSpecificCastSenderLog(RtcpParser * rtcp_parser)484 void RtcpReceiver::HandleApplicationSpecificCastSenderLog(
485     RtcpParser* rtcp_parser) {
486   const RtcpField& rtcp_field = rtcp_parser->Field();
487   uint32 remote_ssrc = rtcp_field.cast_sender_log.sender_ssrc;
488 
489   if (remote_ssrc_ != remote_ssrc) {
490     RtcpFieldTypes field_type;
491     // Message not to us. Iterate until we have passed this message.
492     do {
493       field_type = rtcp_parser->Iterate();
494     } while (field_type == kRtcpApplicationSpecificCastSenderLogCode);
495     return;
496   }
497   RtcpSenderLogMessage sender_log;
498 
499   RtcpFieldTypes field_type = rtcp_parser->Iterate();
500   while (field_type == kRtcpApplicationSpecificCastSenderLogCode) {
501     const RtcpField& rtcp_field = rtcp_parser->Field();
502     RtcpSenderFrameLogMessage frame_log;
503     frame_log.frame_status =
504         TranslateToFrameStatusFromWireFormat(rtcp_field.cast_sender_log.status);
505     frame_log.rtp_timestamp = rtcp_field.cast_sender_log.rtp_timestamp;
506     sender_log.push_back(frame_log);
507     field_type = rtcp_parser->Iterate();
508   }
509   if (receiver_feedback_) {
510     receiver_feedback_->OnReceivedSenderLog(sender_log);
511   }
512 }
513 
HandlePayloadSpecificCastItem(RtcpParser * rtcp_parser)514 void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) {
515   const RtcpField& rtcp_field = rtcp_parser->Field();
516   RtcpCastMessage cast_message(remote_ssrc_);
517   cast_message.ack_frame_id_ = ack_frame_id_wrap_helper_.MapTo32bitsFrameId(
518       rtcp_field.cast_item.last_frame_id);
519 
520   RtcpFieldTypes packet_type = rtcp_parser->Iterate();
521   while (packet_type == kRtcpPayloadSpecificCastNackItemCode) {
522     const RtcpField& rtcp_field = rtcp_parser->Field();
523     HandlePayloadSpecificCastNackItem(
524         &rtcp_field, &cast_message.missing_frames_and_packets_);
525     packet_type = rtcp_parser->Iterate();
526   }
527   if (sender_feedback_) {
528     sender_feedback_->OnReceivedCastFeedback(cast_message);
529   }
530 }
531 
HandlePayloadSpecificCastNackItem(const RtcpField * rtcp_field,MissingFramesAndPacketsMap * missing_frames_and_packets)532 void RtcpReceiver::HandlePayloadSpecificCastNackItem(
533     const RtcpField* rtcp_field,
534     MissingFramesAndPacketsMap* missing_frames_and_packets) {
535 
536   MissingFramesAndPacketsMap::iterator frame_it =
537       missing_frames_and_packets->find(rtcp_field->cast_nack_item.frame_id);
538 
539   if (frame_it == missing_frames_and_packets->end()) {
540     // First missing packet in a frame.
541     PacketIdSet empty_set;
542     std::pair<MissingFramesAndPacketsMap::iterator, bool> ret =
543         missing_frames_and_packets->insert(std::pair<uint8, PacketIdSet>(
544             rtcp_field->cast_nack_item.frame_id, empty_set));
545     frame_it = ret.first;
546     DCHECK(frame_it != missing_frames_and_packets->end()) << "Invalid state";
547   }
548   if (rtcp_field->cast_nack_item.packet_id == kRtcpCastAllPacketsLost) {
549     // Special case all packets in a frame is missing.
550     return;
551   }
552   uint16 packet_id = rtcp_field->cast_nack_item.packet_id;
553   uint8 bitmask = rtcp_field->cast_nack_item.bitmask;
554 
555   frame_it->second.insert(packet_id);
556 
557   if (bitmask) {
558     for (int i = 1; i <= 8; ++i) {
559       if (bitmask & 1) {
560         frame_it->second.insert(packet_id + i);
561       }
562       bitmask = bitmask >> 1;
563     }
564   }
565 }
566 
HandleFIR(RtcpParser * rtcp_parser)567 void RtcpReceiver::HandleFIR(RtcpParser* rtcp_parser) {
568   const RtcpField& rtcp_field = rtcp_parser->Field();
569 
570   RtcpFieldTypes field_type = rtcp_parser->Iterate();
571   while (field_type == kRtcpPayloadSpecificFirItemCode) {
572     HandleFIRItem(&rtcp_field);
573     field_type = rtcp_parser->Iterate();
574   }
575 }
576 
HandleFIRItem(const RtcpField * rtcp_field)577 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) {
578   // Is it our sender that is requested to generate a new keyframe.
579   if (ssrc_ != rtcp_field->fir_item.ssrc) return;
580 
581   VLOG(1) << "Cast RTCP received FIR on our SSRC " << ssrc_;
582 }
583 
584 }  // namespace cast
585 }  // namespace media
586