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/transport/pacing/paced_sender.h" | 5 #include "media/cast/transport/pacing/paced_sender.h" |
| 6 | 6 |
| 7 #include "base/big_endian.h" | 7 #include "base/big_endian.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 | 10 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 return is_audio ? media::cast::kAudioPacketRetransmitted | 28 return is_audio ? media::cast::kAudioPacketRetransmitted |
| 29 : media::cast::kVideoPacketRetransmitted; | 29 : media::cast::kVideoPacketRetransmitted; |
| 30 } else { | 30 } else { |
| 31 return is_audio ? media::cast::kAudioPacketSentToNetwork | 31 return is_audio ? media::cast::kAudioPacketSentToNetwork |
| 32 : media::cast::kVideoPacketSentToNetwork; | 32 : media::cast::kVideoPacketSentToNetwork; |
| 33 } | 33 } |
| 34 } | 34 } |
| 35 | 35 |
| 36 } // namespace | 36 } // namespace |
| 37 | 37 |
| 38 | |
| 39 PacketKey PacedPacketSender::MakePacketKey(const base::TimeTicks& ticks, | |
| 40 unsigned int ssrc, | |
| 41 uint16 packet_id) { | |
| 42 return std::make_pair(ticks, std::make_pair(ssrc, packet_id)); | |
| 43 } | |
| 44 | |
| 38 PacedSender::PacedSender( | 45 PacedSender::PacedSender( |
| 39 base::TickClock* clock, | 46 base::TickClock* clock, |
| 40 LoggingImpl* logging, | 47 LoggingImpl* logging, |
| 41 PacketSender* transport, | 48 PacketSender* transport, |
| 42 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) | 49 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) |
| 43 : clock_(clock), | 50 : clock_(clock), |
| 44 logging_(logging), | 51 logging_(logging), |
| 45 transport_(transport), | 52 transport_(transport), |
| 46 transport_task_runner_(transport_task_runner), | 53 transport_task_runner_(transport_task_runner), |
| 47 audio_ssrc_(0), | 54 audio_ssrc_(0), |
| 48 video_ssrc_(0), | 55 video_ssrc_(0), |
| 49 max_burst_size_(kTargetBurstSize), | 56 max_burst_size_(kTargetBurstSize), |
| 50 next_max_burst_size_(kTargetBurstSize), | 57 next_max_burst_size_(kTargetBurstSize), |
| 51 next_next_max_burst_size_(kTargetBurstSize), | 58 next_next_max_burst_size_(kTargetBurstSize), |
| 52 current_burst_size_(0), | 59 current_burst_size_(0), |
| 53 state_(State_Unblocked), | 60 state_(State_Unblocked), |
| 54 weak_factory_(this) { | 61 weak_factory_(this) { |
| 55 } | 62 } |
| 56 | 63 |
| 57 PacedSender::~PacedSender() {} | 64 PacedSender::~PacedSender() {} |
| 58 | 65 |
| 59 void PacedSender::RegisterAudioSsrc(uint32 audio_ssrc) { | 66 void PacedSender::RegisterAudioSsrc(uint32 audio_ssrc) { |
| 60 audio_ssrc_ = audio_ssrc; | 67 audio_ssrc_ = audio_ssrc; |
| 61 } | 68 } |
| 62 | 69 |
| 63 void PacedSender::RegisterVideoSsrc(uint32 video_ssrc) { | 70 void PacedSender::RegisterVideoSsrc(uint32 video_ssrc) { |
| 64 video_ssrc_ = video_ssrc; | 71 video_ssrc_ = video_ssrc; |
| 65 } | 72 } |
| 66 | 73 |
| 67 bool PacedSender::SendPackets(const PacketList& packets) { | 74 bool PacedSender::SendPackets(const SendPacketVector& packets) { |
| 68 if (packets.empty()) { | 75 if (packets.empty()) { |
| 69 return true; | 76 return true; |
| 70 } | 77 } |
| 71 packet_list_.insert(packet_list_.end(), packets.begin(), packets.end()); | 78 for (size_t i = 0; i < packets.size(); i++) { |
| 79 packet_list_[packets[i].first] = | |
| 80 make_pair(PacketType_Normal, packets[i].second); | |
| 81 } | |
| 72 if (state_ == State_Unblocked) { | 82 if (state_ == State_Unblocked) { |
| 73 SendStoredPackets(); | 83 SendStoredPackets(); |
| 74 } | 84 } |
| 75 return true; | 85 return true; |
| 76 } | 86 } |
| 77 | 87 |
| 78 bool PacedSender::ResendPackets(const PacketList& packets) { | 88 bool PacedSender::ResendPackets(const SendPacketVector& packets) { |
| 79 if (packets.empty()) { | 89 if (packets.empty()) { |
| 80 return true; | 90 return true; |
| 81 } | 91 } |
| 82 resend_packet_list_.insert(resend_packet_list_.end(), | 92 for (size_t i = 0; i < packets.size(); i++) { |
| 83 packets.begin(), | 93 packet_list_[packets[i].first] = |
| 84 packets.end()); | 94 make_pair(PacketType_Resend, packets[i].second); |
| 95 } | |
| 85 if (state_ == State_Unblocked) { | 96 if (state_ == State_Unblocked) { |
| 86 SendStoredPackets(); | 97 SendStoredPackets(); |
| 87 } | 98 } |
| 88 return true; | 99 return true; |
| 89 } | 100 } |
| 90 | 101 |
| 91 bool PacedSender::SendRtcpPacket(PacketRef packet) { | 102 bool PacedSender::SendRtcpPacket(unsigned int ssrc, PacketRef packet) { |
| 92 if (state_ == State_TransportBlocked) { | 103 if (state_ == State_TransportBlocked) { |
| 93 | 104 packet_list_[PacedPacketSender::MakePacketKey(base::TimeTicks(), ssrc, 0)] = |
| 94 rtcp_packet_list_.push_back(packet); | 105 make_pair(PacketType_RTCP, packet); |
| 95 } else { | 106 } else { |
| 96 // We pass the RTCP packets straight through. | 107 // We pass the RTCP packets straight through. |
| 97 if (!transport_->SendPacket( | 108 if (!transport_->SendPacket( |
| 98 packet, | 109 packet, |
| 99 base::Bind(&PacedSender::SendStoredPackets, | 110 base::Bind(&PacedSender::SendStoredPackets, |
| 100 weak_factory_.GetWeakPtr()))) { | 111 weak_factory_.GetWeakPtr()))) { |
| 101 state_ = State_TransportBlocked; | 112 state_ = State_TransportBlocked; |
| 102 } | 113 } |
| 103 | 114 |
| 104 } | 115 } |
| 105 return true; | 116 return true; |
| 106 } | 117 } |
| 107 | 118 |
| 108 PacketRef PacedSender::GetNextPacket(PacketType* packet_type) { | 119 PacketRef PacedSender::GetNextPacket(PacketType* packet_type) { |
| 109 PacketRef ret; | 120 std::map<PacketKey, std::pair<PacketType, PacketRef> >::iterator i; |
| 110 if (!rtcp_packet_list_.empty()) { | 121 i = packet_list_.begin(); |
| 111 ret = rtcp_packet_list_.front(); | 122 *packet_type = i->second.first; |
|
miu
2014/04/24 00:09:06
nit: Suggest DCHECK(i != packet_list_.end());
hubbe
2014/04/24 18:36:42
Done.
| |
| 112 rtcp_packet_list_.pop_front(); | 123 PacketRef ret = i->second.second; |
| 113 *packet_type = PacketType_RTCP; | 124 packet_list_.erase(i); |
| 114 } else if (!resend_packet_list_.empty()) { | |
| 115 ret = resend_packet_list_.front(); | |
| 116 resend_packet_list_.pop_front(); | |
| 117 *packet_type = PacketType_Resend; | |
| 118 } else if (!packet_list_.empty()) { | |
| 119 ret = packet_list_.front(); | |
| 120 packet_list_.pop_front(); | |
| 121 *packet_type = PacketType_Normal; | |
| 122 } else { | |
| 123 NOTREACHED(); | |
| 124 } | |
| 125 return ret; | 125 return ret; |
| 126 } | 126 } |
| 127 | 127 |
| 128 bool PacedSender::empty() const { | 128 bool PacedSender::empty() const { |
| 129 return rtcp_packet_list_.empty() && | 129 return packet_list_.empty(); |
| 130 resend_packet_list_.empty() && | |
| 131 packet_list_.empty(); | |
| 132 } | 130 } |
| 133 | 131 |
| 134 size_t PacedSender::size() const { | 132 size_t PacedSender::size() const { |
| 135 return rtcp_packet_list_.size() + | 133 return packet_list_.size(); |
| 136 resend_packet_list_.size() + | |
| 137 packet_list_.size(); | |
| 138 } | 134 } |
| 139 | 135 |
| 140 // This function can be called from three places: | 136 // This function can be called from three places: |
| 141 // 1. User called one of the Send* functions and we were in an unblocked state. | 137 // 1. User called one of the Send* functions and we were in an unblocked state. |
| 142 // 2. state_ == State_TransportBlocked and the transport is calling us to | 138 // 2. state_ == State_TransportBlocked and the transport is calling us to |
| 143 // let us know that it's ok to send again. | 139 // let us know that it's ok to send again. |
| 144 // 3. state_ == State_BurstFull and there are still packets to send. In this | 140 // 3. state_ == State_BurstFull and there are still packets to send. In this |
| 145 // case we called PostDelayedTask on this function to start a new burst. | 141 // case we called PostDelayedTask on this function to start a new burst. |
| 146 void PacedSender::SendStoredPackets() { | 142 void PacedSender::SendStoredPackets() { |
| 147 State previous_state = state_; | 143 State previous_state = state_; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 } | 232 } |
| 237 | 233 |
| 238 CastLoggingEvent event = GetLoggingEvent(is_audio, retransmit); | 234 CastLoggingEvent event = GetLoggingEvent(is_audio, retransmit); |
| 239 | 235 |
| 240 logging_->InsertSinglePacketEvent(clock_->NowTicks(), event, packet); | 236 logging_->InsertSinglePacketEvent(clock_->NowTicks(), event, packet); |
| 241 } | 237 } |
| 242 | 238 |
| 243 } // namespace transport | 239 } // namespace transport |
| 244 } // namespace cast | 240 } // namespace cast |
| 245 } // namespace media | 241 } // namespace media |
| OLD | NEW |