blob: 323cafec20dd360fc3250e0282fa0649521a9b22 [file] [log] [blame]
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/pacing/include/paced_sender.h"
12
13#include <assert.h>
14
pbos@webrtc.org03c817e2014-07-07 10:20:35 +000015#include <map>
16#include <set>
17
pwestin@webrtc.org52b4e882013-05-02 19:02:17 +000018#include "webrtc/modules/interface/module_common_types.h"
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +000019#include "webrtc/system_wrappers/interface/clock.h"
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000020#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
pwestin@webrtc.org52b4e882013-05-02 19:02:17 +000021#include "webrtc/system_wrappers/interface/trace_event.h"
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000022
23namespace {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000024// Time limit in milliseconds between packet bursts.
25const int kMinPacketLimitMs = 5;
26
27// Upper cap on process interval, in case process has not been called in a long
28// time.
29const int kMaxIntervalTimeMs = 30;
30
31// Max time that the first packet in the queue can sit in the queue if no
32// packets are sent, regardless of buffer state. In practice only in effect at
33// low bitrates (less than 320 kbits/s).
34const int kMaxQueueTimeWithoutSendingMs = 30;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000035
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000036} // namespace
37
38namespace webrtc {
39
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000040namespace paced_sender {
41struct Packet {
pbos@webrtc.org03c817e2014-07-07 10:20:35 +000042 Packet(uint32_t ssrc,
43 uint16_t seq_number,
44 int64_t capture_time_ms,
45 int64_t enqueue_time_ms,
46 int length_in_bytes,
47 bool retransmission)
48 : ssrc(ssrc),
49 sequence_number(seq_number),
50 capture_time_ms(capture_time_ms),
51 enqueue_time_ms(enqueue_time_ms),
52 bytes(length_in_bytes),
53 retransmission(retransmission) {}
54 uint32_t ssrc;
55 uint16_t sequence_number;
56 int64_t capture_time_ms;
57 int64_t enqueue_time_ms;
58 int bytes;
59 bool retransmission;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000060};
61
62// STL list style class which prevents duplicates in the list.
63class PacketList {
64 public:
65 PacketList() {};
66
67 bool empty() const {
68 return packet_list_.empty();
69 }
70
71 Packet front() const {
72 return packet_list_.front();
73 }
74
75 void pop_front() {
76 Packet& packet = packet_list_.front();
pbos@webrtc.org03c817e2014-07-07 10:20:35 +000077 uint16_t sequence_number = packet.sequence_number;
78 uint32_t ssrc = packet.ssrc;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000079 packet_list_.pop_front();
pbos@webrtc.org03c817e2014-07-07 10:20:35 +000080 sequence_number_set_[ssrc].erase(sequence_number);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000081 }
82
83 void push_back(const Packet& packet) {
pbos@webrtc.org03c817e2014-07-07 10:20:35 +000084 if (sequence_number_set_[packet.ssrc].find(packet.sequence_number) ==
85 sequence_number_set_[packet.ssrc].end()) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000086 // Don't insert duplicates.
87 packet_list_.push_back(packet);
pbos@webrtc.org03c817e2014-07-07 10:20:35 +000088 sequence_number_set_[packet.ssrc].insert(packet.sequence_number);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000089 }
90 }
91
92 private:
93 std::list<Packet> packet_list_;
pbos@webrtc.org03c817e2014-07-07 10:20:35 +000094 std::map<uint32_t, std::set<uint16_t> > sequence_number_set_;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000095};
96
97class IntervalBudget {
98 public:
99 explicit IntervalBudget(int initial_target_rate_kbps)
100 : target_rate_kbps_(initial_target_rate_kbps),
101 bytes_remaining_(0) {}
102
103 void set_target_rate_kbps(int target_rate_kbps) {
104 target_rate_kbps_ = target_rate_kbps;
105 }
106
107 void IncreaseBudget(int delta_time_ms) {
108 int bytes = target_rate_kbps_ * delta_time_ms / 8;
109 if (bytes_remaining_ < 0) {
110 // We overused last interval, compensate this interval.
111 bytes_remaining_ = bytes_remaining_ + bytes;
112 } else {
113 // If we underused last interval we can't use it this interval.
114 bytes_remaining_ = bytes;
115 }
116 }
117
118 void UseBudget(int bytes) {
119 bytes_remaining_ = std::max(bytes_remaining_ - bytes,
stefan@webrtc.orgef2d5542013-11-21 14:37:11 +0000120 -500 * target_rate_kbps_ / 8);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000121 }
122
123 int bytes_remaining() const { return bytes_remaining_; }
124
125 private:
126 int target_rate_kbps_;
127 int bytes_remaining_;
128};
129} // namespace paced_sender
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000130
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000131const float PacedSender::kDefaultPaceMultiplier = 2.5f;
132
133PacedSender::PacedSender(Clock* clock,
134 Callback* callback,
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000135 int max_bitrate_kbps,
136 int min_bitrate_kbps)
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000137 : clock_(clock),
138 callback_(callback),
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000139 critsect_(CriticalSectionWrapper::CreateCriticalSection()),
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000140 enabled_(true),
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000141 paused_(false),
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000142 max_queue_length_ms_(kDefaultMaxQueueLengthMs),
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000143 media_budget_(new paced_sender::IntervalBudget(max_bitrate_kbps)),
144 padding_budget_(new paced_sender::IntervalBudget(min_bitrate_kbps)),
stefan@webrtc.org875ad492014-07-04 15:27:55 +0000145 time_last_update_(TickTime::Now()),
pwestin@webrtc.org52b4e882013-05-02 19:02:17 +0000146 capture_time_ms_last_queued_(0),
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000147 capture_time_ms_last_sent_(0),
148 high_priority_packets_(new paced_sender::PacketList),
149 normal_priority_packets_(new paced_sender::PacketList),
150 low_priority_packets_(new paced_sender::PacketList) {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000151 UpdateBytesPerInterval(kMinPacketLimitMs);
152}
153
154PacedSender::~PacedSender() {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000155}
156
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000157void PacedSender::Pause() {
158 CriticalSectionScoped cs(critsect_.get());
159 paused_ = true;
160}
161
162void PacedSender::Resume() {
163 CriticalSectionScoped cs(critsect_.get());
164 paused_ = false;
165}
166
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000167void PacedSender::SetStatus(bool enable) {
168 CriticalSectionScoped cs(critsect_.get());
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000169 enabled_ = enable;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000170}
171
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000172bool PacedSender::Enabled() const {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000173 CriticalSectionScoped cs(critsect_.get());
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000174 return enabled_;
175}
176
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000177void PacedSender::UpdateBitrate(int max_bitrate_kbps,
178 int min_bitrate_kbps) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000179 CriticalSectionScoped cs(critsect_.get());
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000180 media_budget_->set_target_rate_kbps(max_bitrate_kbps);
181 padding_budget_->set_target_rate_kbps(min_bitrate_kbps);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000182}
183
184bool PacedSender::SendPacket(Priority priority, uint32_t ssrc,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000185 uint16_t sequence_number, int64_t capture_time_ms, int bytes,
186 bool retransmission) {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000187 CriticalSectionScoped cs(critsect_.get());
188
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000189 if (!enabled_) {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000190 return true; // We can send now.
191 }
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000192 if (capture_time_ms < 0) {
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000193 capture_time_ms = clock_->TimeInMilliseconds();
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000194 }
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000195 if (priority != kHighPriority &&
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000196 capture_time_ms > capture_time_ms_last_queued_) {
197 capture_time_ms_last_queued_ = capture_time_ms;
198 TRACE_EVENT_ASYNC_BEGIN1("webrtc_rtp", "PacedSend", capture_time_ms,
199 "capture_time_ms", capture_time_ms);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000200 }
stefan@webrtc.org8ad3ec92013-06-04 09:52:46 +0000201 paced_sender::PacketList* packet_list = NULL;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000202 switch (priority) {
203 case kHighPriority:
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000204 packet_list = high_priority_packets_.get();
205 break;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000206 case kNormalPriority:
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000207 packet_list = normal_priority_packets_.get();
208 break;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000209 case kLowPriority:
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000210 packet_list = low_priority_packets_.get();
211 break;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000212 }
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000213 packet_list->push_back(paced_sender::Packet(ssrc,
214 sequence_number,
215 capture_time_ms,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000216 clock_->TimeInMilliseconds(),
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000217 bytes,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000218 retransmission));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000219 return false;
220}
221
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000222void PacedSender::set_max_queue_length_ms(int max_queue_length_ms) {
223 CriticalSectionScoped cs(critsect_.get());
224 max_queue_length_ms_ = max_queue_length_ms;
225}
226
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000227int PacedSender::QueueInMs() const {
228 CriticalSectionScoped cs(critsect_.get());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000229 int64_t now_ms = clock_->TimeInMilliseconds();
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000230 int64_t oldest_packet_enqueue_time = now_ms;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000231 if (!high_priority_packets_->empty()) {
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000232 oldest_packet_enqueue_time =
233 std::min(oldest_packet_enqueue_time,
234 high_priority_packets_->front().enqueue_time_ms);
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000235 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000236 if (!normal_priority_packets_->empty()) {
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000237 oldest_packet_enqueue_time =
238 std::min(oldest_packet_enqueue_time,
239 normal_priority_packets_->front().enqueue_time_ms);
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000240 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000241 if (!low_priority_packets_->empty()) {
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000242 oldest_packet_enqueue_time =
243 std::min(oldest_packet_enqueue_time,
244 low_priority_packets_->front().enqueue_time_ms);
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000245 }
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000246 return now_ms - oldest_packet_enqueue_time;
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000247}
248
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000249int32_t PacedSender::TimeUntilNextProcess() {
250 CriticalSectionScoped cs(critsect_.get());
251 int64_t elapsed_time_ms =
stefan@webrtc.org875ad492014-07-04 15:27:55 +0000252 (TickTime::Now() - time_last_update_).Milliseconds();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000253 if (elapsed_time_ms <= 0) {
254 return kMinPacketLimitMs;
255 }
256 if (elapsed_time_ms >= kMinPacketLimitMs) {
257 return 0;
258 }
259 return kMinPacketLimitMs - elapsed_time_ms;
260}
261
262int32_t PacedSender::Process() {
stefan@webrtc.org875ad492014-07-04 15:27:55 +0000263 TickTime now = TickTime::Now();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000264 CriticalSectionScoped cs(critsect_.get());
stefan@webrtc.org875ad492014-07-04 15:27:55 +0000265 int elapsed_time_ms = (now - time_last_update_).Milliseconds();
266 time_last_update_ = now;
stefan@webrtc.org80865fd2013-08-09 11:31:23 +0000267 if (!enabled_) {
268 return 0;
269 }
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000270 if (!paused_) {
271 if (elapsed_time_ms > 0) {
272 uint32_t delta_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms);
273 UpdateBytesPerInterval(delta_time_ms);
274 }
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000275 paced_sender::PacketList* packet_list;
276 while (ShouldSendNextPacket(&packet_list)) {
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000277 if (!SendPacketFromList(packet_list))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000278 return 0;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000279 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000280 if (high_priority_packets_->empty() &&
281 normal_priority_packets_->empty() &&
282 low_priority_packets_->empty() &&
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000283 padding_budget_->bytes_remaining() > 0) {
284 int padding_needed = padding_budget_->bytes_remaining();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000285 critsect_->Leave();
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000286 int bytes_sent = callback_->TimeToSendPadding(padding_needed);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000287 critsect_->Enter();
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000288 media_budget_->UseBudget(bytes_sent);
289 padding_budget_->UseBudget(bytes_sent);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000290 }
291 }
292 return 0;
293}
294
295// MUST have critsect_ when calling.
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000296bool PacedSender::SendPacketFromList(paced_sender::PacketList* packet_list)
elham@webrtc.org32c32472014-01-21 16:16:58 +0000297 EXCLUSIVE_LOCKS_REQUIRED(critsect_.get()) {
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000298 paced_sender::Packet packet = GetNextPacketFromList(packet_list);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000299 critsect_->Leave();
300
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000301 const bool success = callback_->TimeToSendPacket(packet.ssrc,
302 packet.sequence_number,
303 packet.capture_time_ms,
304 packet.retransmission);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000305 critsect_->Enter();
306 // If packet cannot be sent then keep it in packet list and exit early.
307 // There's no need to send more packets.
308 if (!success) {
309 return false;
310 }
311 packet_list->pop_front();
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000312 const bool last_packet =
313 packet_list->empty() ||
314 packet_list->front().capture_time_ms > packet.capture_time_ms;
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000315 if (packet_list != high_priority_packets_.get()) {
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000316 if (packet.capture_time_ms > capture_time_ms_last_sent_) {
317 capture_time_ms_last_sent_ = packet.capture_time_ms;
318 } else if (packet.capture_time_ms == capture_time_ms_last_sent_ &&
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000319 last_packet) {
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000320 TRACE_EVENT_ASYNC_END0("webrtc_rtp", "PacedSend", packet.capture_time_ms);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000321 }
322 }
323 return true;
324}
325
326// MUST have critsect_ when calling.
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000327void PacedSender::UpdateBytesPerInterval(uint32_t delta_time_ms) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000328 media_budget_->IncreaseBudget(delta_time_ms);
329 padding_budget_->IncreaseBudget(delta_time_ms);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000330}
331
332// MUST have critsect_ when calling.
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000333bool PacedSender::ShouldSendNextPacket(paced_sender::PacketList** packet_list) {
stefan@webrtc.orgb627f672013-11-28 14:00:09 +0000334 *packet_list = NULL;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000335 if (media_budget_->bytes_remaining() <= 0) {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000336 // All bytes consumed for this interval.
337 // Check if we have not sent in a too long time.
stefan@webrtc.org875ad492014-07-04 15:27:55 +0000338 if ((TickTime::Now() - time_last_send_).Milliseconds() >
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000339 kMaxQueueTimeWithoutSendingMs) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000340 if (!high_priority_packets_->empty()) {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000341 *packet_list = high_priority_packets_.get();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000342 return true;
343 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000344 if (!normal_priority_packets_->empty()) {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000345 *packet_list = normal_priority_packets_.get();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000346 return true;
347 }
348 }
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000349 // Send any old packets to avoid queuing for too long.
350 if (max_queue_length_ms_ >= 0 && QueueInMs() > max_queue_length_ms_) {
351 int64_t high_priority_capture_time = -1;
352 if (!high_priority_packets_->empty()) {
353 high_priority_capture_time =
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000354 high_priority_packets_->front().capture_time_ms;
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000355 *packet_list = high_priority_packets_.get();
356 }
stefan@webrtc.orgb627f672013-11-28 14:00:09 +0000357 if (!normal_priority_packets_->empty() &&
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000358 (high_priority_capture_time == -1 ||
359 high_priority_capture_time >
360 normal_priority_packets_->front().capture_time_ms)) {
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000361 *packet_list = normal_priority_packets_.get();
362 }
363 if (*packet_list)
364 return true;
365 }
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000366 return false;
367 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000368 if (!high_priority_packets_->empty()) {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000369 *packet_list = high_priority_packets_.get();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000370 return true;
371 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000372 if (!normal_priority_packets_->empty()) {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000373 *packet_list = normal_priority_packets_.get();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000374 return true;
375 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000376 if (!low_priority_packets_->empty()) {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000377 *packet_list = low_priority_packets_.get();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000378 return true;
379 }
380 return false;
381}
382
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000383paced_sender::Packet PacedSender::GetNextPacketFromList(
384 paced_sender::PacketList* packets) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000385 paced_sender::Packet packet = packets->front();
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000386 UpdateMediaBytesSent(packet.bytes);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000387 return packet;
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000388}
389
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000390// MUST have critsect_ when calling.
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000391void PacedSender::UpdateMediaBytesSent(int num_bytes) {
stefan@webrtc.org875ad492014-07-04 15:27:55 +0000392 time_last_send_ = TickTime::Now();
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000393 media_budget_->UseBudget(num_bytes);
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000394 padding_budget_->UseBudget(num_bytes);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000395}
396
397} // namespace webrtc