| OLD | NEW |
| 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 |
| 11 #include "webrtc/modules/pacing/paced_sender.h" | 11 #include "webrtc/modules/pacing/paced_sender.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <map> | |
| 15 #include <queue> | 14 #include <queue> |
| 16 #include <set> | |
| 17 #include <vector> | 15 #include <vector> |
| 18 | 16 |
| 19 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
| 20 #include "webrtc/base/logging.h" | 18 #include "webrtc/base/logging.h" |
| 21 #include "webrtc/modules/include/module_common_types.h" | 19 #include "webrtc/modules/include/module_common_types.h" |
| 22 #include "webrtc/modules/pacing/alr_detector.h" | 20 #include "webrtc/modules/pacing/alr_detector.h" |
| 23 #include "webrtc/modules/pacing/bitrate_prober.h" | 21 #include "webrtc/modules/pacing/bitrate_prober.h" |
| 24 #include "webrtc/modules/utility/include/process_thread.h" | 22 #include "webrtc/modules/utility/include/process_thread.h" |
| 25 #include "webrtc/system_wrappers/include/clock.h" | 23 #include "webrtc/system_wrappers/include/clock.h" |
| 26 #include "webrtc/system_wrappers/include/field_trial.h" | 24 #include "webrtc/system_wrappers/include/field_trial.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 class PacketQueue { | 90 class PacketQueue { |
| 93 public: | 91 public: |
| 94 explicit PacketQueue(const Clock* clock) | 92 explicit PacketQueue(const Clock* clock) |
| 95 : bytes_(0), | 93 : bytes_(0), |
| 96 clock_(clock), | 94 clock_(clock), |
| 97 queue_time_sum_(0), | 95 queue_time_sum_(0), |
| 98 time_last_updated_(clock_->TimeInMilliseconds()) {} | 96 time_last_updated_(clock_->TimeInMilliseconds()) {} |
| 99 virtual ~PacketQueue() {} | 97 virtual ~PacketQueue() {} |
| 100 | 98 |
| 101 void Push(const Packet& packet) { | 99 void Push(const Packet& packet) { |
| 102 if (!AddToDupeSet(packet)) | |
| 103 return; | |
| 104 | |
| 105 UpdateQueueTime(packet.enqueue_time_ms); | 100 UpdateQueueTime(packet.enqueue_time_ms); |
| 106 | 101 |
| 107 // Store packet in list, use pointers in priority queue for cheaper moves. | 102 // Store packet in list, use pointers in priority queue for cheaper moves. |
| 108 // Packets have a handle to its own iterator in the list, for easy removal | 103 // Packets have a handle to its own iterator in the list, for easy removal |
| 109 // when popping from queue. | 104 // when popping from queue. |
| 110 packet_list_.push_front(packet); | 105 packet_list_.push_front(packet); |
| 111 std::list<Packet>::iterator it = packet_list_.begin(); | 106 std::list<Packet>::iterator it = packet_list_.begin(); |
| 112 it->this_it = it; // Handle for direct removal from list. | 107 it->this_it = it; // Handle for direct removal from list. |
| 113 prio_queue_.push(&(*it)); // Pointer into list. | 108 prio_queue_.push(&(*it)); // Pointer into list. |
| 114 bytes_ += packet.bytes; | 109 bytes_ += packet.bytes; |
| 115 } | 110 } |
| 116 | 111 |
| 117 const Packet& BeginPop() { | 112 const Packet& BeginPop() { |
| 118 const Packet& packet = *prio_queue_.top(); | 113 const Packet& packet = *prio_queue_.top(); |
| 119 prio_queue_.pop(); | 114 prio_queue_.pop(); |
| 120 return packet; | 115 return packet; |
| 121 } | 116 } |
| 122 | 117 |
| 123 void CancelPop(const Packet& packet) { prio_queue_.push(&(*packet.this_it)); } | 118 void CancelPop(const Packet& packet) { prio_queue_.push(&(*packet.this_it)); } |
| 124 | 119 |
| 125 void FinalizePop(const Packet& packet) { | 120 void FinalizePop(const Packet& packet) { |
| 126 RemoveFromDupeSet(packet); | |
| 127 bytes_ -= packet.bytes; | 121 bytes_ -= packet.bytes; |
| 128 queue_time_sum_ -= (time_last_updated_ - packet.enqueue_time_ms); | 122 queue_time_sum_ -= (time_last_updated_ - packet.enqueue_time_ms); |
| 129 packet_list_.erase(packet.this_it); | 123 packet_list_.erase(packet.this_it); |
| 130 RTC_DCHECK_EQ(packet_list_.size(), prio_queue_.size()); | 124 RTC_DCHECK_EQ(packet_list_.size(), prio_queue_.size()); |
| 131 if (packet_list_.empty()) | 125 if (packet_list_.empty()) |
| 132 RTC_DCHECK_EQ(0, queue_time_sum_); | 126 RTC_DCHECK_EQ(0, queue_time_sum_); |
| 133 } | 127 } |
| 134 | 128 |
| 135 bool Empty() const { return prio_queue_.empty(); } | 129 bool Empty() const { return prio_queue_.empty(); } |
| 136 | 130 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 155 time_last_updated_ = timestamp_ms; | 149 time_last_updated_ = timestamp_ms; |
| 156 } | 150 } |
| 157 | 151 |
| 158 int64_t AverageQueueTimeMs() const { | 152 int64_t AverageQueueTimeMs() const { |
| 159 if (prio_queue_.empty()) | 153 if (prio_queue_.empty()) |
| 160 return 0; | 154 return 0; |
| 161 return queue_time_sum_ / packet_list_.size(); | 155 return queue_time_sum_ / packet_list_.size(); |
| 162 } | 156 } |
| 163 | 157 |
| 164 private: | 158 private: |
| 165 // Try to add a packet to the set of ssrc/seqno identifiers currently in the | 159 // List of packets, in the order they were enqueued. Since dequeueing may |
| 166 // queue. Return true if inserted, false if this is a duplicate. | |
| 167 bool AddToDupeSet(const Packet& packet) { | |
| 168 SsrcSeqNoMap::iterator it = dupe_map_.find(packet.ssrc); | |
| 169 if (it == dupe_map_.end()) { | |
| 170 // First for this ssrc, just insert. | |
| 171 dupe_map_[packet.ssrc].insert(packet.sequence_number); | |
| 172 return true; | |
| 173 } | |
| 174 | |
| 175 // Insert returns a pair, where second is a bool set to true if new element. | |
| 176 return it->second.insert(packet.sequence_number).second; | |
| 177 } | |
| 178 | |
| 179 void RemoveFromDupeSet(const Packet& packet) { | |
| 180 SsrcSeqNoMap::iterator it = dupe_map_.find(packet.ssrc); | |
| 181 RTC_DCHECK(it != dupe_map_.end()); | |
| 182 it->second.erase(packet.sequence_number); | |
| 183 if (it->second.empty()) { | |
| 184 dupe_map_.erase(it); | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 // List of packets, in the order the were enqueued. Since dequeueing may | |
| 189 // occur out of order, use list instead of vector. | 160 // occur out of order, use list instead of vector. |
| 190 std::list<Packet> packet_list_; | 161 std::list<Packet> packet_list_; |
| 191 // Priority queue of the packets, sorted according to Comparator. | 162 // Priority queue of the packets, sorted according to Comparator. |
| 192 // Use pointers into list, to avoid moving whole struct within heap. | 163 // Use pointers into list, to avoid moving whole struct within heap. |
| 193 std::priority_queue<Packet*, std::vector<Packet*>, Comparator> prio_queue_; | 164 std::priority_queue<Packet*, std::vector<Packet*>, Comparator> prio_queue_; |
| 194 // Total number of bytes in the queue. | 165 // Total number of bytes in the queue. |
| 195 uint64_t bytes_; | 166 uint64_t bytes_; |
| 196 // Map<ssrc, std::set<seq_no> >, for checking duplicates. | |
| 197 typedef std::map<uint32_t, std::set<uint16_t> > SsrcSeqNoMap; | |
| 198 SsrcSeqNoMap dupe_map_; | |
| 199 const Clock* const clock_; | 167 const Clock* const clock_; |
| 200 int64_t queue_time_sum_; | 168 int64_t queue_time_sum_; |
| 201 int64_t time_last_updated_; | 169 int64_t time_last_updated_; |
| 202 }; | 170 }; |
| 203 | 171 |
| 204 class IntervalBudget { | 172 class IntervalBudget { |
| 205 public: | 173 public: |
| 206 explicit IntervalBudget(int initial_target_rate_kbps) | 174 explicit IntervalBudget(int initial_target_rate_kbps) |
| 207 : target_rate_kbps_(initial_target_rate_kbps), | 175 : target_rate_kbps_(initial_target_rate_kbps), |
| 208 bytes_remaining_(0) {} | 176 bytes_remaining_(0) {} |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 void PacedSender::UpdateBudgetWithElapsedTime(int64_t delta_time_ms) { | 497 void PacedSender::UpdateBudgetWithElapsedTime(int64_t delta_time_ms) { |
| 530 media_budget_->IncreaseBudget(delta_time_ms); | 498 media_budget_->IncreaseBudget(delta_time_ms); |
| 531 padding_budget_->IncreaseBudget(delta_time_ms); | 499 padding_budget_->IncreaseBudget(delta_time_ms); |
| 532 } | 500 } |
| 533 | 501 |
| 534 void PacedSender::UpdateBudgetWithBytesSent(size_t bytes_sent) { | 502 void PacedSender::UpdateBudgetWithBytesSent(size_t bytes_sent) { |
| 535 media_budget_->UseBudget(bytes_sent); | 503 media_budget_->UseBudget(bytes_sent); |
| 536 padding_budget_->UseBudget(bytes_sent); | 504 padding_budget_->UseBudget(bytes_sent); |
| 537 } | 505 } |
| 538 } // namespace webrtc | 506 } // namespace webrtc |
| OLD | NEW |