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