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