mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-18 08:07:56 +01:00

Before this CL, the RemoteEstimatorProxy used a std::map to track which arrival time a packet with a certain sequence number was received at. While this works, it's fairly slow as most manipulations and insertions are O(log(N)) and there were quite many of them. By taking advantage that sequence numbers generally are received in sequence, recording a packet is now amortized O(1). Also other operations such as creating the periodic feedback reports, are also much faster as it previously was done by searching quite a few times in that map. In highly loaded Media Servers, RemoteEstimatorProxy's usage of std::map attributes to around 0.52% CPU. Bug: webrtc:12689 Change-Id: I3dd58105f9fbfb111f176833cd4aa6b040c0e01d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217388 Reviewed-by: Björn Terelius <terelius@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Commit-Queue: Victor Boivie <boivie@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33979}
134 lines
5.6 KiB
C++
134 lines
5.6 KiB
C++
/*
|
|
* Copyright (c) 2015 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 MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_ESTIMATOR_PROXY_H_
|
|
#define MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_ESTIMATOR_PROXY_H_
|
|
|
|
#include <deque>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "api/transport/network_control.h"
|
|
#include "api/transport/webrtc_key_value_config.h"
|
|
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
|
#include "modules/remote_bitrate_estimator/packet_arrival_map.h"
|
|
#include "rtc_base/experiments/field_trial_parser.h"
|
|
#include "rtc_base/numerics/sequence_number_util.h"
|
|
#include "rtc_base/synchronization/mutex.h"
|
|
|
|
namespace webrtc {
|
|
|
|
class Clock;
|
|
namespace rtcp {
|
|
class TransportFeedback;
|
|
}
|
|
|
|
// Class used when send-side BWE is enabled: This proxy is instantiated on the
|
|
// receive side. It buffers a number of receive timestamps and then sends
|
|
// transport feedback messages back too the send side.
|
|
class RemoteEstimatorProxy : public RemoteBitrateEstimator {
|
|
public:
|
|
// Used for sending transport feedback messages when send side
|
|
// BWE is used.
|
|
using TransportFeedbackSender = std::function<void(
|
|
std::vector<std::unique_ptr<rtcp::RtcpPacket>> packets)>;
|
|
RemoteEstimatorProxy(Clock* clock,
|
|
TransportFeedbackSender feedback_sender,
|
|
const WebRtcKeyValueConfig* key_value_config,
|
|
NetworkStateEstimator* network_state_estimator);
|
|
~RemoteEstimatorProxy() override;
|
|
|
|
void IncomingPacket(int64_t arrival_time_ms,
|
|
size_t payload_size,
|
|
const RTPHeader& header) override;
|
|
void RemoveStream(uint32_t ssrc) override {}
|
|
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
|
|
unsigned int* bitrate_bps) const override;
|
|
void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override {}
|
|
void SetMinBitrate(int min_bitrate_bps) override {}
|
|
int64_t TimeUntilNextProcess() override;
|
|
void Process() override;
|
|
void OnBitrateChanged(int bitrate);
|
|
void SetSendPeriodicFeedback(bool send_periodic_feedback);
|
|
|
|
private:
|
|
struct TransportWideFeedbackConfig {
|
|
FieldTrialParameter<TimeDelta> back_window{"wind", TimeDelta::Millis(500)};
|
|
FieldTrialParameter<TimeDelta> min_interval{"min", TimeDelta::Millis(50)};
|
|
FieldTrialParameter<TimeDelta> max_interval{"max", TimeDelta::Millis(250)};
|
|
FieldTrialParameter<TimeDelta> default_interval{"def",
|
|
TimeDelta::Millis(100)};
|
|
FieldTrialParameter<double> bandwidth_fraction{"frac", 0.05};
|
|
explicit TransportWideFeedbackConfig(
|
|
const WebRtcKeyValueConfig* key_value_config) {
|
|
ParseFieldTrial({&back_window, &min_interval, &max_interval,
|
|
&default_interval, &bandwidth_fraction},
|
|
key_value_config->Lookup(
|
|
"WebRTC-Bwe-TransportWideFeedbackIntervals"));
|
|
}
|
|
};
|
|
|
|
void MaybeCullOldPackets(int64_t sequence_number, int64_t arrival_time_ms)
|
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_);
|
|
void SendPeriodicFeedbacks() RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_);
|
|
void SendFeedbackOnRequest(int64_t sequence_number,
|
|
const FeedbackRequest& feedback_request)
|
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_);
|
|
|
|
// Returns a Transport Feedback packet with information about as many packets
|
|
// that has been received between [`begin_sequence_number_incl`,
|
|
// `end_sequence_number_excl`) that can fit in it. If `is_periodic_update`,
|
|
// this represents sending a periodic feedback message, which will make it
|
|
// update the `periodic_window_start_seq_` variable with the first packet that
|
|
// was not included in the feedback packet, so that the next update can
|
|
// continue from that sequence number.
|
|
//
|
|
// If no incoming packets were added, nullptr is returned.
|
|
//
|
|
// `include_timestamps` decide if the returned TransportFeedback should
|
|
// include timestamps.
|
|
std::unique_ptr<rtcp::TransportFeedback> MaybeBuildFeedbackPacket(
|
|
bool include_timestamps,
|
|
int64_t begin_sequence_number_inclusive,
|
|
int64_t end_sequence_number_exclusive,
|
|
bool is_periodic_update) RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_);
|
|
|
|
Clock* const clock_;
|
|
const TransportFeedbackSender feedback_sender_;
|
|
const TransportWideFeedbackConfig send_config_;
|
|
int64_t last_process_time_ms_;
|
|
|
|
Mutex lock_;
|
|
// |network_state_estimator_| may be null.
|
|
NetworkStateEstimator* const network_state_estimator_
|
|
RTC_PT_GUARDED_BY(&lock_);
|
|
uint32_t media_ssrc_ RTC_GUARDED_BY(&lock_);
|
|
uint8_t feedback_packet_count_ RTC_GUARDED_BY(&lock_);
|
|
SeqNumUnwrapper<uint16_t> unwrapper_ RTC_GUARDED_BY(&lock_);
|
|
|
|
// The next sequence number that should be the start sequence number during
|
|
// periodic reporting. Will be absl::nullopt before the first seen packet.
|
|
absl::optional<int64_t> periodic_window_start_seq_ RTC_GUARDED_BY(&lock_);
|
|
|
|
// Packet arrival times, by sequence number.
|
|
PacketArrivalTimeMap packet_arrival_times_ RTC_GUARDED_BY(&lock_);
|
|
|
|
int64_t send_interval_ms_ RTC_GUARDED_BY(&lock_);
|
|
bool send_periodic_feedback_ RTC_GUARDED_BY(&lock_);
|
|
|
|
// Unwraps absolute send times.
|
|
uint32_t previous_abs_send_time_ RTC_GUARDED_BY(&lock_);
|
|
Timestamp abs_send_timestamp_ RTC_GUARDED_BY(&lock_);
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_ESTIMATOR_PROXY_H_
|