Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: media/cast/transport/pacing/paced_sender.cc

Issue 343523005: Cast: Avoid retransmit if we sent the same packet recently (less than RTT) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: got 500 responses when uploading, uploading again Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 for (size_t i = 0; i < packets.size(); i++) { 66 for (size_t i = 0; i < packets.size(); i++) {
67 packet_list_[packets[i].first] = 67 packet_list_[packets[i].first] =
68 make_pair(PacketType_Normal, packets[i].second); 68 make_pair(PacketType_Normal, packets[i].second);
69 } 69 }
70 if (state_ == State_Unblocked) { 70 if (state_ == State_Unblocked) {
71 SendStoredPackets(); 71 SendStoredPackets();
72 } 72 }
73 return true; 73 return true;
74 } 74 }
75 75
76 bool PacedSender::ResendPackets(const SendPacketVector& packets) { 76 bool PacedSender::ResendPackets(const SendPacketVector& packets,
77 base::TimeDelta rtt) {
78 VLOG(0) << "RESENDPACKETS!!!!!!!";
Alpha Left Google 2014/06/18 01:43:32 This shouldn't be there.
hubbe 2014/06/18 20:22:28 Already gone.
77 if (packets.empty()) { 79 if (packets.empty()) {
78 return true; 80 return true;
79 } 81 }
82 base::TimeTicks now = clock_->NowTicks();
80 for (size_t i = 0; i < packets.size(); i++) { 83 for (size_t i = 0; i < packets.size(); i++) {
84 std::map<PacketKey, base::TimeTicks>::const_iterator j =
85 sent_time_.find(packets[i].first);
86
87 if (j != sent_time_.end() && now - j->second < rtt) {
88 // TODO(hubbe): Log this.
Alpha Left Google 2014/06/18 01:43:32 We should log a PACKET_RTX_REJECTED event in the l
hubbe 2014/06/18 20:22:28 Done.
89 continue;
90 }
91
81 packet_list_[packets[i].first] = 92 packet_list_[packets[i].first] =
82 make_pair(PacketType_Resend, packets[i].second); 93 make_pair(PacketType_Resend, packets[i].second);
83 } 94 }
84 if (state_ == State_Unblocked) { 95 if (state_ == State_Unblocked) {
85 SendStoredPackets(); 96 SendStoredPackets();
86 } 97 }
87 return true; 98 return true;
88 } 99 }
89 100
90 bool PacedSender::SendRtcpPacket(uint32 ssrc, PacketRef packet) { 101 bool PacedSender::SendRtcpPacket(uint32 ssrc, PacketRef packet) {
(...skipping 10 matching lines...) Expand all
101 } 112 }
102 113
103 } 114 }
104 return true; 115 return true;
105 } 116 }
106 117
107 void PacedSender::CancelSendingPacket(const PacketKey& packet_key) { 118 void PacedSender::CancelSendingPacket(const PacketKey& packet_key) {
108 packet_list_.erase(packet_key); 119 packet_list_.erase(packet_key);
109 } 120 }
110 121
111 PacketRef PacedSender::GetNextPacket(PacketType* packet_type) { 122 PacketRef PacedSender::GetNextPacket(PacketType* packet_type,
123 PacketKey* packet_key) {
112 std::map<PacketKey, std::pair<PacketType, PacketRef> >::iterator i; 124 std::map<PacketKey, std::pair<PacketType, PacketRef> >::iterator i;
113 i = packet_list_.begin(); 125 i = packet_list_.begin();
114 DCHECK(i != packet_list_.end()); 126 DCHECK(i != packet_list_.end());
115 *packet_type = i->second.first; 127 *packet_type = i->second.first;
128 *packet_key = i->first;
116 PacketRef ret = i->second.second; 129 PacketRef ret = i->second.second;
117 packet_list_.erase(i); 130 packet_list_.erase(i);
118 return ret; 131 return ret;
119 } 132 }
120 133
121 bool PacedSender::empty() const { 134 bool PacedSender::empty() const {
122 return packet_list_.empty(); 135 return packet_list_.empty();
123 } 136 }
124 137
125 size_t PacedSender::size() const { 138 size_t PacedSender::size() const {
126 return packet_list_.size(); 139 return packet_list_.size();
127 } 140 }
128 141
129 // This function can be called from three places: 142 // This function can be called from three places:
130 // 1. User called one of the Send* functions and we were in an unblocked state. 143 // 1. User called one of the Send* functions and we were in an unblocked state.
131 // 2. state_ == State_TransportBlocked and the transport is calling us to 144 // 2. state_ == State_TransportBlocked and the transport is calling us to
132 // let us know that it's ok to send again. 145 // let us know that it's ok to send again.
133 // 3. state_ == State_BurstFull and there are still packets to send. In this 146 // 3. state_ == State_BurstFull and there are still packets to send. In this
134 // case we called PostDelayedTask on this function to start a new burst. 147 // case we called PostDelayedTask on this function to start a new burst.
135 void PacedSender::SendStoredPackets() { 148 void PacedSender::SendStoredPackets() {
136 State previous_state = state_; 149 State previous_state = state_;
150
151 if (state_ == State_TransportBlocked) {
152 base::TimeTicks sent_time = clock_->NowTicks();
153 sent_time_[in_progress_packet_key_] = sent_time;
154 sent_time_buffer_[in_progress_packet_key_] = sent_time;
155 }
156
137 state_ = State_Unblocked; 157 state_ = State_Unblocked;
138 if (empty()) { 158 if (empty()) {
139 return; 159 return;
140 } 160 }
141 161
142 base::TimeTicks now = clock_->NowTicks(); 162 base::TimeTicks now = clock_->NowTicks();
143 // I don't actually trust that PostDelayTask(x - now) will mean that 163 // I don't actually trust that PostDelayTask(x - now) will mean that
144 // now >= x when the call happens, so check if the previous state was 164 // now >= x when the call happens, so check if the previous state was
145 // State_BurstFull too. 165 // State_BurstFull too.
146 if (now >= burst_end_ || previous_state == State_BurstFull) { 166 if (now >= burst_end_ || previous_state == State_BurstFull) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 weak_factory_.GetWeakPtr()); 198 weak_factory_.GetWeakPtr());
179 while (!empty()) { 199 while (!empty()) {
180 if (current_burst_size_ >= max_burst_size_) { 200 if (current_burst_size_ >= max_burst_size_) {
181 transport_task_runner_->PostDelayedTask(FROM_HERE, 201 transport_task_runner_->PostDelayedTask(FROM_HERE,
182 cb, 202 cb,
183 burst_end_ - now); 203 burst_end_ - now);
184 state_ = State_BurstFull; 204 state_ = State_BurstFull;
185 return; 205 return;
186 } 206 }
187 PacketType packet_type; 207 PacketType packet_type;
188 PacketRef packet = GetNextPacket(&packet_type); 208 PacketRef packet = GetNextPacket(&packet_type,
209 &in_progress_packet_key_);
189 210
190 switch (packet_type) { 211 switch (packet_type) {
191 case PacketType_Resend: 212 case PacketType_Resend:
192 LogPacketEvent(packet->data, true); 213 LogPacketEvent(packet->data, true);
193 break; 214 break;
194 case PacketType_Normal: 215 case PacketType_Normal:
195 LogPacketEvent(packet->data, false); 216 LogPacketEvent(packet->data, false);
196 break; 217 break;
197 case PacketType_RTCP: 218 case PacketType_RTCP:
198 break; 219 break;
199 } 220 }
200 if (!transport_->SendPacket(packet, cb)) { 221 if (!transport_->SendPacket(packet, cb)) {
201 state_ = State_TransportBlocked; 222 state_ = State_TransportBlocked;
202 return; 223 return;
203 } 224 }
204 current_burst_size_++; 225 current_burst_size_++;
226 base::TimeTicks sent_time = clock_->NowTicks();
227 sent_time_[in_progress_packet_key_] = sent_time;
228 sent_time_buffer_[in_progress_packet_key_] = sent_time;
229 }
230 // Keep ~1 second of data (1000 packets)
231 if (sent_time_buffer_.size() > kMaxBurstSize * 1000 / kPacingIntervalMs) {
Alpha Left Google 2014/06/18 01:43:32 nit: Define 1000 as a constant at the top of this
hubbe 2014/06/18 20:22:27 It's just the number of milliseconds in a second.
232 sent_time_.swap(sent_time_buffer_);
233 sent_time_buffer_.clear();
205 } 234 }
206 state_ = State_Unblocked; 235 state_ = State_Unblocked;
Alpha Left Google 2014/06/18 01:43:32 Please put a DCHECK for the sizes of the sent_time
hubbe 2014/06/18 20:22:27 Done.
207 } 236 }
208 237
209 void PacedSender::LogPacketEvent(const Packet& packet, bool retransmit) { 238 void PacedSender::LogPacketEvent(const Packet& packet, bool retransmit) {
210 // Get SSRC from packet and compare with the audio_ssrc / video_ssrc to see 239 // Get SSRC from packet and compare with the audio_ssrc / video_ssrc to see
211 // if the packet is audio or video. 240 // if the packet is audio or video.
212 DCHECK_GE(packet.size(), 12u); 241 DCHECK_GE(packet.size(), 12u);
213 base::BigEndianReader reader(reinterpret_cast<const char*>(&packet[8]), 4); 242 base::BigEndianReader reader(reinterpret_cast<const char*>(&packet[8]), 4);
214 uint32 ssrc; 243 uint32 ssrc;
215 bool success = reader.ReadU32(&ssrc); 244 bool success = reader.ReadU32(&ssrc);
216 DCHECK(success); 245 DCHECK(success);
(...skipping 10 matching lines...) Expand all
227 CastLoggingEvent event = retransmit ? 256 CastLoggingEvent event = retransmit ?
228 PACKET_RETRANSMITTED : PACKET_SENT_TO_NETWORK; 257 PACKET_RETRANSMITTED : PACKET_SENT_TO_NETWORK;
229 EventMediaType media_type = is_audio ? AUDIO_EVENT : VIDEO_EVENT; 258 EventMediaType media_type = is_audio ? AUDIO_EVENT : VIDEO_EVENT;
230 logging_->InsertSinglePacketEvent(clock_->NowTicks(), event, media_type, 259 logging_->InsertSinglePacketEvent(clock_->NowTicks(), event, media_type,
231 packet); 260 packet);
232 } 261 }
233 262
234 } // namespace transport 263 } // namespace transport
235 } // namespace cast 264 } // namespace cast
236 } // namespace media 265 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698