mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
[fix] fix qos module
This commit is contained in:
181
src/qos/remote_bitrate_estimator_single_stream.ccxx
Normal file
181
src/qos/remote_bitrate_estimator_single_stream.ccxx
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2012 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 "remote_bitrate_estimator_single_stream.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include "aimd_rate_control.h"
|
||||
#include "bwe_defines.h"
|
||||
#include "clock.h"
|
||||
#include "inter_arrival.h"
|
||||
#include "log.h"
|
||||
#include "overuse_detector.h"
|
||||
#include "overuse_estimator.h"
|
||||
#include "rtp_packet_received.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
constexpr int kTimestampGroupLengthMs = 5;
|
||||
constexpr double kTimestampToMs = 1.0 / 90.0;
|
||||
|
||||
} // namespace
|
||||
|
||||
RemoteBitrateEstimatorSingleStream::Detector::Detector()
|
||||
: last_packet_time(Timestamp::Zero()),
|
||||
inter_arrival(90 * kTimestampGroupLengthMs, kTimestampToMs) {}
|
||||
|
||||
RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
|
||||
std::shared_ptr<Clock> clock, RemoteBitrateObserver* observer)
|
||||
: clock_(clock),
|
||||
observer_(observer),
|
||||
incoming_bitrate_(kBitrateWindow),
|
||||
last_valid_incoming_bitrate_(DataRate::Zero()),
|
||||
process_interval_(kProcessInterval),
|
||||
uma_recorded_(false) {
|
||||
LOG_INFO("RemoteBitrateEstimatorSingleStream: Instantiating");
|
||||
}
|
||||
|
||||
RemoteBitrateEstimatorSingleStream::~RemoteBitrateEstimatorSingleStream() =
|
||||
default;
|
||||
|
||||
void RemoteBitrateEstimatorSingleStream::IncomingPacket(
|
||||
const RtpPacketReceived& rtp_packet) {
|
||||
std::optional<int32_t> transmission_time_offset = rtp_packet.Timestamp();
|
||||
if (!uma_recorded_) {
|
||||
BweNames type = transmission_time_offset.has_value()
|
||||
? BweNames::kReceiverTOffset
|
||||
: BweNames::kReceiverNoExtension;
|
||||
uma_recorded_ = true;
|
||||
}
|
||||
uint32_t ssrc = rtp_packet.Ssrc();
|
||||
uint32_t rtp_timestamp =
|
||||
rtp_packet.Timestamp() + transmission_time_offset.value_or(0);
|
||||
Timestamp now = clock_->CurrentTime();
|
||||
Detector& estimator = overuse_detectors_[ssrc];
|
||||
estimator.last_packet_time = now;
|
||||
|
||||
// Check if incoming bitrate estimate is valid, and if it needs to be reset.
|
||||
std::optional<DataRate> incoming_bitrate = incoming_bitrate_.Rate(now);
|
||||
if (incoming_bitrate) {
|
||||
last_valid_incoming_bitrate_ = *incoming_bitrate;
|
||||
} else if (last_valid_incoming_bitrate_ > DataRate::Zero()) {
|
||||
// Incoming bitrate had a previous valid value, but now not enough data
|
||||
// point are left within the current window. Reset incoming bitrate
|
||||
// estimator so that the window size will only contain new data points.
|
||||
incoming_bitrate_.Reset();
|
||||
last_valid_incoming_bitrate_ = DataRate::Zero();
|
||||
}
|
||||
size_t payload_size = rtp_packet.payload_size() + rtp_packet.padding_size();
|
||||
incoming_bitrate_.Update(payload_size, now);
|
||||
|
||||
const BandwidthUsage prior_state = estimator.detector.State();
|
||||
uint32_t timestamp_delta = 0;
|
||||
int64_t time_delta = 0;
|
||||
int size_delta = 0;
|
||||
int64_t now_ms = now.ms();
|
||||
if (estimator.inter_arrival.ComputeDeltas(
|
||||
rtp_timestamp, rtp_packet.arrival_time().ms(), now_ms, payload_size,
|
||||
×tamp_delta, &time_delta, &size_delta)) {
|
||||
double timestamp_delta_ms = timestamp_delta * kTimestampToMs;
|
||||
estimator.estimator.Update(time_delta, timestamp_delta_ms, size_delta,
|
||||
estimator.detector.State(), now_ms);
|
||||
estimator.detector.Detect(estimator.estimator.offset(), timestamp_delta_ms,
|
||||
estimator.estimator.num_of_deltas(), now_ms);
|
||||
}
|
||||
if (estimator.detector.State() == BandwidthUsage::kBwOverusing) {
|
||||
std::optional<DataRate> incoming_bitrate = incoming_bitrate_.Rate(now);
|
||||
if (incoming_bitrate.has_value() &&
|
||||
(prior_state != BandwidthUsage::kBwOverusing ||
|
||||
remote_rate_.TimeToReduceFurther(now, *incoming_bitrate))) {
|
||||
// The first overuse should immediately trigger a new estimate.
|
||||
// We also have to update the estimate immediately if we are overusing
|
||||
// and the target bitrate is too high compared to what we are receiving.
|
||||
UpdateEstimate(now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimeDelta RemoteBitrateEstimatorSingleStream::Process() {
|
||||
Timestamp now = clock_->CurrentTime();
|
||||
Timestamp next_process_time = last_process_time_.has_value()
|
||||
? *last_process_time_ + process_interval_
|
||||
: now;
|
||||
// TODO(bugs.webrtc.org/13756): Removing rounding to milliseconds after
|
||||
// investigating why tests fails without that rounding.
|
||||
if (now.ms() >= next_process_time.ms()) {
|
||||
UpdateEstimate(now);
|
||||
last_process_time_ = now;
|
||||
return process_interval_;
|
||||
}
|
||||
|
||||
return next_process_time - now;
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorSingleStream::UpdateEstimate(Timestamp now) {
|
||||
BandwidthUsage bw_state = BandwidthUsage::kBwNormal;
|
||||
auto it = overuse_detectors_.begin();
|
||||
while (it != overuse_detectors_.end()) {
|
||||
if (now - it->second.last_packet_time > kStreamTimeOut) {
|
||||
// This over-use detector hasn't received packets for `kStreamTimeOut`
|
||||
// and is considered stale.
|
||||
overuse_detectors_.erase(it++);
|
||||
} else {
|
||||
// Make sure that we trigger an over-use if any of the over-use detectors
|
||||
// is detecting over-use.
|
||||
if (it->second.detector.State() > bw_state) {
|
||||
bw_state = it->second.detector.State();
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
// We can't update the estimate if we don't have any active streams.
|
||||
if (overuse_detectors_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const RateControlInput input(bw_state, incoming_bitrate_.Rate(now));
|
||||
uint32_t target_bitrate = remote_rate_.Update(input, now).bps<uint32_t>();
|
||||
if (remote_rate_.ValidEstimate()) {
|
||||
process_interval_ = remote_rate_.GetFeedbackInterval();
|
||||
if (observer_)
|
||||
observer_->OnReceiveBitrateChanged(GetSsrcs(), target_bitrate);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorSingleStream::OnRttUpdate(int64_t avg_rtt_ms,
|
||||
int64_t /* max_rtt_ms */) {
|
||||
remote_rate_.SetRtt(TimeDelta::Millis(avg_rtt_ms));
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorSingleStream::RemoveStream(uint32_t ssrc) {
|
||||
overuse_detectors_.erase(ssrc);
|
||||
}
|
||||
|
||||
DataRate RemoteBitrateEstimatorSingleStream::LatestEstimate() const {
|
||||
if (!remote_rate_.ValidEstimate() || overuse_detectors_.empty()) {
|
||||
return DataRate::Zero();
|
||||
}
|
||||
return remote_rate_.LatestEstimate();
|
||||
}
|
||||
|
||||
std::vector<uint32_t> RemoteBitrateEstimatorSingleStream::GetSsrcs() const {
|
||||
std::vector<uint32_t> ssrcs;
|
||||
ssrcs.reserve(overuse_detectors_.size());
|
||||
for (const auto& [ssrc, unused] : overuse_detectors_) {
|
||||
ssrcs.push_back(ssrc);
|
||||
}
|
||||
return ssrcs;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
Reference in New Issue
Block a user