mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
[fix] fix congestion control module
This commit is contained in:
42
src/common/api/media_types.h
Normal file
42
src/common/api/media_types.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
#ifndef API_MEDIA_TYPES_H_
|
||||
#define API_MEDIA_TYPES_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
// The cricket and webrtc have separate definitions for what a media type is.
|
||||
// They're not compatible. Watch out for this.
|
||||
|
||||
namespace cricket {
|
||||
|
||||
enum MediaType {
|
||||
MEDIA_TYPE_AUDIO,
|
||||
MEDIA_TYPE_VIDEO,
|
||||
MEDIA_TYPE_DATA,
|
||||
MEDIA_TYPE_UNSUPPORTED
|
||||
};
|
||||
|
||||
extern const char kMediaTypeAudio[];
|
||||
extern const char kMediaTypeVideo[];
|
||||
extern const char kMediaTypeData[];
|
||||
|
||||
std::string MediaTypeToString(MediaType type);
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
enum class MediaType { ANY, AUDIO, VIDEO, DATA };
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_MEDIA_TYPES_H_
|
||||
51
src/common/api/network_state_predictor.h
Normal file
51
src/common/api/network_state_predictor.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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.
|
||||
*/
|
||||
|
||||
#ifndef API_NETWORK_STATE_PREDICTOR_H_
|
||||
#define API_NETWORK_STATE_PREDICTOR_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "api/transport/bandwidth_usage.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// TODO(yinwa): work in progress. API in class NetworkStatePredictor should not
|
||||
// be used by other users until this comment is removed.
|
||||
|
||||
// NetworkStatePredictor predict network state based on current network metrics.
|
||||
// Usage:
|
||||
// Setup by calling Initialize.
|
||||
// For each update, call Update. Update returns network state
|
||||
// prediction.
|
||||
class NetworkStatePredictor {
|
||||
public:
|
||||
virtual ~NetworkStatePredictor() {}
|
||||
|
||||
// Returns current network state prediction.
|
||||
// Inputs: send_time_ms - packet send time.
|
||||
// arrival_time_ms - packet arrival time.
|
||||
// network_state - computed network state.
|
||||
virtual BandwidthUsage Update(int64_t send_time_ms,
|
||||
int64_t arrival_time_ms,
|
||||
BandwidthUsage network_state) = 0;
|
||||
};
|
||||
|
||||
class NetworkStatePredictorFactoryInterface {
|
||||
public:
|
||||
virtual std::unique_ptr<NetworkStatePredictor>
|
||||
CreateNetworkStatePredictor() = 0;
|
||||
virtual ~NetworkStatePredictorFactoryInterface() = default;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_NETWORK_STATE_PREDICTOR_H_
|
||||
17
src/common/api/transport/bandwidth_usage.h
Normal file
17
src/common/api/transport/bandwidth_usage.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-01-15
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _BANDWIDTH_USAGE_H_
|
||||
#define _BANDWIDTH_USAGE_H_
|
||||
|
||||
enum class BandwidthUsage {
|
||||
kBwNormal = 0,
|
||||
kBwUnderusing = 1,
|
||||
kBwOverusing = 2,
|
||||
kLast
|
||||
};
|
||||
|
||||
#endif
|
||||
124
src/common/api/transport/network_control.h
Normal file
124
src/common/api/transport/network_control.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.
|
||||
*/
|
||||
|
||||
#ifndef API_TRANSPORT_NETWORK_CONTROL_H_
|
||||
#define API_TRANSPORT_NETWORK_CONTROL_H_
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "api/transport/network_types.h"
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/time_delta.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class TargetTransferRateObserver {
|
||||
public:
|
||||
virtual ~TargetTransferRateObserver() = default;
|
||||
// Called to indicate target transfer rate as well as giving information about
|
||||
// the current estimate of network parameters.
|
||||
virtual void OnTargetTransferRate(TargetTransferRate) = 0;
|
||||
// Called to provide updates to the expected target rate in case it changes
|
||||
// before the first call to OnTargetTransferRate.
|
||||
virtual void OnStartRateUpdate(DataRate) {}
|
||||
};
|
||||
|
||||
// Configuration sent to factory create function. The parameters here are
|
||||
// optional to use for a network controller implementation.
|
||||
struct NetworkControllerConfig {
|
||||
explicit NetworkControllerConfig() {}
|
||||
|
||||
// The initial constraints to start with, these can be changed at any later
|
||||
// time by calls to OnTargetRateConstraints. Note that the starting rate
|
||||
// has to be set initially to provide a starting state for the network
|
||||
// controller, even though the field is marked as optional.
|
||||
TargetRateConstraints constraints;
|
||||
// Initial stream specific configuration, these are changed at any later time
|
||||
// by calls to OnStreamsConfig.
|
||||
StreamsConfig stream_based_config;
|
||||
};
|
||||
|
||||
// NetworkControllerInterface is implemented by network controllers. A network
|
||||
// controller is a class that uses information about network state and traffic
|
||||
// to estimate network parameters such as round trip time and bandwidth. Network
|
||||
// controllers does not guarantee thread safety, the interface must be used in a
|
||||
// non-concurrent fashion.
|
||||
class NetworkControllerInterface {
|
||||
public:
|
||||
virtual ~NetworkControllerInterface() = default;
|
||||
|
||||
// Called when network availabilty changes.
|
||||
virtual NetworkControlUpdate OnNetworkAvailability(NetworkAvailability) = 0;
|
||||
// Called when the receiving or sending endpoint changes address.
|
||||
virtual NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange) = 0;
|
||||
// Called periodically with a periodicy as specified by
|
||||
// NetworkControllerFactoryInterface::GetProcessInterval.
|
||||
virtual NetworkControlUpdate OnProcessInterval(ProcessInterval) = 0;
|
||||
// Called when remotely calculated bitrate is received.
|
||||
virtual NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport) = 0;
|
||||
// Called round trip time has been calculated by protocol specific mechanisms.
|
||||
virtual NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate) = 0;
|
||||
// Called when a packet is sent on the network.
|
||||
virtual NetworkControlUpdate OnSentPacket(SentPacket) = 0;
|
||||
// Called when a packet is received from the remote client.
|
||||
virtual NetworkControlUpdate OnReceivedPacket(ReceivedPacket) = 0;
|
||||
// Called when the stream specific configuration has been updated.
|
||||
virtual NetworkControlUpdate OnStreamsConfig(StreamsConfig) = 0;
|
||||
// Called when target transfer rate constraints has been changed.
|
||||
virtual NetworkControlUpdate OnTargetRateConstraints(
|
||||
TargetRateConstraints) = 0;
|
||||
// Called when a protocol specific calculation of packet loss has been made.
|
||||
virtual NetworkControlUpdate OnTransportLossReport(TransportLossReport) = 0;
|
||||
// Called with per packet feedback regarding receive time.
|
||||
virtual NetworkControlUpdate OnTransportPacketsFeedback(
|
||||
TransportPacketsFeedback) = 0;
|
||||
// Called with network state estimate updates.
|
||||
virtual NetworkControlUpdate OnNetworkStateEstimate(NetworkStateEstimate) = 0;
|
||||
};
|
||||
|
||||
// NetworkControllerFactoryInterface is an interface for creating a network
|
||||
// controller.
|
||||
class NetworkControllerFactoryInterface {
|
||||
public:
|
||||
virtual ~NetworkControllerFactoryInterface() = default;
|
||||
|
||||
// Used to create a new network controller, requires an observer to be
|
||||
// provided to handle callbacks.
|
||||
virtual std::unique_ptr<NetworkControllerInterface> Create(
|
||||
NetworkControllerConfig config) = 0;
|
||||
// Returns the interval by which the network controller expects
|
||||
// OnProcessInterval calls.
|
||||
virtual TimeDelta GetProcessInterval() const = 0;
|
||||
};
|
||||
|
||||
// Under development, subject to change without notice.
|
||||
class NetworkStateEstimator {
|
||||
public:
|
||||
// Gets the current best estimate according to the estimator.
|
||||
virtual std::optional<NetworkStateEstimate> GetCurrentEstimate() = 0;
|
||||
// Called with per packet feedback regarding receive time.
|
||||
// Used when the NetworkStateEstimator runs in the sending endpoint.
|
||||
virtual void OnTransportPacketsFeedback(const TransportPacketsFeedback&) = 0;
|
||||
// Called with per packet feedback regarding receive time.
|
||||
// Used when the NetworkStateEstimator runs in the receiving endpoint.
|
||||
virtual void OnReceivedPacket(const PacketResult&) {}
|
||||
// Called when the receiving or sending endpoint changes address.
|
||||
virtual void OnRouteChange(const NetworkRouteChange&) = 0;
|
||||
virtual ~NetworkStateEstimator() = default;
|
||||
};
|
||||
class NetworkStateEstimatorFactory {
|
||||
public:
|
||||
virtual std::unique_ptr<NetworkStateEstimator> Create() = 0;
|
||||
virtual ~NetworkStateEstimatorFactory() = default;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_TRANSPORT_NETWORK_CONTROL_H_
|
||||
39
src/common/rtc_base/bitrate_tracker.cc
Normal file
39
src/common/rtc_base/bitrate_tracker.cc
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 "rtc_base/bitrate_tracker.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "rtc_base/rate_statistics.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
BitrateTracker::BitrateTracker(TimeDelta max_window_size)
|
||||
: impl_(max_window_size.ms(), RateStatistics::kBpsScale) {}
|
||||
|
||||
std::optional<DataRate> BitrateTracker::Rate(Timestamp now) const {
|
||||
if (std::optional<int64_t> rate = impl_.Rate(now.ms())) {
|
||||
return DataRate::BitsPerSec(*rate);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool BitrateTracker::SetWindowSize(TimeDelta window_size, Timestamp now) {
|
||||
return impl_.SetWindowSize(window_size.ms(), now.ms());
|
||||
}
|
||||
|
||||
void BitrateTracker::Update(int64_t bytes, Timestamp now) {
|
||||
impl_.Update(bytes, now.ms());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
64
src/common/rtc_base/bitrate_tracker.h
Normal file
64
src/common/rtc_base/bitrate_tracker.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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.
|
||||
*/
|
||||
|
||||
#ifndef RTC_BASE_BITRATE_TRACKER_H_
|
||||
#define RTC_BASE_BITRATE_TRACKER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/data_size.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "rtc_base/rate_statistics.h"
|
||||
|
||||
namespace webrtc {
|
||||
// Class to estimate bitrates over running window.
|
||||
// Timestamps used in Update(), Rate() and SetWindowSize() must never
|
||||
// decrease for two consecutive calls.
|
||||
// This class is thread unsafe.
|
||||
class BitrateTracker {
|
||||
public:
|
||||
// max_window_sizes = Maximum window size for the rate estimation.
|
||||
// Initial window size is set to this, but may be changed
|
||||
// to something lower by calling SetWindowSize().
|
||||
explicit BitrateTracker(TimeDelta max_window_size);
|
||||
|
||||
BitrateTracker(const BitrateTracker&) = default;
|
||||
BitrateTracker(BitrateTracker&&) = default;
|
||||
BitrateTracker& operator=(const BitrateTracker&) = delete;
|
||||
BitrateTracker& operator=(BitrateTracker&&) = delete;
|
||||
|
||||
~BitrateTracker() = default;
|
||||
|
||||
// Resets instance to original state.
|
||||
void Reset() { impl_.Reset(); }
|
||||
|
||||
// Updates bitrate with a new data point, moving averaging window as needed.
|
||||
void Update(int64_t bytes, Timestamp now);
|
||||
void Update(DataSize size, Timestamp now) { Update(size.bytes(), now); }
|
||||
|
||||
// Returns bitrate, moving averaging window as needed.
|
||||
// Returns nullopt when bitrate can't be measured.
|
||||
std::optional<DataRate> Rate(Timestamp now) const;
|
||||
|
||||
// Update the size of the averaging window. The maximum allowed value for
|
||||
// `window_size` is `max_window_size` as supplied in the constructor.
|
||||
bool SetWindowSize(TimeDelta window_size, Timestamp now);
|
||||
|
||||
private:
|
||||
RateStatistics impl_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // RTC_BASE_BITRATE_TRACKER_H_
|
||||
160
src/common/rtc_base/rate_statistics.cc
Normal file
160
src/common/rtc_base/rate_statistics.cc
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2013 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 "rtc_base/rate_statistics.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
#include "log.h"
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RateStatistics::Bucket::Bucket(int64_t timestamp)
|
||||
: sum(0), num_samples(0), timestamp(timestamp) {}
|
||||
|
||||
RateStatistics::RateStatistics(int64_t window_size_ms, float scale)
|
||||
: accumulated_count_(0),
|
||||
first_timestamp_(-1),
|
||||
num_samples_(0),
|
||||
scale_(scale),
|
||||
max_window_size_ms_(window_size_ms),
|
||||
current_window_size_ms_(max_window_size_ms_) {}
|
||||
|
||||
RateStatistics::RateStatistics(const RateStatistics& other)
|
||||
: buckets_(other.buckets_),
|
||||
accumulated_count_(other.accumulated_count_),
|
||||
first_timestamp_(other.first_timestamp_),
|
||||
overflow_(other.overflow_),
|
||||
num_samples_(other.num_samples_),
|
||||
scale_(other.scale_),
|
||||
max_window_size_ms_(other.max_window_size_ms_),
|
||||
current_window_size_ms_(other.current_window_size_ms_) {}
|
||||
|
||||
RateStatistics::RateStatistics(RateStatistics&& other) = default;
|
||||
|
||||
RateStatistics::~RateStatistics() {}
|
||||
|
||||
void RateStatistics::Reset() {
|
||||
accumulated_count_ = 0;
|
||||
overflow_ = false;
|
||||
num_samples_ = 0;
|
||||
first_timestamp_ = -1;
|
||||
current_window_size_ms_ = max_window_size_ms_;
|
||||
buckets_.clear();
|
||||
}
|
||||
|
||||
void RateStatistics::Update(int64_t count, int64_t now_ms) {
|
||||
// Don't reset `first_timestamp_` if the last sample removed by EraseOld() was
|
||||
// recent. This ensures that the window maintains its intended duration even
|
||||
// when samples are received near the boundary. Use a margin of 50% of the
|
||||
// current window size.
|
||||
const int64_t recent_sample_time_margin = 1.5 * current_window_size_ms_;
|
||||
bool last_sample_is_recent =
|
||||
!buckets_.empty() &&
|
||||
buckets_.back().timestamp > now_ms - recent_sample_time_margin;
|
||||
|
||||
EraseOld(now_ms);
|
||||
if (first_timestamp_ == -1 || (num_samples_ == 0 && !last_sample_is_recent)) {
|
||||
first_timestamp_ = now_ms;
|
||||
}
|
||||
|
||||
if (buckets_.empty() || now_ms != buckets_.back().timestamp) {
|
||||
if (!buckets_.empty() && now_ms < buckets_.back().timestamp) {
|
||||
LOG_WARN(
|
||||
"Timestamp {} is before the last added timestamp in the rate window: "
|
||||
"{}, aligning to that.",
|
||||
now_ms, buckets_.back().timestamp);
|
||||
now_ms = buckets_.back().timestamp;
|
||||
}
|
||||
buckets_.emplace_back(now_ms);
|
||||
}
|
||||
Bucket& last_bucket = buckets_.back();
|
||||
last_bucket.sum += count;
|
||||
++last_bucket.num_samples;
|
||||
|
||||
if (std::numeric_limits<int64_t>::max() - accumulated_count_ > count) {
|
||||
accumulated_count_ += count;
|
||||
} else {
|
||||
overflow_ = true;
|
||||
}
|
||||
++num_samples_;
|
||||
}
|
||||
|
||||
std::optional<int64_t> RateStatistics::Rate(int64_t now_ms) const {
|
||||
// Yeah, this const_cast ain't pretty, but the alternative is to declare most
|
||||
// of the members as mutable...
|
||||
const_cast<RateStatistics*>(this)->EraseOld(now_ms);
|
||||
|
||||
int active_window_size = 0;
|
||||
if (first_timestamp_ != -1) {
|
||||
if (first_timestamp_ <= now_ms - current_window_size_ms_) {
|
||||
// Count window as full even if no data points currently in view, if the
|
||||
// data stream started before the window.
|
||||
active_window_size = current_window_size_ms_;
|
||||
} else {
|
||||
// Size of a single bucket is 1ms, so even if now_ms == first_timestmap_
|
||||
// the window size should be 1.
|
||||
active_window_size = now_ms - first_timestamp_ + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If window is a single bucket or there is only one sample in a data set that
|
||||
// has not grown to the full window size, or if the accumulator has
|
||||
// overflowed, treat this as rate unavailable.
|
||||
if (num_samples_ == 0 || active_window_size <= 1 ||
|
||||
(num_samples_ <= 1 &&
|
||||
rtc::SafeLt(active_window_size, current_window_size_ms_)) ||
|
||||
overflow_) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
float scale = static_cast<float>(scale_) / active_window_size;
|
||||
float result = accumulated_count_ * scale + 0.5f;
|
||||
|
||||
// Better return unavailable rate than garbage value (undefined behavior).
|
||||
if (result > static_cast<float>(std::numeric_limits<int64_t>::max())) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return rtc::dchecked_cast<int64_t>(result);
|
||||
}
|
||||
|
||||
void RateStatistics::EraseOld(int64_t now_ms) {
|
||||
// New oldest time that is included in data set.
|
||||
const int64_t new_oldest_time = now_ms - current_window_size_ms_ + 1;
|
||||
|
||||
// Loop over buckets and remove too old data points.
|
||||
while (!buckets_.empty() && buckets_.front().timestamp < new_oldest_time) {
|
||||
const Bucket& oldest_bucket = buckets_.front();
|
||||
accumulated_count_ -= oldest_bucket.sum;
|
||||
num_samples_ -= oldest_bucket.num_samples;
|
||||
buckets_.pop_front();
|
||||
// This does not clear overflow_ even when counter is empty.
|
||||
// TODO(https://bugs.webrtc.org/11247): Consider if overflow_ can be reset.
|
||||
}
|
||||
}
|
||||
|
||||
bool RateStatistics::SetWindowSize(int64_t window_size_ms, int64_t now_ms) {
|
||||
if (window_size_ms <= 0 || window_size_ms > max_window_size_ms_) return false;
|
||||
if (first_timestamp_ != -1) {
|
||||
// If the window changes (e.g. decreases - removing data point, then
|
||||
// increases again) we need to update the first timestamp mark as
|
||||
// otherwise it indicates the window coveres a region of zeros, suddenly
|
||||
// under-estimating the rate.
|
||||
first_timestamp_ = std::max(first_timestamp_, now_ms - window_size_ms + 1);
|
||||
}
|
||||
current_window_size_ms_ = window_size_ms;
|
||||
EraseOld(now_ms);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
103
src/common/rtc_base/rate_statistics.h
Normal file
103
src/common/rtc_base/rate_statistics.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef RTC_BASE_RATE_STATISTICS_H_
|
||||
#define RTC_BASE_RATE_STATISTICS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Class to estimate rates based on counts in a sequence of 1-millisecond
|
||||
// intervals.
|
||||
|
||||
// This class uses int64 for all its numbers because some rates can be very
|
||||
// high; for instance, a 20 Mbit/sec video stream can wrap a 32-bit byte
|
||||
// counter in 14 minutes.
|
||||
|
||||
// Note that timestamps used in Update(), Rate() and SetWindowSize() must never
|
||||
// decrease for two consecutive calls.
|
||||
// TODO(bugs.webrtc.org/11600): Migrate from int64_t to Timestamp.
|
||||
|
||||
class RateStatistics {
|
||||
public:
|
||||
static constexpr float kBpsScale = 8000.0f;
|
||||
|
||||
// max_window_size_ms = Maximum window size in ms for the rate estimation.
|
||||
// Initial window size is set to this, but may be changed
|
||||
// to something lower by calling SetWindowSize().
|
||||
// scale = coefficient to convert counts/ms to desired unit
|
||||
// ex: kBpsScale (8000) for bits/s if count represents bytes.
|
||||
RateStatistics(int64_t max_window_size_ms, float scale);
|
||||
|
||||
RateStatistics(const RateStatistics& other);
|
||||
|
||||
RateStatistics(RateStatistics&& other);
|
||||
|
||||
~RateStatistics();
|
||||
|
||||
// Reset instance to original state.
|
||||
void Reset();
|
||||
|
||||
// Update rate with a new data point, moving averaging window as needed.
|
||||
void Update(int64_t count, int64_t now_ms);
|
||||
|
||||
// Note that despite this being a const method, it still updates the internal
|
||||
// state (moves averaging window), but it doesn't make any alterations that
|
||||
// are observable from the other methods, as long as supplied timestamps are
|
||||
// from a monotonic clock. Ie, it doesn't matter if this call moves the
|
||||
// window, since any subsequent call to Update or Rate would still have moved
|
||||
// the window as much or more.
|
||||
std::optional<int64_t> Rate(int64_t now_ms) const;
|
||||
|
||||
// Update the size of the averaging window. The maximum allowed value for
|
||||
// window_size_ms is max_window_size_ms as supplied in the constructor.
|
||||
bool SetWindowSize(int64_t window_size_ms, int64_t now_ms);
|
||||
|
||||
private:
|
||||
void EraseOld(int64_t now_ms);
|
||||
|
||||
struct Bucket {
|
||||
explicit Bucket(int64_t timestamp);
|
||||
int64_t sum; // Sum of all samples in this bucket.
|
||||
int num_samples; // Number of samples in this bucket.
|
||||
const int64_t timestamp; // Timestamp this bucket corresponds to.
|
||||
};
|
||||
// All buckets within the time window, ordered by time.
|
||||
std::deque<Bucket> buckets_;
|
||||
|
||||
// Total count recorded in all buckets.
|
||||
int64_t accumulated_count_;
|
||||
|
||||
// Timestamp of the first data point seen, or -1 of none seen.
|
||||
int64_t first_timestamp_;
|
||||
|
||||
// True if accumulated_count_ has ever grown too large to be
|
||||
// contained in its integer type.
|
||||
bool overflow_ = false;
|
||||
|
||||
// The total number of samples in the buckets.
|
||||
int num_samples_;
|
||||
|
||||
// To convert counts/ms to desired units
|
||||
const float scale_;
|
||||
|
||||
// The window sizes, in ms, over which the rate is calculated.
|
||||
const int64_t max_window_size_ms_;
|
||||
int64_t current_window_size_ms_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // RTC_BASE_RATE_STATISTICS_H_
|
||||
98
src/common/rtc_base/thread_annotations.h
Normal file
98
src/common/rtc_base/thread_annotations.h
Normal file
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// Copyright (c) 2013 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.
|
||||
//
|
||||
// Borrowed from
|
||||
// https://code.google.com/p/gperftools/source/browse/src/base/thread_annotations.h
|
||||
// but adapted for clang attributes instead of the gcc.
|
||||
//
|
||||
// This header file contains the macro definitions for thread safety
|
||||
// annotations that allow the developers to document the locking policies
|
||||
// of their multi-threaded code. The annotations can also help program
|
||||
// analysis tools to identify potential thread safety issues.
|
||||
|
||||
#ifndef RTC_BASE_THREAD_ANNOTATIONS_H_
|
||||
#define RTC_BASE_THREAD_ANNOTATIONS_H_
|
||||
|
||||
#if defined(__clang__) && (!defined(SWIG))
|
||||
#define RTC_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
|
||||
#else
|
||||
#define RTC_THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
|
||||
#endif
|
||||
|
||||
// Document if a shared variable/field needs to be protected by a lock.
|
||||
// GUARDED_BY allows the user to specify a particular lock that should be
|
||||
// held when accessing the annotated variable.
|
||||
#define RTC_GUARDED_BY(x) RTC_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
|
||||
|
||||
// Document if the memory location pointed to by a pointer should be guarded
|
||||
// by a lock when dereferencing the pointer. Note that a pointer variable to a
|
||||
// shared memory location could itself be a shared variable. For example, if a
|
||||
// shared global pointer q, which is guarded by mu1, points to a shared memory
|
||||
// location that is guarded by mu2, q should be annotated as follows:
|
||||
// int *q GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
|
||||
#define RTC_PT_GUARDED_BY(x) RTC_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
|
||||
|
||||
// Document the acquisition order between locks that can be held
|
||||
// simultaneously by a thread. For any two locks that need to be annotated
|
||||
// to establish an acquisition order, only one of them needs the annotation.
|
||||
// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER
|
||||
// and ACQUIRED_BEFORE.)
|
||||
#define RTC_ACQUIRED_AFTER(x) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x))
|
||||
#define RTC_ACQUIRED_BEFORE(x) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x))
|
||||
|
||||
// The following three annotations document the lock requirements for
|
||||
// functions/methods.
|
||||
|
||||
// Document if a function expects certain locks to be held before it is called
|
||||
#define RTC_EXCLUSIVE_LOCKS_REQUIRED(...) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
|
||||
#define RTC_SHARED_LOCKS_REQUIRED(...) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
|
||||
|
||||
// Document the locks acquired in the body of the function. These locks
|
||||
// cannot be held when calling this function (as google3's Mutex locks are
|
||||
// non-reentrant).
|
||||
#define RTC_LOCKS_EXCLUDED(...) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
|
||||
|
||||
// Document the lock the annotated function returns without acquiring it.
|
||||
#define RTC_LOCK_RETURNED(x) RTC_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
|
||||
|
||||
// Document if a class/type is a lockable type (such as the Mutex class).
|
||||
#define RTC_LOCKABLE RTC_THREAD_ANNOTATION_ATTRIBUTE__(lockable)
|
||||
|
||||
// Document if a class is a scoped lockable type (such as the MutexLock class).
|
||||
#define RTC_SCOPED_LOCKABLE RTC_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
|
||||
|
||||
// The following annotations specify lock and unlock primitives.
|
||||
#define RTC_EXCLUSIVE_LOCK_FUNCTION(...) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
|
||||
|
||||
#define RTC_SHARED_LOCK_FUNCTION(...) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
|
||||
|
||||
#define RTC_EXCLUSIVE_TRYLOCK_FUNCTION(...) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
|
||||
|
||||
#define RTC_SHARED_TRYLOCK_FUNCTION(...) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
|
||||
|
||||
#define RTC_UNLOCK_FUNCTION(...) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
|
||||
|
||||
#define RTC_ASSERT_EXCLUSIVE_LOCK(...) \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
|
||||
|
||||
// An escape hatch for thread safety analysis to ignore the annotated function.
|
||||
#define RTC_NO_THREAD_SAFETY_ANALYSIS \
|
||||
RTC_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
|
||||
|
||||
#endif // RTC_BASE_THREAD_ANNOTATIONS_H_
|
||||
Reference in New Issue
Block a user