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

Side by Side Diff: webrtc/modules/pacing/paced_sender.cc

Issue 1474533006: Fix bug in calculation of averge queue time in paced sender. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Cleanup Created 5 years 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 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 class PacketQueue { 86 class PacketQueue {
87 public: 87 public:
88 explicit PacketQueue(Clock* clock) 88 explicit PacketQueue(Clock* clock)
89 : bytes_(0), 89 : bytes_(0),
90 clock_(clock), 90 clock_(clock),
91 queue_time_sum_(0), 91 queue_time_sum_(0),
92 time_last_updated_(clock_->TimeInMilliseconds()) {} 92 time_last_updated_(clock_->TimeInMilliseconds()) {}
93 virtual ~PacketQueue() {} 93 virtual ~PacketQueue() {}
94 94
95 void Push(const Packet& packet) { 95 void Push(const Packet& packet) {
96 if (!AddToDupeSet(packet)) { 96 if (!AddToDupeSet(packet))
97 return; 97 return;
98 } 98
99 UpdateQueueTime(packet.enqueue_time_ms);
100
99 // Store packet in list, use pointers in priority queue for cheaper moves. 101 // Store packet in list, use pointers in priority queue for cheaper moves.
100 // Packets have a handle to its own iterator in the list, for easy removal 102 // Packets have a handle to its own iterator in the list, for easy removal
101 // when popping from queue. 103 // when popping from queue.
102 packet_list_.push_front(packet); 104 packet_list_.push_front(packet);
103 std::list<Packet>::iterator it = packet_list_.begin(); 105 std::list<Packet>::iterator it = packet_list_.begin();
104 it->this_it = it; // Handle for direct removal from list. 106 it->this_it = it; // Handle for direct removal from list.
105 prio_queue_.push(&(*it)); // Pointer into list. 107 prio_queue_.push(&(*it)); // Pointer into list.
106 bytes_ += packet.bytes; 108 bytes_ += packet.bytes;
107 } 109 }
108 110
(...skipping 18 matching lines...) Expand all
127 129
128 uint64_t SizeInBytes() const { return bytes_; } 130 uint64_t SizeInBytes() const { return bytes_; }
129 131
130 int64_t OldestEnqueueTimeMs() const { 132 int64_t OldestEnqueueTimeMs() const {
131 auto it = packet_list_.rbegin(); 133 auto it = packet_list_.rbegin();
132 if (it == packet_list_.rend()) 134 if (it == packet_list_.rend())
133 return 0; 135 return 0;
134 return it->enqueue_time_ms; 136 return it->enqueue_time_ms;
135 } 137 }
136 138
137 int64_t AverageQueueTimeMs() { 139 void UpdateQueueTime(int64_t timestamp_ms) {
138 int64_t now = clock_->TimeInMilliseconds(); 140 RTC_DCHECK_GE(timestamp_ms, time_last_updated_);
139 RTC_DCHECK_GE(now, time_last_updated_); 141 int64_t delta = timestamp_ms - time_last_updated_;
140 int64_t delta = now - time_last_updated_;
141 queue_time_sum_ += delta * prio_queue_.size(); 142 queue_time_sum_ += delta * prio_queue_.size();
142 time_last_updated_ = now; 143 time_last_updated_ = timestamp_ms;
144 }
145
146 int64_t AverageQueueTimeMs() const {
147 if (prio_queue_.empty())
148 return 0;
143 return queue_time_sum_ / prio_queue_.size(); 149 return queue_time_sum_ / prio_queue_.size();
144 } 150 }
145 151
146 private: 152 private:
147 // Try to add a packet to the set of ssrc/seqno identifiers currently in the 153 // Try to add a packet to the set of ssrc/seqno identifiers currently in the
148 // queue. Return true if inserted, false if this is a duplicate. 154 // queue. Return true if inserted, false if this is a duplicate.
149 bool AddToDupeSet(const Packet& packet) { 155 bool AddToDupeSet(const Packet& packet) {
150 SsrcSeqNoMap::iterator it = dupe_map_.find(packet.ssrc); 156 SsrcSeqNoMap::iterator it = dupe_map_.find(packet.ssrc);
151 if (it == dupe_map_.end()) { 157 if (it == dupe_map_.end()) {
152 // First for this ssrc, just insert. 158 // First for this ssrc, just insert.
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 int64_t PacedSender::QueueInMs() const { 318 int64_t PacedSender::QueueInMs() const {
313 CriticalSectionScoped cs(critsect_.get()); 319 CriticalSectionScoped cs(critsect_.get());
314 320
315 int64_t oldest_packet = packets_->OldestEnqueueTimeMs(); 321 int64_t oldest_packet = packets_->OldestEnqueueTimeMs();
316 if (oldest_packet == 0) 322 if (oldest_packet == 0)
317 return 0; 323 return 0;
318 324
319 return clock_->TimeInMilliseconds() - oldest_packet; 325 return clock_->TimeInMilliseconds() - oldest_packet;
320 } 326 }
321 327
328 int64_t PacedSender::AverageQueueTimeMs() const {
stefan-webrtc 2015/11/25 18:14:22 Can this really be const if we call UpdateQueueTim
sprang_webrtc 2015/11/25 19:40:42 Ehh, yeah.. What am I missing? Why does this compi
stefan-webrtc 2015/11/26 08:02:46 Did you figure out why it works? Should we remove
sprang_webrtc 2015/11/26 08:11:20 Did not figure out why it works. Removed it anyway
329 CriticalSectionScoped cs(critsect_.get());
330 packets_->UpdateQueueTime(clock_->TimeInMilliseconds());
331 return packets_->AverageQueueTimeMs();
332 }
333
322 int64_t PacedSender::TimeUntilNextProcess() { 334 int64_t PacedSender::TimeUntilNextProcess() {
323 CriticalSectionScoped cs(critsect_.get()); 335 CriticalSectionScoped cs(critsect_.get());
324 if (prober_->IsProbing()) { 336 if (prober_->IsProbing()) {
325 int64_t ret = prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds()); 337 int64_t ret = prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds());
326 if (ret >= 0) 338 if (ret >= 0)
327 return ret; 339 return ret;
328 } 340 }
329 int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_; 341 int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_;
330 int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000; 342 int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000;
331 return std::max<int64_t>(kMinPacketLimitMs - elapsed_time_ms, 0); 343 return std::max<int64_t>(kMinPacketLimitMs - elapsed_time_ms, 0);
332 } 344 }
333 345
334 int32_t PacedSender::Process() { 346 int32_t PacedSender::Process() {
335 int64_t now_us = clock_->TimeInMicroseconds(); 347 int64_t now_us = clock_->TimeInMicroseconds();
336 CriticalSectionScoped cs(critsect_.get()); 348 CriticalSectionScoped cs(critsect_.get());
337 int64_t elapsed_time_ms = (now_us - time_last_update_us_ + 500) / 1000; 349 int64_t elapsed_time_ms = (now_us - time_last_update_us_ + 500) / 1000;
338 time_last_update_us_ = now_us; 350 time_last_update_us_ = now_us;
339 if (paused_) 351 if (paused_)
340 return 0; 352 return 0;
341 int target_bitrate_kbps = max_bitrate_kbps_; 353 int target_bitrate_kbps = max_bitrate_kbps_;
342 if (elapsed_time_ms > 0) { 354 if (elapsed_time_ms > 0) {
343 size_t queue_size_bytes = packets_->SizeInBytes(); 355 size_t queue_size_bytes = packets_->SizeInBytes();
344 if (queue_size_bytes > 0) { 356 if (queue_size_bytes > 0) {
345 // Assuming equal size packets and input/output rate, the average packet 357 // Assuming equal size packets and input/output rate, the average packet
346 // has avg_time_left_ms left to get queue_size_bytes out of the queue, if 358 // has avg_time_left_ms left to get queue_size_bytes out of the queue, if
347 // time constraint shall be met. Determine bitrate needed for that. 359 // time constraint shall be met. Determine bitrate needed for that.
360 packets_->UpdateQueueTime(clock_->TimeInMilliseconds());
348 int64_t avg_time_left_ms = std::max<int64_t>( 361 int64_t avg_time_left_ms = std::max<int64_t>(
349 1, kMaxQueueLengthMs - packets_->AverageQueueTimeMs()); 362 1, kMaxQueueLengthMs - packets_->AverageQueueTimeMs());
350 int min_bitrate_needed_kbps = 363 int min_bitrate_needed_kbps =
351 static_cast<int>(queue_size_bytes * 8 / avg_time_left_ms); 364 static_cast<int>(queue_size_bytes * 8 / avg_time_left_ms);
352 if (min_bitrate_needed_kbps > target_bitrate_kbps) 365 if (min_bitrate_needed_kbps > target_bitrate_kbps)
353 target_bitrate_kbps = min_bitrate_needed_kbps; 366 target_bitrate_kbps = min_bitrate_needed_kbps;
354 } 367 }
355 368
356 media_budget_->set_target_rate_kbps(target_bitrate_kbps); 369 media_budget_->set_target_rate_kbps(target_bitrate_kbps);
357 370
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 media_budget_->UseBudget(bytes_sent); 434 media_budget_->UseBudget(bytes_sent);
422 padding_budget_->UseBudget(bytes_sent); 435 padding_budget_->UseBudget(bytes_sent);
423 } 436 }
424 } 437 }
425 438
426 void PacedSender::UpdateBytesPerInterval(int64_t delta_time_ms) { 439 void PacedSender::UpdateBytesPerInterval(int64_t delta_time_ms) {
427 media_budget_->IncreaseBudget(delta_time_ms); 440 media_budget_->IncreaseBudget(delta_time_ms);
428 padding_budget_->IncreaseBudget(delta_time_ms); 441 padding_budget_->IncreaseBudget(delta_time_ms);
429 } 442 }
430 } // namespace webrtc 443 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698