mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-14 14:20:45 +01:00

This cl prepares for a later CL introducing a new send side congestion controller that will run on a task queue. It mostly consists of minor fixes but adds some new interfaces that are unused in practice. Bug: webrtc:8415 Change-Id: I1b58d0180a18eb15320d18733dac0dfe2e0f902a Reviewed-on: https://webrtc-review.googlesource.com/53321 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Björn Terelius <terelius@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22099}
128 lines
3.8 KiB
C++
128 lines
3.8 KiB
C++
/*
|
|
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "modules/pacing/packet_queue.h"
|
|
|
|
#include <algorithm>
|
|
#include <list>
|
|
#include <vector>
|
|
|
|
#include "modules/include/module_common_types.h"
|
|
#include "modules/pacing/bitrate_prober.h"
|
|
#include "modules/pacing/interval_budget.h"
|
|
#include "modules/utility/include/process_thread.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/logging.h"
|
|
#include "system_wrappers/include/clock.h"
|
|
#include "system_wrappers/include/field_trial.h"
|
|
|
|
namespace webrtc {
|
|
|
|
PacketQueue::PacketQueue(const Clock* clock)
|
|
: bytes_(0),
|
|
clock_(clock),
|
|
queue_time_sum_(0),
|
|
time_last_updated_(clock_->TimeInMilliseconds()),
|
|
paused_(false) {}
|
|
|
|
PacketQueue::~PacketQueue() {}
|
|
|
|
void PacketQueue::Push(const Packet& packet) {
|
|
UpdateQueueTime(packet.enqueue_time_ms);
|
|
|
|
// Store packet in list, use pointers in priority queue for cheaper moves.
|
|
// Packets have a handle to its own iterator in the list, for easy removal
|
|
// when popping from queue.
|
|
packet_list_.push_front(packet);
|
|
std::list<Packet>::iterator it = packet_list_.begin();
|
|
it->this_it = it; // Handle for direct removal from list.
|
|
prio_queue_.push(&(*it)); // Pointer into list.
|
|
bytes_ += packet.bytes;
|
|
}
|
|
|
|
const PacketQueueInterface::Packet& PacketQueue::BeginPop() {
|
|
const Packet& packet = *prio_queue_.top();
|
|
prio_queue_.pop();
|
|
return packet;
|
|
}
|
|
|
|
void PacketQueue::CancelPop(const Packet& packet) {
|
|
prio_queue_.push(&(*packet.this_it));
|
|
}
|
|
|
|
void PacketQueue::FinalizePop(const Packet& packet) {
|
|
bytes_ -= packet.bytes;
|
|
int64_t packet_queue_time_ms = time_last_updated_ - packet.enqueue_time_ms;
|
|
RTC_DCHECK_LE(packet.sum_paused_ms, packet_queue_time_ms);
|
|
packet_queue_time_ms -= packet.sum_paused_ms;
|
|
RTC_DCHECK_LE(packet_queue_time_ms, queue_time_sum_);
|
|
queue_time_sum_ -= packet_queue_time_ms;
|
|
packet_list_.erase(packet.this_it);
|
|
RTC_DCHECK_EQ(packet_list_.size(), prio_queue_.size());
|
|
if (packet_list_.empty())
|
|
RTC_DCHECK_EQ(0, queue_time_sum_);
|
|
}
|
|
|
|
bool PacketQueue::Empty() const {
|
|
return prio_queue_.empty();
|
|
}
|
|
|
|
size_t PacketQueue::SizeInPackets() const {
|
|
return prio_queue_.size();
|
|
}
|
|
|
|
uint64_t PacketQueue::SizeInBytes() const {
|
|
return bytes_;
|
|
}
|
|
|
|
int64_t PacketQueue::OldestEnqueueTimeMs() const {
|
|
auto it = packet_list_.rbegin();
|
|
if (it == packet_list_.rend())
|
|
return 0;
|
|
return it->enqueue_time_ms;
|
|
}
|
|
|
|
void PacketQueue::UpdateQueueTime(int64_t timestamp_ms) {
|
|
RTC_DCHECK_GE(timestamp_ms, time_last_updated_);
|
|
if (timestamp_ms == time_last_updated_)
|
|
return;
|
|
|
|
int64_t delta_ms = timestamp_ms - time_last_updated_;
|
|
|
|
if (paused_) {
|
|
// Increase per-packet accumulators of time spent in queue while paused,
|
|
// so that we can disregard that when subtracting main accumulator when
|
|
// popping packet from the queue.
|
|
for (auto& it : packet_list_) {
|
|
it.sum_paused_ms += delta_ms;
|
|
}
|
|
} else {
|
|
// Use packet packet_list_.size() not prio_queue_.size() here, as there
|
|
// might be an outstanding element popped from prio_queue_ currently in
|
|
// the SendPacket() call, while packet_list_ will always be correct.
|
|
queue_time_sum_ += delta_ms * packet_list_.size();
|
|
}
|
|
time_last_updated_ = timestamp_ms;
|
|
}
|
|
|
|
void PacketQueue::SetPauseState(bool paused, int64_t timestamp_ms) {
|
|
if (paused_ == paused)
|
|
return;
|
|
UpdateQueueTime(timestamp_ms);
|
|
paused_ = paused;
|
|
}
|
|
|
|
int64_t PacketQueue::AverageQueueTimeMs() const {
|
|
if (prio_queue_.empty())
|
|
return 0;
|
|
return queue_time_sum_ / packet_list_.size();
|
|
}
|
|
|
|
} // namespace webrtc
|