Temporary hack to avoid assert errors when time moves backwards.
Once we have eliminated all non-monotonic clocks, revert this change. BUG=webrtc:5452 Review URL: https://codereview.webrtc.org/1618333002 Cr-Commit-Position: refs/heads/master@{#11361}
This commit is contained in:
parent
cc71c4107f
commit
38b39d59d1
@ -35,6 +35,15 @@ const int64_t kMaxIntervalTimeMs = 30;
|
|||||||
// TODO(sprang): Move at least PacketQueue and MediaBudget out to separate
|
// TODO(sprang): Move at least PacketQueue and MediaBudget out to separate
|
||||||
// files, so that we can more easily test them.
|
// files, so that we can more easily test them.
|
||||||
|
|
||||||
|
// Note about the -1 enqueue times below:
|
||||||
|
// This is a temporary hack to avoid crashes when the real-time clock is
|
||||||
|
// adjusted backwards, which can happen on Android when the phone syncs the
|
||||||
|
// clock to the network. See this bug:
|
||||||
|
// https://bugs.chromium.org/p/webrtc/issues/detail?id=5452
|
||||||
|
// We can't just comment out the DCHECK either, as that would lead to the sum
|
||||||
|
// being wrong. Instead we just ignore packets from the past when we calculate
|
||||||
|
// the average queue time.
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace paced_sender {
|
namespace paced_sender {
|
||||||
struct Packet {
|
struct Packet {
|
||||||
@ -50,7 +59,8 @@ struct Packet {
|
|||||||
ssrc(ssrc),
|
ssrc(ssrc),
|
||||||
sequence_number(seq_number),
|
sequence_number(seq_number),
|
||||||
capture_time_ms(capture_time_ms),
|
capture_time_ms(capture_time_ms),
|
||||||
enqueue_time_ms(enqueue_time_ms),
|
// TODO(sprang): Remove -1 option once we can guarantee monotonic clock.
|
||||||
|
enqueue_time_ms(enqueue_time_ms), // -1 = not valid; don't count.
|
||||||
bytes(length_in_bytes),
|
bytes(length_in_bytes),
|
||||||
retransmission(retransmission),
|
retransmission(retransmission),
|
||||||
enqueue_order(enqueue_order) {}
|
enqueue_order(enqueue_order) {}
|
||||||
@ -99,6 +109,7 @@ class PacketQueue {
|
|||||||
if (!AddToDupeSet(packet))
|
if (!AddToDupeSet(packet))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (packet.enqueue_time_ms >= time_last_updated_)
|
||||||
UpdateQueueTime(packet.enqueue_time_ms);
|
UpdateQueueTime(packet.enqueue_time_ms);
|
||||||
|
|
||||||
// Store packet in list, use pointers in priority queue for cheaper moves.
|
// Store packet in list, use pointers in priority queue for cheaper moves.
|
||||||
@ -106,6 +117,8 @@ class PacketQueue {
|
|||||||
// when popping from queue.
|
// when popping from queue.
|
||||||
packet_list_.push_front(packet);
|
packet_list_.push_front(packet);
|
||||||
std::list<Packet>::iterator it = packet_list_.begin();
|
std::list<Packet>::iterator it = packet_list_.begin();
|
||||||
|
if (packet.enqueue_time_ms < time_last_updated_)
|
||||||
|
it->enqueue_time_ms = -1;
|
||||||
it->this_it = it; // Handle for direct removal from list.
|
it->this_it = it; // Handle for direct removal from list.
|
||||||
prio_queue_.push(&(*it)); // Pointer into list.
|
prio_queue_.push(&(*it)); // Pointer into list.
|
||||||
bytes_ += packet.bytes;
|
bytes_ += packet.bytes;
|
||||||
@ -122,6 +135,7 @@ class PacketQueue {
|
|||||||
void FinalizePop(const Packet& packet) {
|
void FinalizePop(const Packet& packet) {
|
||||||
RemoveFromDupeSet(packet);
|
RemoveFromDupeSet(packet);
|
||||||
bytes_ -= packet.bytes;
|
bytes_ -= packet.bytes;
|
||||||
|
if (packet.enqueue_time_ms != -1)
|
||||||
queue_time_sum_ -= (time_last_updated_ - packet.enqueue_time_ms);
|
queue_time_sum_ -= (time_last_updated_ - packet.enqueue_time_ms);
|
||||||
packet_list_.erase(packet.this_it);
|
packet_list_.erase(packet.this_it);
|
||||||
RTC_DCHECK_EQ(packet_list_.size(), prio_queue_.size());
|
RTC_DCHECK_EQ(packet_list_.size(), prio_queue_.size());
|
||||||
@ -136,14 +150,18 @@ class PacketQueue {
|
|||||||
uint64_t SizeInBytes() const { return bytes_; }
|
uint64_t SizeInBytes() const { return bytes_; }
|
||||||
|
|
||||||
int64_t OldestEnqueueTimeMs() const {
|
int64_t OldestEnqueueTimeMs() const {
|
||||||
auto it = packet_list_.rbegin();
|
for (auto it = packet_list_.rbegin(); it != packet_list_.rend(); ++it) {
|
||||||
if (it == packet_list_.rend())
|
if (it->enqueue_time_ms != -1)
|
||||||
return 0;
|
|
||||||
return it->enqueue_time_ms;
|
return it->enqueue_time_ms;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateQueueTime(int64_t timestamp_ms) {
|
void UpdateQueueTime(int64_t timestamp_ms) {
|
||||||
RTC_DCHECK_GE(timestamp_ms, time_last_updated_);
|
// TODO(sprang): Remove this condition and reinstate a DCHECK once we have
|
||||||
|
// made sure all clocks are monotonic.
|
||||||
|
if (timestamp_ms < time_last_updated_)
|
||||||
|
return;
|
||||||
int64_t delta = timestamp_ms - time_last_updated_;
|
int64_t delta = timestamp_ms - time_last_updated_;
|
||||||
// Use packet packet_list_.size() not prio_queue_.size() here, as there
|
// Use packet packet_list_.size() not prio_queue_.size() here, as there
|
||||||
// might be an outstanding element popped from prio_queue_ currently in the
|
// might be an outstanding element popped from prio_queue_ currently in the
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user