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 |