Chromium Code Reviews| Index: webrtc/modules/congestion_controller/receive_side_congestion_controller.cc |
| diff --git a/webrtc/modules/congestion_controller/receive_side_congestion_controller.cc b/webrtc/modules/congestion_controller/receive_side_congestion_controller.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3fb636080d18eee317497e2c106f6aa779b8c427 |
| --- /dev/null |
| +++ b/webrtc/modules/congestion_controller/receive_side_congestion_controller.cc |
| @@ -0,0 +1,185 @@ |
| +/* |
| + * 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 "webrtc/modules/congestion_controller/include/receive_side_congestion_controller.h" |
| + |
| +#include "webrtc/base/logging.h" |
| +#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h" |
| +#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h" |
| + |
| +namespace webrtc { |
| + |
| +namespace { |
| +static const uint32_t kTimeOffsetSwitchThreshold = 30; |
| +} // namespace |
| + |
| +ReceiveSideCongestionController::WrappingBitrateEstimator:: |
| + WrappingBitrateEstimator(RemoteBitrateObserver* observer, |
| + const Clock* clock) |
| + : observer_(observer), |
| + clock_(clock), |
| + rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)), |
| + using_absolute_send_time_(false), |
| + packets_since_absolute_send_time_(0), |
| + min_bitrate_bps_(congestion_controller::GetMinBitrateBps()) {} |
| + |
| +void ReceiveSideCongestionController::WrappingBitrateEstimator::IncomingPacket( |
| + int64_t arrival_time_ms, |
| + size_t payload_size, |
| + const RTPHeader& header) { |
| + rtc::CritScope cs(&crit_sect_); |
| + PickEstimatorFromHeader(header); |
| + rbe_->IncomingPacket(arrival_time_ms, payload_size, header); |
| +} |
| + |
| +void ReceiveSideCongestionController::WrappingBitrateEstimator::Process() { |
| + rtc::CritScope cs(&crit_sect_); |
| + rbe_->Process(); |
| +} |
| + |
| +int64_t ReceiveSideCongestionController::WrappingBitrateEstimator:: |
| + TimeUntilNextProcess() { |
| + rtc::CritScope cs(&crit_sect_); |
| + return rbe_->TimeUntilNextProcess(); |
| +} |
| + |
| +void ReceiveSideCongestionController::WrappingBitrateEstimator::OnRttUpdate( |
| + int64_t avg_rtt_ms, |
| + int64_t max_rtt_ms) { |
| + rtc::CritScope cs(&crit_sect_); |
| + rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); |
| +} |
| + |
| +void ReceiveSideCongestionController::WrappingBitrateEstimator::RemoveStream( |
| + unsigned int ssrc) { |
| + rtc::CritScope cs(&crit_sect_); |
| + rbe_->RemoveStream(ssrc); |
| +} |
| + |
| +bool ReceiveSideCongestionController::WrappingBitrateEstimator::LatestEstimate( |
| + std::vector<unsigned int>* ssrcs, |
| + unsigned int* bitrate_bps) const { |
| + rtc::CritScope cs(&crit_sect_); |
| + return rbe_->LatestEstimate(ssrcs, bitrate_bps); |
| +} |
| + |
| +void ReceiveSideCongestionController::WrappingBitrateEstimator::SetMinBitrate( |
| + int min_bitrate_bps) { |
| + rtc::CritScope cs(&crit_sect_); |
| + rbe_->SetMinBitrate(min_bitrate_bps); |
| + min_bitrate_bps_ = min_bitrate_bps; |
| +} |
| + |
| +void ReceiveSideCongestionController::WrappingBitrateEstimator:: |
| + PickEstimatorFromHeader(const RTPHeader& header) { |
| + if (header.extension.hasAbsoluteSendTime) { |
| + // If we see AST in header, switch RBE strategy immediately. |
| + if (!using_absolute_send_time_) { |
| + LOG(LS_INFO) |
| + << "WrappingBitrateEstimator: Switching to absolute send time RBE."; |
| + using_absolute_send_time_ = true; |
| + PickEstimator(); |
| + } |
| + packets_since_absolute_send_time_ = 0; |
| + } else { |
| + // When we don't see AST, wait for a few packets before going back to TOF. |
| + if (using_absolute_send_time_) { |
| + ++packets_since_absolute_send_time_; |
| + if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) { |
| + LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission " |
| + << "time offset RBE."; |
| + using_absolute_send_time_ = false; |
| + PickEstimator(); |
| + } |
| + } |
| + } |
| +} |
| + |
| +// Instantiate RBE for Time Offset or Absolute Send Time extensions. |
| +void ReceiveSideCongestionController::WrappingBitrateEstimator:: |
| + PickEstimator() { |
| + if (using_absolute_send_time_) { |
| + rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_)); |
| + } else { |
| + rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_)); |
| + } |
| + rbe_->SetMinBitrate(min_bitrate_bps_); |
| +} |
| + |
| +ReceiveSideCongestionController::ReceiveSideCongestionController( |
| + const Clock* clock, |
| + RemoteBitrateObserver* remote_bitrate_observer, |
| + PacketRouter* packet_router) |
| + : remote_bitrate_estimator_(remote_bitrate_observer, clock), |
| + remote_estimator_proxy_(clock, packet_router) {} |
| + |
| +void ReceiveSideCongestionController::OnReceivedPacket( |
| + int64_t arrival_time_ms, |
| + size_t payload_size, |
| + const RTPHeader& header) { |
| + // Send-side BWE. |
| + if (header.extension.hasTransportSequenceNumber) { |
| + remote_estimator_proxy_.IncomingPacket(arrival_time_ms, payload_size, |
| + header); |
| + } else { |
| + // Receive-side BWE. |
| + remote_bitrate_estimator_.IncomingPacket(arrival_time_ms, payload_size, |
| + header); |
| + } |
| +} |
| + |
| +RemoteBitrateEstimator* |
| +ReceiveSideCongestionController::GetRemoteBitrateEstimator(bool send_side_bwe) { |
| + if (send_side_bwe) { |
| + return &remote_estimator_proxy_; |
| + } else { |
| + return &remote_bitrate_estimator_; |
| + } |
| +} |
| + |
| +const RemoteBitrateEstimator* |
| +ReceiveSideCongestionController::GetRemoteBitrateEstimator( |
| + bool send_side_bwe) const { |
| + if (send_side_bwe) { |
| + return &remote_estimator_proxy_; |
| + } else { |
| + return &remote_bitrate_estimator_; |
| + } |
| +} |
| + |
| +// TODO(nisse): When this code was part of CongestionController, the |
| +// method MaybeTriggerOnNetworkChanged called |
| +// remote_estimator_proxy_.OnBitrateChanged(bitrate_bps), and this was |
| +// called by both OnNetworkRouteChanged and Process. Do we need any |
| +// calls to OnBitRateChanged here? |
| + |
| +void ReceiveSideCongestionController::OnNetworkRouteChanged( |
| + int min_bitrate_bps) { |
|
stefan-webrtc
2017/03/17 08:03:32
I doubt there's much value in this as I don't thin
nisse-webrtc
2017/03/17 10:49:23
Sounds good to me. Deleted.
|
| + // TODO(nisse): Do we need to clamp using |
| + // webrtc::congestion_controller::GetMinBitrateBps? |
| + // TODO(honghaiz): Recreate this object once the remote bitrate estimator is |
| + // no longer exposed outside CongestionController. |
| + remote_bitrate_estimator_.SetMinBitrate(min_bitrate_bps); |
| +} |
| + |
| +void ReceiveSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms, |
| + int64_t max_rtt_ms) { |
| + remote_bitrate_estimator_.OnRttUpdate(avg_rtt_ms, max_rtt_ms); |
| +} |
| + |
| +int64_t ReceiveSideCongestionController::TimeUntilNextProcess() { |
| + return remote_bitrate_estimator_.TimeUntilNextProcess(); |
| +} |
| + |
| +void ReceiveSideCongestionController::Process() { |
| + remote_bitrate_estimator_.Process(); |
| +} |
| + |
| +} // namespace webrtc |