OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/cast/rtcp/rtcp_receiver.h" | 5 #include "media/cast/rtcp/rtcp_receiver.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "media/cast/rtcp/rtcp_utility.h" | 9 #include "media/cast/rtcp/rtcp_utility.h" |
10 | 10 |
| 11 namespace { |
| 12 |
| 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 default: |
| 28 // If the sender adds new log messages we will end up here until we add |
| 29 // the new messages in the receiver. |
| 30 VLOG(1) << "Unexpected log message received: " << static_cast<int>(event); |
| 31 NOTREACHED(); |
| 32 return media::cast::kUnknown; |
| 33 } |
| 34 } |
| 35 |
| 36 media::cast::RtcpSenderFrameStatus TranslateToFrameStatusFromWireFormat( |
| 37 uint8 status) { |
| 38 switch (status) { |
| 39 case 0: |
| 40 return media::cast::kRtcpSenderFrameStatusUnknown; |
| 41 case 1: |
| 42 return media::cast::kRtcpSenderFrameStatusDroppedByEncoder; |
| 43 case 2: |
| 44 return media::cast::kRtcpSenderFrameStatusDroppedByFlowControl; |
| 45 case 3: |
| 46 return media::cast::kRtcpSenderFrameStatusSentToNetwork; |
| 47 default: |
| 48 // If the sender adds new log messages we will end up here until we add |
| 49 // the new messages in the receiver. |
| 50 NOTREACHED(); |
| 51 VLOG(1) << "Unexpected status received: " << static_cast<int>(status); |
| 52 return media::cast::kRtcpSenderFrameStatusUnknown; |
| 53 } |
| 54 } |
| 55 |
| 56 } // namespace |
| 57 |
11 namespace media { | 58 namespace media { |
12 namespace cast { | 59 namespace cast { |
13 | 60 |
14 RtcpReceiver::RtcpReceiver(RtcpSenderFeedback* sender_feedback, | 61 RtcpReceiver::RtcpReceiver(RtcpSenderFeedback* sender_feedback, |
15 RtcpReceiverFeedback* receiver_feedback, | 62 RtcpReceiverFeedback* receiver_feedback, |
16 RtcpRttFeedback* rtt_feedback, | 63 RtcpRttFeedback* rtt_feedback, |
17 uint32 local_ssrc) | 64 uint32 local_ssrc) |
18 : ssrc_(local_ssrc), | 65 : ssrc_(local_ssrc), |
19 remote_ssrc_(0), | 66 remote_ssrc_(0), |
20 sender_feedback_(sender_feedback), | 67 sender_feedback_(sender_feedback), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 break; | 107 break; |
61 case kRtcpPayloadSpecificRpsiCode: | 108 case kRtcpPayloadSpecificRpsiCode: |
62 HandleRpsi(rtcp_parser); | 109 HandleRpsi(rtcp_parser); |
63 break; | 110 break; |
64 case kRtcpPayloadSpecificFirCode: | 111 case kRtcpPayloadSpecificFirCode: |
65 HandleFIR(rtcp_parser); | 112 HandleFIR(rtcp_parser); |
66 break; | 113 break; |
67 case kRtcpPayloadSpecificAppCode: | 114 case kRtcpPayloadSpecificAppCode: |
68 HandlePayloadSpecificApp(rtcp_parser); | 115 HandlePayloadSpecificApp(rtcp_parser); |
69 break; | 116 break; |
| 117 case kRtcpApplicationSpecificCastReceiverLogCode: |
| 118 HandleApplicationSpecificCastReceiverLog(rtcp_parser); |
| 119 break; |
| 120 case kRtcpApplicationSpecificCastSenderLogCode: |
| 121 HandleApplicationSpecificCastSenderLog(rtcp_parser); |
| 122 break; |
70 case kRtcpPayloadSpecificRembCode: | 123 case kRtcpPayloadSpecificRembCode: |
71 case kRtcpPayloadSpecificRembItemCode: | 124 case kRtcpPayloadSpecificRembItemCode: |
72 // Ignore this until we want to support interop with webrtc. | |
73 rtcp_parser->Iterate(); | |
74 break; | |
75 case kRtcpPayloadSpecificCastCode: | 125 case kRtcpPayloadSpecificCastCode: |
76 case kRtcpPayloadSpecificCastNackItemCode: | 126 case kRtcpPayloadSpecificCastNackItemCode: |
77 rtcp_parser->Iterate(); | 127 case kRtcpApplicationSpecificCastReceiverLogFrameCode: |
78 break; | 128 case kRtcpApplicationSpecificCastReceiverLogEventCode: |
79 case kRtcpNotValidCode: | 129 case kRtcpNotValidCode: |
80 case kRtcpReportBlockItemCode: | 130 case kRtcpReportBlockItemCode: |
81 case kRtcpSdesChunkCode: | 131 case kRtcpSdesChunkCode: |
82 case kRtcpGenericRtpFeedbackNackItemCode: | 132 case kRtcpGenericRtpFeedbackNackItemCode: |
83 case kRtcpPayloadSpecificFirItemCode: | 133 case kRtcpPayloadSpecificFirItemCode: |
84 case kRtcpXrRrtrCode: | 134 case kRtcpXrRrtrCode: |
85 case kRtcpXrDlrrCode: | 135 case kRtcpXrDlrrCode: |
86 case kRtcpXrUnknownItemCode: | 136 case kRtcpXrUnknownItemCode: |
87 rtcp_parser->Iterate(); | 137 rtcp_parser->Iterate(); |
88 DCHECK(false) << "Invalid state"; | 138 NOTREACHED() << "Invalid state"; |
89 break; | 139 break; |
90 } | 140 } |
91 field_type = rtcp_parser->FieldType(); | 141 field_type = rtcp_parser->FieldType(); |
92 } | 142 } |
93 } | 143 } |
94 | 144 |
95 void RtcpReceiver::HandleSenderReport(RtcpParser* rtcp_parser) { | 145 void RtcpReceiver::HandleSenderReport(RtcpParser* rtcp_parser) { |
96 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType(); | 146 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType(); |
97 const RtcpField& rtcp_field = rtcp_parser->Field(); | 147 const RtcpField& rtcp_field = rtcp_parser->Field(); |
98 | 148 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 rtt_feedback_->OnReceivedDelaySinceLastReport( | 298 rtt_feedback_->OnReceivedDelaySinceLastReport( |
249 rtcp_field.dlrr.receivers_ssrc, | 299 rtcp_field.dlrr.receivers_ssrc, |
250 rtcp_field.dlrr.last_receiver_report, | 300 rtcp_field.dlrr.last_receiver_report, |
251 rtcp_field.dlrr.delay_last_receiver_report); | 301 rtcp_field.dlrr.delay_last_receiver_report); |
252 } | 302 } |
253 } | 303 } |
254 | 304 |
255 void RtcpReceiver::HandleNACK(RtcpParser* rtcp_parser) { | 305 void RtcpReceiver::HandleNACK(RtcpParser* rtcp_parser) { |
256 const RtcpField& rtcp_field = rtcp_parser->Field(); | 306 const RtcpField& rtcp_field = rtcp_parser->Field(); |
257 if (ssrc_ != rtcp_field.nack.media_ssrc) { | 307 if (ssrc_ != rtcp_field.nack.media_ssrc) { |
258 // Not to us. | 308 RtcpFieldTypes field_type; |
259 rtcp_parser->Iterate(); | 309 // Message not to us. Iterate until we have passed this message. |
| 310 do { |
| 311 field_type = rtcp_parser->Iterate(); |
| 312 } while (field_type == kRtcpGenericRtpFeedbackNackItemCode); |
260 return; | 313 return; |
261 } | 314 } |
262 std::list<uint16> nackSequenceNumbers; | 315 std::list<uint16> nackSequenceNumbers; |
263 | 316 |
264 RtcpFieldTypes field_type = rtcp_parser->Iterate(); | 317 RtcpFieldTypes field_type = rtcp_parser->Iterate(); |
265 while (field_type == kRtcpGenericRtpFeedbackNackItemCode) { | 318 while (field_type == kRtcpGenericRtpFeedbackNackItemCode) { |
266 HandleNACKItem(&rtcp_field, &nackSequenceNumbers); | 319 HandleNACKItem(&rtcp_field, &nackSequenceNumbers); |
267 field_type = rtcp_parser->Iterate(); | 320 field_type = rtcp_parser->Iterate(); |
268 } | 321 } |
269 } | 322 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 } | 380 } |
328 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[bytes - 1] & 0x7f); | 381 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[bytes - 1] & 0x7f); |
329 | 382 |
330 VLOG(1) << "Cast RTCP received RPSI with picture_id " << rpsi_picture_id; | 383 VLOG(1) << "Cast RTCP received RPSI with picture_id " << rpsi_picture_id; |
331 } | 384 } |
332 | 385 |
333 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) { | 386 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) { |
334 const RtcpField& rtcp_field = rtcp_parser->Field(); | 387 const RtcpField& rtcp_field = rtcp_parser->Field(); |
335 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc; | 388 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc; |
336 if (remote_ssrc_ != remote_ssrc) { | 389 if (remote_ssrc_ != remote_ssrc) { |
337 // Message not to us. | 390 // Message not to us. Iterate until we have passed this message. |
338 rtcp_parser->Iterate(); | 391 RtcpFieldTypes field_type; |
| 392 do { |
| 393 field_type = rtcp_parser->Iterate(); |
| 394 } while (field_type == kRtcpPayloadSpecificRembCode || |
| 395 field_type == kRtcpPayloadSpecificRembItemCode || |
| 396 field_type == kRtcpPayloadSpecificCastCode || |
| 397 field_type == kRtcpPayloadSpecificCastNackItemCode); |
339 return; | 398 return; |
340 } | 399 } |
341 | 400 |
342 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); | 401 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); |
343 switch (packet_type) { | 402 switch (packet_type) { |
344 case kRtcpPayloadSpecificRembCode: | 403 case kRtcpPayloadSpecificRembCode: |
345 packet_type = rtcp_parser->Iterate(); | 404 packet_type = rtcp_parser->Iterate(); |
346 if (packet_type == kRtcpPayloadSpecificRembItemCode) { | 405 if (packet_type == kRtcpPayloadSpecificRembItemCode) { |
347 HandlePayloadSpecificRembItem(rtcp_parser); | 406 HandlePayloadSpecificRembItem(rtcp_parser); |
348 rtcp_parser->Iterate(); | 407 rtcp_parser->Iterate(); |
(...skipping 16 matching lines...) Expand all Loading... |
365 for (int i = 0; i < rtcp_field.remb_item.number_of_ssrcs; ++i) { | 424 for (int i = 0; i < rtcp_field.remb_item.number_of_ssrcs; ++i) { |
366 if (rtcp_field.remb_item.ssrcs[i] == ssrc_) { | 425 if (rtcp_field.remb_item.ssrcs[i] == ssrc_) { |
367 // Found matching ssrc. | 426 // Found matching ssrc. |
368 VLOG(1) << "Cast RTCP received REMB with received_bitrate " | 427 VLOG(1) << "Cast RTCP received REMB with received_bitrate " |
369 << rtcp_field.remb_item.bitrate; | 428 << rtcp_field.remb_item.bitrate; |
370 return; | 429 return; |
371 } | 430 } |
372 } | 431 } |
373 } | 432 } |
374 | 433 |
| 434 void RtcpReceiver::HandleApplicationSpecificCastReceiverLog( |
| 435 RtcpParser* rtcp_parser) { |
| 436 const RtcpField& rtcp_field = rtcp_parser->Field(); |
| 437 |
| 438 uint32 remote_ssrc = rtcp_field.cast_receiver_log.sender_ssrc; |
| 439 if (remote_ssrc_ != remote_ssrc) { |
| 440 // Message not to us. Iterate until we have passed this message. |
| 441 RtcpFieldTypes field_type; |
| 442 do { |
| 443 field_type = rtcp_parser->Iterate(); |
| 444 } while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode || |
| 445 field_type == kRtcpApplicationSpecificCastReceiverLogEventCode); |
| 446 return; |
| 447 } |
| 448 RtcpReceiverLogMessage receiver_log; |
| 449 RtcpFieldTypes field_type = rtcp_parser->Iterate(); |
| 450 while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode) { |
| 451 RtcpReceiverFrameLogMessage frame_log( |
| 452 rtcp_field.cast_receiver_log.rtp_timestamp); |
| 453 |
| 454 field_type = rtcp_parser->Iterate(); |
| 455 while (field_type == kRtcpApplicationSpecificCastReceiverLogEventCode) { |
| 456 HandleApplicationSpecificCastReceiverEventLog(rtcp_parser, |
| 457 &frame_log.event_log_messages); |
| 458 field_type = rtcp_parser->Iterate(); |
| 459 } |
| 460 receiver_log.push_back(frame_log); |
| 461 } |
| 462 |
| 463 if (receiver_feedback_ && !receiver_log.empty()) { |
| 464 receiver_feedback_->OnReceivedReceiverLog(receiver_log); |
| 465 } |
| 466 } |
| 467 |
| 468 void RtcpReceiver::HandleApplicationSpecificCastReceiverEventLog( |
| 469 RtcpParser* rtcp_parser, |
| 470 RtcpReceiverEventLogMessages* event_log_messages) { |
| 471 const RtcpField& rtcp_field = rtcp_parser->Field(); |
| 472 |
| 473 RtcpReceiverEventLogMessage event_log; |
| 474 event_log.type = TranslateToLogEventFromWireFormat( |
| 475 rtcp_field.cast_receiver_log.event); |
| 476 event_log.event_timestamp = base::TimeTicks() + |
| 477 base::TimeDelta::FromMilliseconds( |
| 478 rtcp_field.cast_receiver_log.event_timestamp_base + |
| 479 rtcp_field.cast_receiver_log.event_timestamp_delta); |
| 480 event_log.delay_delta = base::TimeDelta::FromMilliseconds( |
| 481 rtcp_field.cast_receiver_log.delay_delta_or_packet_id); |
| 482 event_log.packet_id = |
| 483 rtcp_field.cast_receiver_log.delay_delta_or_packet_id; |
| 484 event_log_messages->push_back(event_log); |
| 485 } |
| 486 |
| 487 void RtcpReceiver::HandleApplicationSpecificCastSenderLog( |
| 488 RtcpParser* rtcp_parser) { |
| 489 const RtcpField& rtcp_field = rtcp_parser->Field(); |
| 490 uint32 remote_ssrc = rtcp_field.cast_sender_log.sender_ssrc; |
| 491 |
| 492 if (remote_ssrc_ != remote_ssrc) { |
| 493 RtcpFieldTypes field_type; |
| 494 // Message not to us. Iterate until we have passed this message. |
| 495 do { |
| 496 field_type = rtcp_parser->Iterate(); |
| 497 } while (field_type == kRtcpApplicationSpecificCastSenderLogCode); |
| 498 return; |
| 499 } |
| 500 RtcpSenderLogMessage sender_log; |
| 501 |
| 502 RtcpFieldTypes field_type = rtcp_parser->Iterate(); |
| 503 while (field_type == kRtcpApplicationSpecificCastSenderLogCode) { |
| 504 const RtcpField& rtcp_field = rtcp_parser->Field(); |
| 505 RtcpSenderFrameLogMessage frame_log; |
| 506 frame_log.frame_status = |
| 507 TranslateToFrameStatusFromWireFormat(rtcp_field.cast_sender_log.status); |
| 508 frame_log.rtp_timestamp = rtcp_field.cast_sender_log.rtp_timestamp; |
| 509 sender_log.push_back(frame_log); |
| 510 field_type = rtcp_parser->Iterate(); |
| 511 } |
| 512 if (receiver_feedback_) { |
| 513 receiver_feedback_->OnReceivedSenderLog(sender_log); |
| 514 } |
| 515 } |
| 516 |
375 void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) { | 517 void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) { |
376 const RtcpField& rtcp_field = rtcp_parser->Field(); | 518 const RtcpField& rtcp_field = rtcp_parser->Field(); |
377 | |
378 RtcpCastMessage cast_message(remote_ssrc_); | 519 RtcpCastMessage cast_message(remote_ssrc_); |
379 cast_message.ack_frame_id_ = ack_frame_id_wrap_helper_.MapTo32bitsFrameId( | 520 cast_message.ack_frame_id_ = ack_frame_id_wrap_helper_.MapTo32bitsFrameId( |
380 rtcp_field.cast_item.last_frame_id); | 521 rtcp_field.cast_item.last_frame_id); |
381 | 522 |
382 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); | 523 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); |
383 while (packet_type == kRtcpPayloadSpecificCastNackItemCode) { | 524 while (packet_type == kRtcpPayloadSpecificCastNackItemCode) { |
384 const RtcpField& rtcp_field = rtcp_parser->Field(); | 525 const RtcpField& rtcp_field = rtcp_parser->Field(); |
385 HandlePayloadSpecificCastNackItem( | 526 HandlePayloadSpecificCastNackItem( |
386 &rtcp_field, &cast_message.missing_frames_and_packets_); | 527 &rtcp_field, &cast_message.missing_frames_and_packets_); |
387 packet_type = rtcp_parser->Iterate(); | 528 packet_type = rtcp_parser->Iterate(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 | 579 |
439 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) { | 580 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) { |
440 // Is it our sender that is requested to generate a new keyframe. | 581 // Is it our sender that is requested to generate a new keyframe. |
441 if (ssrc_ != rtcp_field->fir_item.ssrc) return; | 582 if (ssrc_ != rtcp_field->fir_item.ssrc) return; |
442 | 583 |
443 VLOG(1) << "Cast RTCP received FIR on our SSRC " << ssrc_; | 584 VLOG(1) << "Cast RTCP received FIR on our SSRC " << ssrc_; |
444 } | 585 } |
445 | 586 |
446 } // namespace cast | 587 } // namespace cast |
447 } // namespace media | 588 } // namespace media |
OLD | NEW |