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

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

Issue 567853002: Cast: Make pacing controllable by the extension (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: forgot to fix test files Created 6 years, 3 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
« no previous file with comments | « media/cast/net/pacing/paced_sender.h ('k') | media/cast/net/pacing/paced_sender_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/net/pacing/paced_sender.h" 5 #include "media/cast/net/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 #include "media/cast/logging/logging_impl.h" 10 #include "media/cast/logging/logging_impl.h"
11 11
12 namespace media { 12 namespace media {
13 namespace cast { 13 namespace cast {
14 14
15 namespace { 15 namespace {
16 16
17 static const int64 kPacingIntervalMs = 10; 17 static const int64 kPacingIntervalMs = 10;
18 // Each frame will be split into no more than kPacingMaxBurstsPerFrame 18 // Each frame will be split into no more than kPacingMaxBurstsPerFrame
19 // bursts of packets. 19 // bursts of packets.
20 static const size_t kPacingMaxBurstsPerFrame = 3; 20 static const size_t kPacingMaxBurstsPerFrame = 3;
21 static const size_t kTargetBurstSize = 10;
22 static const size_t kMaxBurstSize = 20;
23 static const size_t kMaxDedupeWindowMs = 500; 21 static const size_t kMaxDedupeWindowMs = 500;
24 22
25 // Number of packets that we keep the information of sent time and sent bytes.
26 // This number allows 0.5 seconds of history if sending at maximum rate.
27 static const size_t kPacketHistorySize =
28 kMaxBurstSize * kMaxDedupeWindowMs / kPacingIntervalMs;
29
30 } // namespace 23 } // namespace
31 24
32 DedupInfo::DedupInfo() : last_byte_acked_for_audio(0) {} 25 DedupInfo::DedupInfo() : last_byte_acked_for_audio(0) {}
33 26
34 // static 27 // static
35 PacketKey PacedPacketSender::MakePacketKey(const base::TimeTicks& ticks, 28 PacketKey PacedPacketSender::MakePacketKey(const base::TimeTicks& ticks,
36 uint32 ssrc, 29 uint32 ssrc,
37 uint16 packet_id) { 30 uint16 packet_id) {
38 return std::make_pair(ticks, std::make_pair(ssrc, packet_id)); 31 return std::make_pair(ticks, std::make_pair(ssrc, packet_id));
39 } 32 }
40 33
41 PacedSender::PacketSendRecord::PacketSendRecord() 34 PacedSender::PacketSendRecord::PacketSendRecord()
42 : last_byte_sent(0), last_byte_sent_for_audio(0) {} 35 : last_byte_sent(0), last_byte_sent_for_audio(0) {}
43 36
44 PacedSender::PacedSender( 37 PacedSender::PacedSender(
38 size_t target_burst_size,
39 size_t max_burst_size,
45 base::TickClock* clock, 40 base::TickClock* clock,
46 LoggingImpl* logging, 41 LoggingImpl* logging,
47 PacketSender* transport, 42 PacketSender* transport,
48 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) 43 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner)
49 : clock_(clock), 44 : clock_(clock),
50 logging_(logging), 45 logging_(logging),
51 transport_(transport), 46 transport_(transport),
52 transport_task_runner_(transport_task_runner), 47 transport_task_runner_(transport_task_runner),
53 audio_ssrc_(0), 48 audio_ssrc_(0),
54 video_ssrc_(0), 49 video_ssrc_(0),
55 max_burst_size_(kTargetBurstSize), 50 target_burst_size_(target_burst_size),
56 next_max_burst_size_(kTargetBurstSize), 51 max_burst_size_(max_burst_size),
57 next_next_max_burst_size_(kTargetBurstSize), 52 current_max_burst_size_(target_burst_size_),
53 next_max_burst_size_(target_burst_size_),
54 next_next_max_burst_size_(target_burst_size_),
58 current_burst_size_(0), 55 current_burst_size_(0),
59 state_(State_Unblocked), 56 state_(State_Unblocked),
60 weak_factory_(this) { 57 weak_factory_(this) {
61 } 58 }
62 59
63 PacedSender::~PacedSender() {} 60 PacedSender::~PacedSender() {}
64 61
65 void PacedSender::RegisterAudioSsrc(uint32 audio_ssrc) { 62 void PacedSender::RegisterAudioSsrc(uint32 audio_ssrc) {
66 audio_ssrc_ = audio_ssrc; 63 audio_ssrc_ = audio_ssrc;
67 } 64 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 // three bursts, while trying to keep the burst size below 10 if possible. 235 // three bursts, while trying to keep the burst size below 10 if possible.
239 // We have some evidence that sending more than 12 packets in a row doesn't 236 // We have some evidence that sending more than 12 packets in a row doesn't
240 // work very well, but we don't actually know why yet. Sending out packets 237 // work very well, but we don't actually know why yet. Sending out packets
241 // sooner is better than sending out packets later as that gives us more 238 // sooner is better than sending out packets later as that gives us more
242 // time to re-send them if needed. So if we have less than 30 packets, just 239 // time to re-send them if needed. So if we have less than 30 packets, just
243 // send 10 at a time. If we have less than 60 packets, send n / 3 at a time. 240 // send 10 at a time. If we have less than 60 packets, send n / 3 at a time.
244 // if we have more than 60, we send 20 at a time. 20 packets is ~24Mbit/s 241 // if we have more than 60, we send 20 at a time. 20 packets is ~24Mbit/s
245 // which is more bandwidth than the cast library should need, and sending 242 // which is more bandwidth than the cast library should need, and sending
246 // out more data per second is unlikely to be helpful. 243 // out more data per second is unlikely to be helpful.
247 size_t max_burst_size = std::min( 244 size_t max_burst_size = std::min(
248 kMaxBurstSize, 245 max_burst_size_,
249 std::max(kTargetBurstSize, size() / kPacingMaxBurstsPerFrame)); 246 std::max(target_burst_size_, size() / kPacingMaxBurstsPerFrame));
250 247
251 // If the queue is long, issue a warning. Try to limit the number of 248 // If the queue is long, issue a warning. Try to limit the number of
252 // warnings issued by only issuing the warning when the burst size 249 // warnings issued by only issuing the warning when the burst size
253 // grows. Otherwise we might get 100 warnings per second. 250 // grows. Otherwise we might get 100 warnings per second.
254 if (max_burst_size > next_next_max_burst_size_ && size() > 100) { 251 if (max_burst_size > next_next_max_burst_size_ && size() > 100) {
255 LOG(WARNING) << "Packet queue is very long:" << size(); 252 LOG(WARNING) << "Packet queue is very long:" << size();
256 } 253 }
257 254
258 max_burst_size_ = std::max(next_max_burst_size_, max_burst_size); 255 current_max_burst_size_ = std::max(next_max_burst_size_, max_burst_size);
259 next_max_burst_size_ = std::max(next_next_max_burst_size_, max_burst_size); 256 next_max_burst_size_ = std::max(next_next_max_burst_size_, max_burst_size);
260 next_next_max_burst_size_ = max_burst_size; 257 next_next_max_burst_size_ = max_burst_size;
261 } 258 }
262 259
263 base::Closure cb = base::Bind(&PacedSender::SendStoredPackets, 260 base::Closure cb = base::Bind(&PacedSender::SendStoredPackets,
264 weak_factory_.GetWeakPtr()); 261 weak_factory_.GetWeakPtr());
265 while (!empty()) { 262 while (!empty()) {
266 if (current_burst_size_ >= max_burst_size_) { 263 if (current_burst_size_ >= current_max_burst_size_) {
267 transport_task_runner_->PostDelayedTask(FROM_HERE, 264 transport_task_runner_->PostDelayedTask(FROM_HERE,
268 cb, 265 cb,
269 burst_end_ - now); 266 burst_end_ - now);
270 state_ = State_BurstFull; 267 state_ = State_BurstFull;
271 return; 268 return;
272 } 269 }
273 PacketType packet_type; 270 PacketType packet_type;
274 PacketKey packet_key; 271 PacketKey packet_key;
275 PacketRef packet = PopNextPacket(&packet_type, &packet_key); 272 PacketRef packet = PopNextPacket(&packet_type, &packet_key);
276 PacketSendRecord send_record; 273 PacketSendRecord send_record;
(...skipping 20 matching lines...) Expand all
297 last_byte_sent_[packet_key.second.first] = send_record.last_byte_sent; 294 last_byte_sent_[packet_key.second.first] = send_record.last_byte_sent;
298 295
299 if (socket_blocked) { 296 if (socket_blocked) {
300 state_ = State_TransportBlocked; 297 state_ = State_TransportBlocked;
301 return; 298 return;
302 } 299 }
303 current_burst_size_++; 300 current_burst_size_++;
304 } 301 }
305 302
306 // Keep ~0.5 seconds of data (1000 packets). 303 // Keep ~0.5 seconds of data (1000 packets).
307 if (send_history_buffer_.size() >= kPacketHistorySize) { 304 if (send_history_buffer_.size() >=
305 max_burst_size_ * kMaxDedupeWindowMs / kPacingIntervalMs) {
308 send_history_.swap(send_history_buffer_); 306 send_history_.swap(send_history_buffer_);
309 send_history_buffer_.clear(); 307 send_history_buffer_.clear();
310 } 308 }
311 DCHECK_LE(send_history_buffer_.size(), kPacketHistorySize); 309 DCHECK_LE(send_history_buffer_.size(),
310 max_burst_size_ * kMaxDedupeWindowMs / kPacingIntervalMs);
312 state_ = State_Unblocked; 311 state_ = State_Unblocked;
313 } 312 }
314 313
315 void PacedSender::LogPacketEvent(const Packet& packet, CastLoggingEvent event) { 314 void PacedSender::LogPacketEvent(const Packet& packet, CastLoggingEvent event) {
316 // Get SSRC from packet and compare with the audio_ssrc / video_ssrc to see 315 // Get SSRC from packet and compare with the audio_ssrc / video_ssrc to see
317 // if the packet is audio or video. 316 // if the packet is audio or video.
318 DCHECK_GE(packet.size(), 12u); 317 DCHECK_GE(packet.size(), 12u);
319 base::BigEndianReader reader(reinterpret_cast<const char*>(&packet[8]), 4); 318 base::BigEndianReader reader(reinterpret_cast<const char*>(&packet[8]), 4);
320 uint32 ssrc; 319 uint32 ssrc;
321 bool success = reader.ReadU32(&ssrc); 320 bool success = reader.ReadU32(&ssrc);
322 DCHECK(success); 321 DCHECK(success);
323 bool is_audio; 322 bool is_audio;
324 if (ssrc == audio_ssrc_) { 323 if (ssrc == audio_ssrc_) {
325 is_audio = true; 324 is_audio = true;
326 } else if (ssrc == video_ssrc_) { 325 } else if (ssrc == video_ssrc_) {
327 is_audio = false; 326 is_audio = false;
328 } else { 327 } else {
329 DVLOG(3) << "Got unknown ssrc " << ssrc << " when logging packet event"; 328 DVLOG(3) << "Got unknown ssrc " << ssrc << " when logging packet event";
330 return; 329 return;
331 } 330 }
332 331
333 EventMediaType media_type = is_audio ? AUDIO_EVENT : VIDEO_EVENT; 332 EventMediaType media_type = is_audio ? AUDIO_EVENT : VIDEO_EVENT;
334 logging_->InsertSinglePacketEvent(clock_->NowTicks(), event, media_type, 333 logging_->InsertSinglePacketEvent(clock_->NowTicks(), event, media_type,
335 packet); 334 packet);
336 } 335 }
337 336
338 } // namespace cast 337 } // namespace cast
339 } // namespace media 338 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/net/pacing/paced_sender.h ('k') | media/cast/net/pacing/paced_sender_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698