Report errors from ChromiumEnv::GetChildren in Posix.
[chromium-blink-merge.git] / media / cast / pacing / paced_sender.cc
blob4abda9bd0b891ecca55b57e8d524ba08e88bd2f9
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
3 // found in the LICENSE file.
5 #include "media/cast/pacing/paced_sender.h"
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
10 namespace media {
11 namespace cast {
13 static const int64 kPacingIntervalMs = 10;
14 // Each frame will be split into no more than kPacingMaxBurstsPerFrame
15 // bursts of packets.
16 static const size_t kPacingMaxBurstsPerFrame = 3;
18 PacedSender::PacedSender(scoped_refptr<CastEnvironment> cast_environment,
19 PacketSender* transport)
20 : cast_environment_(cast_environment),
21 burst_size_(1),
22 packets_sent_in_burst_(0),
23 transport_(transport),
24 weak_factory_(this) {
25 ScheduleNextSend();
28 PacedSender::~PacedSender() {}
30 bool PacedSender::SendPackets(const PacketList& packets) {
31 return SendPacketsToTransport(packets, &packet_list_);
34 bool PacedSender::ResendPackets(const PacketList& packets) {
35 return SendPacketsToTransport(packets, &resend_packet_list_);
38 bool PacedSender::SendPacketsToTransport(const PacketList& packets,
39 PacketList* packets_not_sent) {
40 UpdateBurstSize(packets.size());
42 if (!packets_not_sent->empty()) {
43 packets_not_sent->insert(packets_not_sent->end(),
44 packets.begin(), packets.end());
45 return true;
47 PacketList packets_to_send;
48 PacketList::const_iterator first_to_store_it = packets.begin();
50 size_t max_packets_to_send_now = burst_size_ - packets_sent_in_burst_;
51 if (max_packets_to_send_now > 0) {
52 size_t packets_to_send_now = std::min(max_packets_to_send_now,
53 packets.size());
55 std::advance(first_to_store_it, packets_to_send_now);
56 packets_to_send.insert(packets_to_send.begin(),
57 packets.begin(), first_to_store_it);
59 packets_not_sent->insert(packets_not_sent->end(),
60 first_to_store_it, packets.end());
61 packets_sent_in_burst_ += packets_to_send.size();
62 if (packets_to_send.empty()) return true;
64 return transport_->SendPackets(packets_to_send);
67 bool PacedSender::SendRtcpPacket(const Packet& packet) {
68 // We pass the RTCP packets straight through.
69 return transport_->SendPacket(packet);
72 void PacedSender::ScheduleNextSend() {
73 base::TimeDelta time_to_next = time_last_process_ -
74 cast_environment_->Clock()->NowTicks() +
75 base::TimeDelta::FromMilliseconds(kPacingIntervalMs);
77 time_to_next = std::max(time_to_next, base::TimeDelta());
79 cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE,
80 base::Bind(&PacedSender::SendNextPacketBurst, weak_factory_.GetWeakPtr()),
81 time_to_next);
84 void PacedSender::SendNextPacketBurst() {
85 SendStoredPackets();
86 time_last_process_ = cast_environment_->Clock()->NowTicks();
87 ScheduleNextSend();
90 void PacedSender::SendStoredPackets() {
91 if (packet_list_.empty() && resend_packet_list_.empty()) return;
93 size_t packets_to_send = burst_size_;
94 PacketList packets_to_resend;
96 // Send our re-send packets first.
97 if (!resend_packet_list_.empty()) {
98 PacketList::iterator it = resend_packet_list_.begin();
99 size_t packets_to_send_now = std::min(packets_to_send,
100 resend_packet_list_.size());
101 std::advance(it, packets_to_send_now);
102 packets_to_resend.insert(packets_to_resend.begin(),
103 resend_packet_list_.begin(), it);
104 resend_packet_list_.erase(resend_packet_list_.begin(), it);
105 packets_to_send -= packets_to_resend.size();
107 if (!packet_list_.empty() && packets_to_send > 0) {
108 PacketList::iterator it = packet_list_.begin();
109 size_t packets_to_send_now = std::min(packets_to_send,
110 packet_list_.size());
112 std::advance(it, packets_to_send_now);
113 packets_to_resend.insert(packets_to_resend.end(),
114 packet_list_.begin(), it);
115 packet_list_.erase(packet_list_.begin(), it);
117 if (packet_list_.empty()) {
118 burst_size_ = 1; // Reset burst size after we sent the last stored packet
119 packets_sent_in_burst_ = 0;
122 transport_->SendPackets(packets_to_resend);
125 void PacedSender::UpdateBurstSize(size_t packets_to_send) {
126 packets_to_send = std::max(packets_to_send,
127 resend_packet_list_.size() + packet_list_.size());
129 packets_to_send += (kPacingMaxBurstsPerFrame - 1); // Round up.
130 burst_size_ = std::max(packets_to_send / kPacingMaxBurstsPerFrame,
131 burst_size_);
134 } // namespace cast
135 } // namespace media