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

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

Issue 1618333002: Temporary hack to avoid assert errors when time moves backwards. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Added comment Created 4 years, 11 months 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 17 matching lines...) Expand all
28 28
29 // Upper cap on process interval, in case process has not been called in a long 29 // Upper cap on process interval, in case process has not been called in a long
30 // time. 30 // time.
31 const int64_t kMaxIntervalTimeMs = 30; 31 const int64_t kMaxIntervalTimeMs = 30;
32 32
33 } // namespace 33 } // namespace
34 34
35 // TODO(sprang): Move at least PacketQueue and MediaBudget out to separate 35 // TODO(sprang): Move at least PacketQueue and MediaBudget out to separate
36 // files, so that we can more easily test them. 36 // files, so that we can more easily test them.
37 37
38 // Note about the -1 enqueue times below:
39 // This is a temporary hack to avoid crashes when the real-time clock is
40 // adjusted backwards, which can happen on Android when the phone syncs the
41 // clock to the network. See this bug:
42 // https://bugs.chromium.org/p/webrtc/issues/detail?id=5452
43 // We can't just comment out the DCHECK either, as that would lead to the sum
44 // being wrong. Instead we just ignore packets from the past when we calculate
45 // the average queue time.
46
38 namespace webrtc { 47 namespace webrtc {
39 namespace paced_sender { 48 namespace paced_sender {
40 struct Packet { 49 struct Packet {
41 Packet(RtpPacketSender::Priority priority, 50 Packet(RtpPacketSender::Priority priority,
42 uint32_t ssrc, 51 uint32_t ssrc,
43 uint16_t seq_number, 52 uint16_t seq_number,
44 int64_t capture_time_ms, 53 int64_t capture_time_ms,
45 int64_t enqueue_time_ms, 54 int64_t enqueue_time_ms,
46 size_t length_in_bytes, 55 size_t length_in_bytes,
47 bool retransmission, 56 bool retransmission,
48 uint64_t enqueue_order) 57 uint64_t enqueue_order)
49 : priority(priority), 58 : priority(priority),
50 ssrc(ssrc), 59 ssrc(ssrc),
51 sequence_number(seq_number), 60 sequence_number(seq_number),
52 capture_time_ms(capture_time_ms), 61 capture_time_ms(capture_time_ms),
53 enqueue_time_ms(enqueue_time_ms), 62 // TODO(sprang): Remove -1 option once we can guarantee monotonic clock.
63 enqueue_time_ms(enqueue_time_ms), // -1 = not valid; don't count.
54 bytes(length_in_bytes), 64 bytes(length_in_bytes),
55 retransmission(retransmission), 65 retransmission(retransmission),
56 enqueue_order(enqueue_order) {} 66 enqueue_order(enqueue_order) {}
57 67
58 RtpPacketSender::Priority priority; 68 RtpPacketSender::Priority priority;
59 uint32_t ssrc; 69 uint32_t ssrc;
60 uint16_t sequence_number; 70 uint16_t sequence_number;
61 int64_t capture_time_ms; 71 int64_t capture_time_ms;
62 int64_t enqueue_time_ms; 72 int64_t enqueue_time_ms;
63 size_t bytes; 73 size_t bytes;
(...skipping 28 matching lines...) Expand all
92 : bytes_(0), 102 : bytes_(0),
93 clock_(clock), 103 clock_(clock),
94 queue_time_sum_(0), 104 queue_time_sum_(0),
95 time_last_updated_(clock_->TimeInMilliseconds()) {} 105 time_last_updated_(clock_->TimeInMilliseconds()) {}
96 virtual ~PacketQueue() {} 106 virtual ~PacketQueue() {}
97 107
98 void Push(const Packet& packet) { 108 void Push(const Packet& packet) {
99 if (!AddToDupeSet(packet)) 109 if (!AddToDupeSet(packet))
100 return; 110 return;
101 111
102 UpdateQueueTime(packet.enqueue_time_ms); 112 if (packet.enqueue_time_ms >= time_last_updated_)
113 UpdateQueueTime(packet.enqueue_time_ms);
103 114
104 // Store packet in list, use pointers in priority queue for cheaper moves. 115 // Store packet in list, use pointers in priority queue for cheaper moves.
105 // Packets have a handle to its own iterator in the list, for easy removal 116 // Packets have a handle to its own iterator in the list, for easy removal
106 // when popping from queue. 117 // when popping from queue.
107 packet_list_.push_front(packet); 118 packet_list_.push_front(packet);
108 std::list<Packet>::iterator it = packet_list_.begin(); 119 std::list<Packet>::iterator it = packet_list_.begin();
120 if (packet.enqueue_time_ms < time_last_updated_)
121 it->enqueue_time_ms = -1;
109 it->this_it = it; // Handle for direct removal from list. 122 it->this_it = it; // Handle for direct removal from list.
110 prio_queue_.push(&(*it)); // Pointer into list. 123 prio_queue_.push(&(*it)); // Pointer into list.
111 bytes_ += packet.bytes; 124 bytes_ += packet.bytes;
112 } 125 }
113 126
114 const Packet& BeginPop() { 127 const Packet& BeginPop() {
115 const Packet& packet = *prio_queue_.top(); 128 const Packet& packet = *prio_queue_.top();
116 prio_queue_.pop(); 129 prio_queue_.pop();
117 return packet; 130 return packet;
118 } 131 }
119 132
120 void CancelPop(const Packet& packet) { prio_queue_.push(&(*packet.this_it)); } 133 void CancelPop(const Packet& packet) { prio_queue_.push(&(*packet.this_it)); }
121 134
122 void FinalizePop(const Packet& packet) { 135 void FinalizePop(const Packet& packet) {
123 RemoveFromDupeSet(packet); 136 RemoveFromDupeSet(packet);
124 bytes_ -= packet.bytes; 137 bytes_ -= packet.bytes;
125 queue_time_sum_ -= (time_last_updated_ - packet.enqueue_time_ms); 138 if (packet.enqueue_time_ms != -1)
139 queue_time_sum_ -= (time_last_updated_ - packet.enqueue_time_ms);
126 packet_list_.erase(packet.this_it); 140 packet_list_.erase(packet.this_it);
127 RTC_DCHECK_EQ(packet_list_.size(), prio_queue_.size()); 141 RTC_DCHECK_EQ(packet_list_.size(), prio_queue_.size());
128 if (packet_list_.empty()) 142 if (packet_list_.empty())
129 RTC_DCHECK_EQ(0u, queue_time_sum_); 143 RTC_DCHECK_EQ(0u, queue_time_sum_);
130 } 144 }
131 145
132 bool Empty() const { return prio_queue_.empty(); } 146 bool Empty() const { return prio_queue_.empty(); }
133 147
134 size_t SizeInPackets() const { return prio_queue_.size(); } 148 size_t SizeInPackets() const { return prio_queue_.size(); }
135 149
136 uint64_t SizeInBytes() const { return bytes_; } 150 uint64_t SizeInBytes() const { return bytes_; }
137 151
138 int64_t OldestEnqueueTimeMs() const { 152 int64_t OldestEnqueueTimeMs() const {
139 auto it = packet_list_.rbegin(); 153 for (auto it = packet_list_.rbegin(); it != packet_list_.rend(); ++it) {
140 if (it == packet_list_.rend()) 154 if (it->enqueue_time_ms != -1)
141 return 0; 155 return it->enqueue_time_ms;
142 return it->enqueue_time_ms; 156 }
157 return 0;
143 } 158 }
144 159
145 void UpdateQueueTime(int64_t timestamp_ms) { 160 void UpdateQueueTime(int64_t timestamp_ms) {
146 RTC_DCHECK_GE(timestamp_ms, time_last_updated_); 161 // TODO(sprang): Remove this condition and reinstate a DCHECK once we have
162 // made sure all clocks are monotonic.
163 if (timestamp_ms < time_last_updated_)
164 return;
147 int64_t delta = timestamp_ms - time_last_updated_; 165 int64_t delta = timestamp_ms - time_last_updated_;
148 // Use packet packet_list_.size() not prio_queue_.size() here, as there 166 // Use packet packet_list_.size() not prio_queue_.size() here, as there
149 // might be an outstanding element popped from prio_queue_ currently in the 167 // might be an outstanding element popped from prio_queue_ currently in the
150 // SendPacket() call, while packet_list_ will always be correct. 168 // SendPacket() call, while packet_list_ will always be correct.
151 queue_time_sum_ += delta * packet_list_.size(); 169 queue_time_sum_ += delta * packet_list_.size();
152 time_last_updated_ = timestamp_ms; 170 time_last_updated_ = timestamp_ms;
153 } 171 }
154 172
155 int64_t AverageQueueTimeMs() const { 173 int64_t AverageQueueTimeMs() const {
156 if (prio_queue_.empty()) 174 if (prio_queue_.empty())
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 media_budget_->UseBudget(bytes_sent); 470 media_budget_->UseBudget(bytes_sent);
453 padding_budget_->UseBudget(bytes_sent); 471 padding_budget_->UseBudget(bytes_sent);
454 } 472 }
455 } 473 }
456 474
457 void PacedSender::UpdateBytesPerInterval(int64_t delta_time_ms) { 475 void PacedSender::UpdateBytesPerInterval(int64_t delta_time_ms) {
458 media_budget_->IncreaseBudget(delta_time_ms); 476 media_budget_->IncreaseBudget(delta_time_ms);
459 padding_budget_->IncreaseBudget(delta_time_ms); 477 padding_budget_->IncreaseBudget(delta_time_ms);
460 } 478 }
461 } // namespace webrtc 479 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698