Chromium Code Reviews| 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/logging.h" | 7 #include "base/logging.h" |
| 8 #include "media/cast/rtcp/rtcp_utility.h" | 8 #include "media/cast/rtcp/rtcp_utility.h" |
| 9 #include "media/cast/transport/cast_transport_defines.h" | 9 #include "media/cast/transport/cast_transport_defines.h" |
| 10 | 10 |
| 11 namespace { | 11 namespace { |
| 12 | 12 |
| 13 media::cast::CastLoggingEvent TranslateToLogEventFromWireFormat(uint8 event) { | 13 bool IsRtcpPacketEvent(media::cast::CastLoggingEvent event_type) { |
| 14 switch (event) { | 14 return event_type == media::cast::kAudioPacketReceived || |
| 15 case 1: | 15 event_type == media::cast::kVideoPacketReceived || |
| 16 return media::cast::kAudioAckSent; | 16 event_type == media::cast::kDuplicateAudioPacketReceived || |
| 17 case 2: | 17 event_type == media::cast::kDuplicateVideoPacketReceived; |
| 18 return media::cast::kAudioPlayoutDelay; | |
| 19 case 3: | |
| 20 return media::cast::kAudioFrameDecoded; | |
| 21 case 4: | |
| 22 return media::cast::kAudioPacketReceived; | |
| 23 case 5: | |
| 24 return media::cast::kVideoAckSent; | |
| 25 case 6: | |
| 26 return media::cast::kVideoFrameDecoded; | |
| 27 case 7: | |
| 28 return media::cast::kVideoRenderDelay; | |
| 29 case 8: | |
| 30 return media::cast::kVideoPacketReceived; | |
| 31 case 9: | |
| 32 return media::cast::kDuplicateAudioPacketReceived; | |
| 33 case 10: | |
| 34 return media::cast::kDuplicateVideoPacketReceived; | |
| 35 default: | |
| 36 // If the sender adds new log messages we will end up here until we add | |
| 37 // the new messages in the receiver. | |
| 38 VLOG(1) << "Unexpected log message received: " << static_cast<int>(event); | |
| 39 NOTREACHED(); | |
| 40 return media::cast::kUnknown; | |
| 41 } | |
| 42 } | 18 } |
| 43 | 19 |
| 44 media::cast::transport::RtcpSenderFrameStatus | 20 media::cast::transport::RtcpSenderFrameStatus |
| 45 TranslateToFrameStatusFromWireFormat(uint8 status) { | 21 TranslateToFrameStatusFromWireFormat(uint8 status) { |
| 46 switch (status) { | 22 switch (status) { |
| 47 case 0: | 23 case 0: |
| 48 return media::cast::transport::kRtcpSenderFrameStatusUnknown; | 24 return media::cast::transport::kRtcpSenderFrameStatusUnknown; |
| 49 case 1: | 25 case 1: |
| 50 return media::cast::transport::kRtcpSenderFrameStatusDroppedByEncoder; | 26 return media::cast::transport::kRtcpSenderFrameStatusDroppedByEncoder; |
| 51 case 2: | 27 case 2: |
| 52 return media::cast::transport::kRtcpSenderFrameStatusDroppedByFlowControl; | 28 return media::cast::transport::kRtcpSenderFrameStatusDroppedByFlowControl; |
| 53 case 3: | 29 case 3: |
| 54 return media::cast::transport::kRtcpSenderFrameStatusSentToNetwork; | 30 return media::cast::transport::kRtcpSenderFrameStatusSentToNetwork; |
| 55 default: | 31 default: |
| 56 // If the sender adds new log messages we will end up here until we add | 32 // If the sender adds new log messages we will end up here until we add |
| 57 // the new messages in the receiver. | 33 // the new messages in the receiver. |
| 58 NOTREACHED(); | 34 NOTREACHED(); |
| 59 VLOG(1) << "Unexpected status received: " << static_cast<int>(status); | 35 VLOG(1) << "Unexpected status received: " << static_cast<int>(status); |
| 60 return media::cast::transport::kRtcpSenderFrameStatusUnknown; | 36 return media::cast::transport::kRtcpSenderFrameStatusUnknown; |
| 61 } | 37 } |
| 62 } | 38 } |
| 63 | 39 |
| 64 // A receiver event is identified by frame RTP timestamp, event timestamp and | 40 // A receiver frame event is identified by frame RTP timestamp, event timestamp |
| 65 // event type. | 41 // and event type. |
| 42 // A receiver packet event is identified by all of the above plus packet id. | |
| 66 size_t HashReceiverEvent(uint32 frame_rtp_timestamp, | 43 size_t HashReceiverEvent(uint32 frame_rtp_timestamp, |
|
Alpha Left Google
2014/05/06 20:55:52
I suggest we change the hash set to use a key of s
imcheng
2014/05/06 21:19:47
Are you suggesting that we get rid of the base::Ha
Alpha Left Google
2014/05/06 21:21:45
That's right. I used it because base::hash_map mig
imcheng
2014/05/06 22:29:39
Done.
| |
| 67 const base::TimeTicks& event_timestamp, | 44 const base::TimeTicks& event_timestamp, |
| 68 media::cast::CastLoggingEvent event_type) { | 45 uint8 event_type, |
| 46 uint16 packet_id_or_zero) { | |
| 69 uint64 value1 = event_type; | 47 uint64 value1 = event_type; |
| 48 value1 <<= 16; | |
| 49 value1 |= packet_id_or_zero; | |
| 70 value1 <<= 32; | 50 value1 <<= 32; |
| 71 value1 |= frame_rtp_timestamp; | 51 value1 |= frame_rtp_timestamp; |
| 72 return base::HashInts64( | 52 return base::HashInts64( |
| 73 value1, static_cast<uint64>(event_timestamp.ToInternalValue())); | 53 value1, static_cast<uint64>(event_timestamp.ToInternalValue())); |
| 74 } | 54 } |
| 75 | 55 |
| 76 } // namespace | 56 } // namespace |
| 77 | 57 |
| 78 namespace media { | 58 namespace media { |
| 79 namespace cast { | 59 namespace cast { |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 483 receiver_feedback_->OnReceivedReceiverLog(receiver_log); | 463 receiver_feedback_->OnReceivedReceiverLog(receiver_log); |
| 484 } | 464 } |
| 485 } | 465 } |
| 486 | 466 |
| 487 void RtcpReceiver::HandleApplicationSpecificCastReceiverEventLog( | 467 void RtcpReceiver::HandleApplicationSpecificCastReceiverEventLog( |
| 488 uint32 frame_rtp_timestamp, | 468 uint32 frame_rtp_timestamp, |
| 489 RtcpParser* rtcp_parser, | 469 RtcpParser* rtcp_parser, |
| 490 RtcpReceiverEventLogMessages* event_log_messages) { | 470 RtcpReceiverEventLogMessages* event_log_messages) { |
| 491 const RtcpField& rtcp_field = rtcp_parser->Field(); | 471 const RtcpField& rtcp_field = rtcp_parser->Field(); |
| 492 | 472 |
| 493 const CastLoggingEvent event_type = | 473 const uint8 event = rtcp_field.cast_receiver_log.event; |
| 494 TranslateToLogEventFromWireFormat(rtcp_field.cast_receiver_log.event); | 474 const CastLoggingEvent event_type = TranslateToLogEventFromWireFormat(event); |
| 475 uint16 packet_id = IsRtcpPacketEvent(event_type) ? | |
| 476 rtcp_field.cast_receiver_log.delay_delta_or_packet_id.packet_id : 0; | |
| 495 const base::TimeTicks event_timestamp = | 477 const base::TimeTicks event_timestamp = |
| 496 base::TimeTicks() + | 478 base::TimeTicks() + |
| 497 base::TimeDelta::FromMilliseconds( | 479 base::TimeDelta::FromMilliseconds( |
| 498 rtcp_field.cast_receiver_log.event_timestamp_base + | 480 rtcp_field.cast_receiver_log.event_timestamp_base + |
| 499 rtcp_field.cast_receiver_log.event_timestamp_delta); | 481 rtcp_field.cast_receiver_log.event_timestamp_delta); |
| 500 | 482 |
| 501 // The following code checks to see if we have already seen this event. | 483 // The following code checks to see if we have already seen this event. |
| 502 // The algorithm works by maintaining a sliding window of events. We have | 484 // The algorithm works by maintaining a sliding window of events. We have |
| 503 // a queue and a set of events. We enqueue every new event and insert it | 485 // a queue and a set of events. We enqueue every new event and insert it |
| 504 // into the set. When the queue becomes too big we remove the oldest event | 486 // into the set. When the queue becomes too big we remove the oldest event |
| 505 // from both the queue and the set. | 487 // from both the queue and the set. |
| 506 // Different events may have the same hash value. That's okay because full | 488 // Different events may have the same hash value. That's okay because full |
| 507 // accuracy is not important in this case. | 489 // accuracy is not important in this case. |
| 508 const size_t event_hash = | 490 const size_t event_hash = |
| 509 HashReceiverEvent(frame_rtp_timestamp, event_timestamp, event_type); | 491 HashReceiverEvent(frame_rtp_timestamp, event_timestamp, event, packet_id); |
| 510 if (receiver_event_hash_set_.find(event_hash) != | 492 if (receiver_event_hash_set_.find(event_hash) != |
| 511 receiver_event_hash_set_.end()) { | 493 receiver_event_hash_set_.end()) { |
| 512 return; | 494 return; |
| 513 } else { | 495 } else { |
| 514 receiver_event_hash_set_.insert(event_hash); | 496 receiver_event_hash_set_.insert(event_hash); |
| 515 receiver_event_hash_queue_.push(event_hash); | 497 receiver_event_hash_queue_.push(event_hash); |
| 516 | 498 |
| 517 if (receiver_event_hash_queue_.size() > receiver_event_history_size_) { | 499 if (receiver_event_hash_queue_.size() > receiver_event_history_size_) { |
| 518 const size_t oldest_hash = receiver_event_hash_queue_.front(); | 500 const size_t oldest_hash = receiver_event_hash_queue_.front(); |
| 519 receiver_event_hash_queue_.pop(); | 501 receiver_event_hash_queue_.pop(); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 628 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) { | 610 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) { |
| 629 // Is it our sender that is requested to generate a new keyframe. | 611 // Is it our sender that is requested to generate a new keyframe. |
| 630 if (ssrc_ != rtcp_field->fir_item.ssrc) | 612 if (ssrc_ != rtcp_field->fir_item.ssrc) |
| 631 return; | 613 return; |
| 632 | 614 |
| 633 VLOG(2) << "Cast RTCP received FIR on our SSRC " << ssrc_; | 615 VLOG(2) << "Cast RTCP received FIR on our SSRC " << ssrc_; |
| 634 } | 616 } |
| 635 | 617 |
| 636 } // namespace cast | 618 } // namespace cast |
| 637 } // namespace media | 619 } // namespace media |
| OLD | NEW |