Reland "Reland "Using units in SendSideBandwidthEstimation.""

This reverts commit a4de9c8b04ce9f7b1c4be639edd6cc4d3a9f07a1.

Reason for revert: <INSERT REASONING HERE>

Original change's description:
> Revert "Reland "Using units in SendSideBandwidthEstimation.""
> 
> This reverts commit e2cb26cb4fa2a3ce7c12636225ba9c720d7c7e56.
> 
> Reason for revert: <INSERT REASONING HERE>
> 
> Original change's description:
> > Reland "Using units in SendSideBandwidthEstimation."
> > 
> > This reverts commit 917e5967a597fa8d6e6cae9ffccb21e3d35d553b.
> > 
> > Reason for revert: Handling downstream use case.
> > 
> > Original change's description:
> > > Revert "Using units in SendSideBandwidthEstimation."
> > > 
> > > This reverts commit 35b5e5f3b0dc409bf571b3609860ad5bb8e00c29.
> > > 
> > > Reason for revert: Breaks downstream project
> > > 
> > > Original change's description:
> > > > Using units in SendSideBandwidthEstimation.
> > > >
> > > > This CL moves SendSideBandwidthEstimation to use the unit types
> > > > DataRate, TimeDelta and Timestamp. This prepares for upcoming changes.
> > > >
> > > > Bug: webrtc:9718
> > > > Change-Id: If10e329920dda037b53055ff3352ae7f8d7e32b8
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/104021
> > > > Commit-Queue: Sebastian Jansson <srte@webrtc.org>
> > > > Reviewed-by: Björn Terelius <terelius@webrtc.org>
> > > > Cr-Commit-Position: refs/heads/master@{#25029}
> > > 
> > > TBR=terelius@webrtc.org,srte@webrtc.org
> > > 
> > > No-Try: True
> > > Bug: webrtc:9718
> > > Change-Id: Iaf470f1eec9911ee6fc7c1b4f5db9675d89d3780
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/104480
> > > Commit-Queue: Oleh Prypin <oprypin@webrtc.org>
> > > Reviewed-by: Oleh Prypin <oprypin@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#25035}
> > 
> > TBR=oprypin@webrtc.org,terelius@webrtc.org,srte@webrtc.org
> > 
> > Change-Id: I0940791fcd1e196598b0f0a2ec779c49931ee5df
> > No-Presubmit: true
> > No-Tree-Checks: true
> > No-Try: true
> > Bug: webrtc:9718
> > Reviewed-on: https://webrtc-review.googlesource.com/c/104520
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Commit-Queue: Sebastian Jansson <srte@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#25036}
> 
> TBR=oprypin@webrtc.org,terelius@webrtc.org,srte@webrtc.org
> 
> Change-Id: I6628771c79fc78dfd856649ae92232e95df63495
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:9718
> Reviewed-on: https://webrtc-review.googlesource.com/c/104540
> Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> Commit-Queue: Sebastian Jansson <srte@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#25037}

TBR=oprypin@webrtc.org,terelius@webrtc.org,srte@webrtc.org

Change-Id: If5473859cea725420afce11b6683fa0c70a29b0a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:9718
Reviewed-on: https://webrtc-review.googlesource.com/c/104501
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25039}
diff --git a/modules/bitrate_controller/BUILD.gn b/modules/bitrate_controller/BUILD.gn
index ae66765..72046f0 100644
--- a/modules/bitrate_controller/BUILD.gn
+++ b/modules/bitrate_controller/BUILD.gn
@@ -44,6 +44,7 @@
     "../rtp_rtcp",
     "../rtp_rtcp:rtp_rtcp_format",
     "//third_party/abseil-cpp/absl/memory",
+    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/modules/bitrate_controller/bitrate_controller_impl.cc b/modules/bitrate_controller/bitrate_controller_impl.cc
index 9b816f6..86b016c 100644
--- a/modules/bitrate_controller/bitrate_controller_impl.cc
+++ b/modules/bitrate_controller/bitrate_controller_impl.cc
@@ -20,7 +20,18 @@
 #include "rtc_base/logging.h"
 
 namespace webrtc {
-
+namespace {
+absl::optional<DataRate> ToOptionalDataRate(int send_bitrate_bps) {
+  if (send_bitrate_bps > 0)
+    return DataRate::bps(send_bitrate_bps);
+  return absl::nullopt;
+}
+DataRate MaxRate(int max_bitrate_bps) {
+  if (max_bitrate_bps == -1)
+    return DataRate::Infinity();
+  return DataRate::bps(max_bitrate_bps);
+}
+}  // namespace
 class BitrateControllerImpl::RtcpBandwidthObserverImpl
     : public RtcpBandwidthObserver {
  public:
@@ -80,7 +91,9 @@
 void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
   {
     rtc::CritScope cs(&critsect_);
-    bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
+    bandwidth_estimation_.SetSendBitrate(
+        DataRate::bps(start_bitrate_bps),
+        Timestamp::ms(clock_->TimeInMilliseconds()));
   }
   MaybeTriggerOnNetworkChanged();
 }
@@ -89,7 +102,8 @@
                                              int max_bitrate_bps) {
   {
     rtc::CritScope cs(&critsect_);
-    bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
+    bandwidth_estimation_.SetMinMaxBitrate(DataRate::bps(min_bitrate_bps),
+                                           DataRate::bps(max_bitrate_bps));
   }
   MaybeTriggerOnNetworkChanged();
 }
@@ -99,8 +113,9 @@
                                         int max_bitrate_bps) {
   {
     rtc::CritScope cs(&critsect_);
-    bandwidth_estimation_.SetBitrates(start_bitrate_bps, min_bitrate_bps,
-                                      max_bitrate_bps);
+    bandwidth_estimation_.SetBitrates(
+        ToOptionalDataRate(start_bitrate_bps), DataRate::bps(min_bitrate_bps),
+        MaxRate(max_bitrate_bps), Timestamp::ms(clock_->TimeInMilliseconds()));
   }
   MaybeTriggerOnNetworkChanged();
 }
@@ -111,8 +126,9 @@
   {
     rtc::CritScope cs(&critsect_);
     bandwidth_estimation_ = SendSideBandwidthEstimation(event_log_);
-    bandwidth_estimation_.SetBitrates(bitrate_bps, min_bitrate_bps,
-                                      max_bitrate_bps);
+    bandwidth_estimation_.SetBitrates(
+        ToOptionalDataRate(bitrate_bps), DataRate::bps(min_bitrate_bps),
+        MaxRate(max_bitrate_bps), Timestamp::ms(clock_->TimeInMilliseconds()));
   }
   MaybeTriggerOnNetworkChanged();
 }
@@ -121,8 +137,8 @@
 void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
   {
     rtc::CritScope cs(&critsect_);
-    bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(),
-                                                 bitrate);
+    bandwidth_estimation_.UpdateReceiverEstimate(
+        Timestamp::ms(clock_->TimeInMilliseconds()), DataRate::bps(bitrate));
     BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", clock_->TimeInMilliseconds(),
                           bitrate / 1000);
   }
@@ -136,12 +152,15 @@
   {
     rtc::CritScope cs(&critsect_);
     if (result.probe) {
-      bandwidth_estimation_.SetSendBitrate(result.target_bitrate_bps);
+      bandwidth_estimation_.SetSendBitrate(
+          DataRate::bps(result.target_bitrate_bps),
+          Timestamp::ms(clock_->TimeInMilliseconds()));
     }
     // Since SetSendBitrate now resets the delay-based estimate, we have to call
     // UpdateDelayBasedEstimate after SetSendBitrate.
-    bandwidth_estimation_.UpdateDelayBasedEstimate(clock_->TimeInMilliseconds(),
-                                                   result.target_bitrate_bps);
+    bandwidth_estimation_.UpdateDelayBasedEstimate(
+        Timestamp::ms(clock_->TimeInMilliseconds()),
+        DataRate::bps(result.target_bitrate_bps));
   }
   MaybeTriggerOnNetworkChanged();
 }
@@ -158,7 +177,8 @@
 void BitrateControllerImpl::Process() {
   {
     rtc::CritScope cs(&critsect_);
-    bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
+    bandwidth_estimation_.UpdateEstimate(
+        Timestamp::ms(clock_->TimeInMilliseconds()));
   }
   MaybeTriggerOnNetworkChanged();
   last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
@@ -213,8 +233,9 @@
 
     RTC_DCHECK_GE(total_number_of_packets, 0);
 
-    bandwidth_estimation_.UpdateReceiverBlock(fraction_lost_aggregate, rtt,
-                                              total_number_of_packets, now_ms);
+    bandwidth_estimation_.UpdateReceiverBlock(
+        fraction_lost_aggregate, TimeDelta::ms(rtt), total_number_of_packets,
+        Timestamp::ms(now_ms));
   }
   MaybeTriggerOnNetworkChanged();
 }
diff --git a/modules/bitrate_controller/send_side_bandwidth_estimation.cc b/modules/bitrate_controller/send_side_bandwidth_estimation.cc
index 48eea3c..cc108a9 100644
--- a/modules/bitrate_controller/send_side_bandwidth_estimation.cc
+++ b/modules/bitrate_controller/send_side_bandwidth_estimation.cc
@@ -27,22 +27,22 @@
 
 namespace webrtc {
 namespace {
-const int64_t kBweIncreaseIntervalMs = 1000;
-const int64_t kBweDecreaseIntervalMs = 300;
-const int64_t kStartPhaseMs = 2000;
-const int64_t kBweConverganceTimeMs = 20000;
-const int kLimitNumPackets = 20;
-const int kDefaultMaxBitrateBps = 1000000000;
-const int64_t kLowBitrateLogPeriodMs = 10000;
-const int64_t kRtcEventLogPeriodMs = 5000;
+constexpr TimeDelta kBweIncreaseInterval = TimeDelta::Millis<1000>();
+constexpr TimeDelta kBweDecreaseInterval = TimeDelta::Millis<300>();
+constexpr TimeDelta kStartPhase = TimeDelta::Millis<2000>();
+constexpr TimeDelta kBweConverganceTime = TimeDelta::Millis<20000>();
+constexpr int kLimitNumPackets = 20;
+constexpr DataRate kDefaultMaxBitrate = DataRate::BitsPerSec<1000000000>();
+constexpr TimeDelta kLowBitrateLogPeriod = TimeDelta::Millis<10000>();
+constexpr TimeDelta kRtcEventLogPeriod = TimeDelta::Millis<5000>();
 // Expecting that RTCP feedback is sent uniformly within [0.5, 1.5]s intervals.
-const int64_t kFeedbackIntervalMs = 5000;
-const int64_t kFeedbackTimeoutIntervals = 3;
-const int64_t kTimeoutIntervalMs = 1000;
+constexpr TimeDelta kMaxRtcpFeedbackInterval = TimeDelta::Millis<5000>();
+constexpr int kFeedbackTimeoutIntervals = 3;
+constexpr TimeDelta kTimeoutInterval = TimeDelta::Millis<1000>();
 
-const float kDefaultLowLossThreshold = 0.02f;
-const float kDefaultHighLossThreshold = 0.1f;
-const int kDefaultBitrateThresholdKbps = 0;
+constexpr float kDefaultLowLossThreshold = 0.02f;
+constexpr float kDefaultHighLossThreshold = 0.1f;
+constexpr DataRate kDefaultBitrateThreshold = DataRate::Zero();
 
 struct UmaRampUpMetric {
   const char* metric_name;
@@ -99,7 +99,7 @@
                          "experiment from field trial string. Using default.";
   *low_loss_threshold = kDefaultLowLossThreshold;
   *high_loss_threshold = kDefaultHighLossThreshold;
-  *bitrate_threshold_kbps = kDefaultBitrateThresholdKbps;
+  *bitrate_threshold_kbps = kDefaultBitrateThreshold.kbps();
   return false;
 }
 }  // namespace
@@ -107,33 +107,34 @@
 SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log)
     : lost_packets_since_last_loss_update_(0),
       expected_packets_since_last_loss_update_(0),
-      current_bitrate_bps_(0),
-      min_bitrate_configured_(congestion_controller::GetMinBitrateBps()),
-      max_bitrate_configured_(kDefaultMaxBitrateBps),
-      last_low_bitrate_log_ms_(-1),
+      current_bitrate_(DataRate::Zero()),
+      min_bitrate_configured_(
+          DataRate::bps(congestion_controller::GetMinBitrateBps())),
+      max_bitrate_configured_(kDefaultMaxBitrate),
+      last_low_bitrate_log_(Timestamp::MinusInfinity()),
       has_decreased_since_last_fraction_loss_(false),
-      last_feedback_ms_(-1),
-      last_packet_report_ms_(-1),
-      last_timeout_ms_(-1),
+      last_loss_feedback_(Timestamp::MinusInfinity()),
+      last_loss_packet_report_(Timestamp::MinusInfinity()),
+      last_timeout_(Timestamp::MinusInfinity()),
       last_fraction_loss_(0),
       last_logged_fraction_loss_(0),
-      last_round_trip_time_ms_(0),
-      bwe_incoming_(0),
-      delay_based_bitrate_bps_(0),
-      time_last_decrease_ms_(0),
-      first_report_time_ms_(-1),
+      last_round_trip_time_(TimeDelta::Zero()),
+      bwe_incoming_(DataRate::Zero()),
+      delay_based_bitrate_(DataRate::Zero()),
+      time_last_decrease_(Timestamp::MinusInfinity()),
+      first_report_time_(Timestamp::MinusInfinity()),
       initially_lost_packets_(0),
-      bitrate_at_2_seconds_kbps_(0),
+      bitrate_at_2_seconds_(DataRate::Zero()),
       uma_update_state_(kNoUpdate),
       uma_rtt_state_(kNoUpdate),
       rampup_uma_stats_updated_(kNumUmaRampupMetrics, false),
       event_log_(event_log),
-      last_rtc_event_log_ms_(-1),
+      last_rtc_event_log_(Timestamp::MinusInfinity()),
       in_timeout_experiment_(
           webrtc::field_trial::IsEnabled("WebRTC-FeedbackTimeout")),
       low_loss_threshold_(kDefaultLowLossThreshold),
       high_loss_threshold_(kDefaultHighLossThreshold),
-      bitrate_threshold_bps_(1000 * kDefaultBitrateThresholdKbps) {
+      bitrate_threshold_(kDefaultBitrateThreshold) {
   RTC_DCHECK(event_log);
   if (BweLossExperimentIsEnabled()) {
     uint32_t bitrate_threshold_kbps;
@@ -143,87 +144,87 @@
       RTC_LOG(LS_INFO) << "Enabled BweLossExperiment with parameters "
                        << low_loss_threshold_ << ", " << high_loss_threshold_
                        << ", " << bitrate_threshold_kbps;
-      bitrate_threshold_bps_ = bitrate_threshold_kbps * 1000;
+      bitrate_threshold_ = DataRate::kbps(bitrate_threshold_kbps);
     }
   }
 }
 
 SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {}
 
-void SendSideBandwidthEstimation::SetBitrates(int send_bitrate,
-                                              int min_bitrate,
-                                              int max_bitrate) {
+void SendSideBandwidthEstimation::SetBitrates(
+    absl::optional<DataRate> send_bitrate,
+    DataRate min_bitrate,
+    DataRate max_bitrate,
+    Timestamp at_time) {
   SetMinMaxBitrate(min_bitrate, max_bitrate);
-  if (send_bitrate > 0)
-    SetSendBitrate(send_bitrate);
+  if (send_bitrate)
+    SetSendBitrate(*send_bitrate, at_time);
 }
 
-void SendSideBandwidthEstimation::SetSendBitrate(int bitrate) {
-  RTC_DCHECK_GT(bitrate, 0);
-  delay_based_bitrate_bps_ = 0;  // Reset to avoid being capped by the estimate.
-  CapBitrateToThresholds(Clock::GetRealTimeClock()->TimeInMilliseconds(),
-                         bitrate);
+void SendSideBandwidthEstimation::SetSendBitrate(DataRate bitrate,
+                                                 Timestamp at_time) {
+  RTC_DCHECK(bitrate > DataRate::Zero());
+  // Reset to avoid being capped by the estimate.
+  delay_based_bitrate_ = DataRate::Zero();
+  CapBitrateToThresholds(at_time, bitrate);
   // Clear last sent bitrate history so the new value can be used directly
   // and not capped.
   min_bitrate_history_.clear();
 }
 
-void SendSideBandwidthEstimation::SetMinMaxBitrate(int min_bitrate,
-                                                   int max_bitrate) {
-  RTC_DCHECK_GE(min_bitrate, 0);
+void SendSideBandwidthEstimation::SetMinMaxBitrate(DataRate min_bitrate,
+                                                   DataRate max_bitrate) {
   min_bitrate_configured_ =
-      std::max(min_bitrate, congestion_controller::GetMinBitrateBps());
-  if (max_bitrate > 0) {
-    max_bitrate_configured_ =
-        std::max<uint32_t>(min_bitrate_configured_, max_bitrate);
+      std::max(min_bitrate, congestion_controller::GetMinBitrate());
+  if (max_bitrate > DataRate::Zero() && max_bitrate.IsFinite()) {
+    max_bitrate_configured_ = std::max(min_bitrate_configured_, max_bitrate);
   } else {
-    max_bitrate_configured_ = kDefaultMaxBitrateBps;
+    max_bitrate_configured_ = kDefaultMaxBitrate;
   }
 }
 
 int SendSideBandwidthEstimation::GetMinBitrate() const {
-  return min_bitrate_configured_;
+  return min_bitrate_configured_.bps<int>();
 }
 
 void SendSideBandwidthEstimation::CurrentEstimate(int* bitrate,
                                                   uint8_t* loss,
                                                   int64_t* rtt) const {
-  *bitrate = current_bitrate_bps_;
+  *bitrate = current_bitrate_.bps<int>();
   *loss = last_fraction_loss_;
-  *rtt = last_round_trip_time_ms_;
+  *rtt = last_round_trip_time_.ms<int64_t>();
 }
 
-void SendSideBandwidthEstimation::UpdateReceiverEstimate(int64_t now_ms,
-                                                         uint32_t bandwidth) {
+void SendSideBandwidthEstimation::UpdateReceiverEstimate(Timestamp at_time,
+                                                         DataRate bandwidth) {
   bwe_incoming_ = bandwidth;
-  CapBitrateToThresholds(now_ms, current_bitrate_bps_);
+  CapBitrateToThresholds(at_time, current_bitrate_);
 }
 
-void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(
-    int64_t now_ms,
-    uint32_t bitrate_bps) {
-  delay_based_bitrate_bps_ = bitrate_bps;
-  CapBitrateToThresholds(now_ms, current_bitrate_bps_);
+void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(Timestamp at_time,
+                                                           DataRate bitrate) {
+  delay_based_bitrate_ = bitrate;
+  CapBitrateToThresholds(at_time, current_bitrate_);
 }
 
 void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss,
-                                                      int64_t rtt_ms,
+                                                      TimeDelta rtt,
                                                       int number_of_packets,
-                                                      int64_t now_ms) {
+                                                      Timestamp at_time) {
   const int kRoundingConstant = 128;
   int packets_lost = (static_cast<int>(fraction_loss) * number_of_packets +
                       kRoundingConstant) >>
                      8;
-  UpdatePacketsLost(packets_lost, number_of_packets, now_ms);
-  UpdateRtt(rtt_ms, now_ms);
+  UpdatePacketsLost(packets_lost, number_of_packets, at_time);
+  UpdateRtt(rtt, at_time);
 }
 
 void SendSideBandwidthEstimation::UpdatePacketsLost(int packets_lost,
                                                     int number_of_packets,
-                                                    int64_t now_ms) {
-  last_feedback_ms_ = now_ms;
-  if (first_report_time_ms_ == -1)
-    first_report_time_ms_ = now_ms;
+                                                    Timestamp at_time) {
+  last_loss_feedback_ = at_time;
+  if (first_report_time_.IsInfinite())
+    first_report_time_ = at_time;
 
   // Check sequence number diff and weight loss report
   if (number_of_packets > 0) {
@@ -244,202 +245,201 @@
 
     lost_packets_since_last_loss_update_ = 0;
     expected_packets_since_last_loss_update_ = 0;
-    last_packet_report_ms_ = now_ms;
-    UpdateEstimate(now_ms);
+    last_loss_packet_report_ = at_time;
+    UpdateEstimate(at_time);
   }
-  UpdateUmaStatsPacketsLost(now_ms, packets_lost);
+  UpdateUmaStatsPacketsLost(at_time, packets_lost);
 }
 
-void SendSideBandwidthEstimation::UpdateUmaStatsPacketsLost(int64_t now_ms,
+void SendSideBandwidthEstimation::UpdateUmaStatsPacketsLost(Timestamp at_time,
                                                             int packets_lost) {
-  int bitrate_kbps = static_cast<int>((current_bitrate_bps_ + 500) / 1000);
+  DataRate bitrate_kbps = DataRate::kbps((current_bitrate_.bps() + 500) / 1000);
   for (size_t i = 0; i < kNumUmaRampupMetrics; ++i) {
     if (!rampup_uma_stats_updated_[i] &&
-        bitrate_kbps >= kUmaRampupMetrics[i].bitrate_kbps) {
+        bitrate_kbps.kbps() >= kUmaRampupMetrics[i].bitrate_kbps) {
       RTC_HISTOGRAMS_COUNTS_100000(i, kUmaRampupMetrics[i].metric_name,
-                                   now_ms - first_report_time_ms_);
+                                   (at_time - first_report_time_).ms());
       rampup_uma_stats_updated_[i] = true;
     }
   }
-  if (IsInStartPhase(now_ms)) {
+  if (IsInStartPhase(at_time)) {
     initially_lost_packets_ += packets_lost;
   } else if (uma_update_state_ == kNoUpdate) {
     uma_update_state_ = kFirstDone;
-    bitrate_at_2_seconds_kbps_ = bitrate_kbps;
+    bitrate_at_2_seconds_ = bitrate_kbps;
     RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitiallyLostPackets",
                          initially_lost_packets_, 0, 100, 50);
     RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialBandwidthEstimate",
-                         bitrate_at_2_seconds_kbps_, 0, 2000, 50);
+                         bitrate_at_2_seconds_.kbps(), 0, 2000, 50);
   } else if (uma_update_state_ == kFirstDone &&
-             now_ms - first_report_time_ms_ >= kBweConverganceTimeMs) {
+             at_time - first_report_time_ >= kBweConverganceTime) {
     uma_update_state_ = kDone;
-    int bitrate_diff_kbps =
-        std::max(bitrate_at_2_seconds_kbps_ - bitrate_kbps, 0);
+    int bitrate_diff_kbps = std::max(
+        bitrate_at_2_seconds_.kbps<int>() - bitrate_kbps.kbps<int>(), 0);
     RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialVsConvergedDiff", bitrate_diff_kbps,
                          0, 2000, 50);
   }
 }
 
-void SendSideBandwidthEstimation::UpdateRtt(int64_t rtt_ms, int64_t now_ms) {
+void SendSideBandwidthEstimation::UpdateRtt(TimeDelta rtt, Timestamp at_time) {
   // Update RTT if we were able to compute an RTT based on this RTCP.
   // FlexFEC doesn't send RTCP SR, which means we won't be able to compute RTT.
-  if (rtt_ms > 0)
-    last_round_trip_time_ms_ = rtt_ms;
+  if (rtt > TimeDelta::Zero())
+    last_round_trip_time_ = rtt;
 
-  if (!IsInStartPhase(now_ms) && uma_rtt_state_ == kNoUpdate) {
+  if (!IsInStartPhase(at_time) && uma_rtt_state_ == kNoUpdate) {
     uma_rtt_state_ = kDone;
-    RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialRtt", static_cast<int>(rtt_ms), 0,
-                         2000, 50);
+    RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialRtt", rtt.ms<int>(), 0, 2000, 50);
   }
 }
 
-void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) {
-  uint32_t new_bitrate = current_bitrate_bps_;
+void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) {
+  DataRate new_bitrate = current_bitrate_;
   // We trust the REMB and/or delay-based estimate during the first 2 seconds if
   // we haven't had any packet loss reported, to allow startup bitrate probing.
-  if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms)) {
+  if (last_fraction_loss_ == 0 && IsInStartPhase(at_time)) {
     new_bitrate = std::max(bwe_incoming_, new_bitrate);
-    new_bitrate = std::max(delay_based_bitrate_bps_, new_bitrate);
+    new_bitrate = std::max(delay_based_bitrate_, new_bitrate);
 
-    if (new_bitrate != current_bitrate_bps_) {
+    if (new_bitrate != current_bitrate_) {
       min_bitrate_history_.clear();
-      min_bitrate_history_.push_back(
-          std::make_pair(now_ms, current_bitrate_bps_));
-      CapBitrateToThresholds(now_ms, new_bitrate);
+      min_bitrate_history_.push_back(std::make_pair(at_time, current_bitrate_));
+      CapBitrateToThresholds(at_time, new_bitrate);
       return;
     }
   }
-  UpdateMinHistory(now_ms);
-  if (last_packet_report_ms_ == -1) {
+  UpdateMinHistory(at_time);
+  if (last_loss_packet_report_.IsInfinite()) {
     // No feedback received.
-    CapBitrateToThresholds(now_ms, current_bitrate_bps_);
+    CapBitrateToThresholds(at_time, current_bitrate_);
     return;
   }
-  int64_t time_since_packet_report_ms = now_ms - last_packet_report_ms_;
-  int64_t time_since_feedback_ms = now_ms - last_feedback_ms_;
-  if (time_since_packet_report_ms < 1.2 * kFeedbackIntervalMs) {
+  TimeDelta time_since_loss_packet_report = at_time - last_loss_packet_report_;
+  TimeDelta time_since_loss_feedback = at_time - last_loss_feedback_;
+  if (time_since_loss_packet_report < 1.2 * kMaxRtcpFeedbackInterval) {
     // We only care about loss above a given bitrate threshold.
     float loss = last_fraction_loss_ / 256.0f;
     // We only make decisions based on loss when the bitrate is above a
     // threshold. This is a crude way of handling loss which is uncorrelated
     // to congestion.
-    if (current_bitrate_bps_ < bitrate_threshold_bps_ ||
-        loss <= low_loss_threshold_) {
+    if (current_bitrate_ < bitrate_threshold_ || loss <= low_loss_threshold_) {
       // Loss < 2%: Increase rate by 8% of the min bitrate in the last
-      // kBweIncreaseIntervalMs.
+      // kBweIncreaseInterval.
       // Note that by remembering the bitrate over the last second one can
       // rampup up one second faster than if only allowed to start ramping
       // at 8% per second rate now. E.g.:
       //   If sending a constant 100kbps it can rampup immediatly to 108kbps
       //   whenever a receiver report is received with lower packet loss.
-      //   If instead one would do: current_bitrate_bps_ *= 1.08^(delta time),
+      //   If instead one would do: current_bitrate_ *= 1.08^(delta time),
       //   it would take over one second since the lower packet loss to achieve
       //   108kbps.
-      new_bitrate = static_cast<uint32_t>(
-          min_bitrate_history_.front().second * 1.08 + 0.5);
+      new_bitrate =
+          DataRate::bps(min_bitrate_history_.front().second.bps() * 1.08 + 0.5);
 
       // Add 1 kbps extra, just to make sure that we do not get stuck
       // (gives a little extra increase at low rates, negligible at higher
       // rates).
-      new_bitrate += 1000;
-    } else if (current_bitrate_bps_ > bitrate_threshold_bps_) {
+      new_bitrate += DataRate::bps(1000);
+    } else if (current_bitrate_ > bitrate_threshold_) {
       if (loss <= high_loss_threshold_) {
         // Loss between 2% - 10%: Do nothing.
       } else {
-        // Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs
+        // Loss > 10%: Limit the rate decreases to once a kBweDecreaseInterval
         // + rtt.
         if (!has_decreased_since_last_fraction_loss_ &&
-            (now_ms - time_last_decrease_ms_) >=
-                (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) {
-          time_last_decrease_ms_ = now_ms;
+            (at_time - time_last_decrease_) >=
+                (kBweDecreaseInterval + last_round_trip_time_)) {
+          time_last_decrease_ = at_time;
 
           // Reduce rate:
           //   newRate = rate * (1 - 0.5*lossRate);
           //   where packetLoss = 256*lossRate;
-          new_bitrate = static_cast<uint32_t>(
-              (current_bitrate_bps_ *
-               static_cast<double>(512 - last_fraction_loss_)) /
-              512.0);
+          new_bitrate =
+              DataRate::bps((current_bitrate_.bps() *
+                             static_cast<double>(512 - last_fraction_loss_)) /
+                            512.0);
           has_decreased_since_last_fraction_loss_ = true;
         }
       }
     }
-  } else if (time_since_feedback_ms >
-                 kFeedbackTimeoutIntervals * kFeedbackIntervalMs &&
-             (last_timeout_ms_ == -1 ||
-              now_ms - last_timeout_ms_ > kTimeoutIntervalMs)) {
+  } else if (time_since_loss_feedback >
+                 kFeedbackTimeoutIntervals * kMaxRtcpFeedbackInterval &&
+             (last_timeout_.IsInfinite() ||
+              at_time - last_timeout_ > kTimeoutInterval)) {
     if (in_timeout_experiment_) {
-      RTC_LOG(LS_WARNING) << "Feedback timed out (" << time_since_feedback_ms
-                          << " ms), reducing bitrate.";
-      new_bitrate *= 0.8;
+      RTC_LOG(LS_WARNING) << "Feedback timed out ("
+                          << ToString(time_since_loss_feedback)
+                          << "), reducing bitrate.";
+      new_bitrate = new_bitrate * 0.8;
       // Reset accumulators since we've already acted on missing feedback and
       // shouldn't to act again on these old lost packets.
       lost_packets_since_last_loss_update_ = 0;
       expected_packets_since_last_loss_update_ = 0;
-      last_timeout_ms_ = now_ms;
+      last_timeout_ = at_time;
     }
   }
 
-  CapBitrateToThresholds(now_ms, new_bitrate);
+  CapBitrateToThresholds(at_time, new_bitrate);
 }
 
-bool SendSideBandwidthEstimation::IsInStartPhase(int64_t now_ms) const {
-  return first_report_time_ms_ == -1 ||
-         now_ms - first_report_time_ms_ < kStartPhaseMs;
+bool SendSideBandwidthEstimation::IsInStartPhase(Timestamp at_time) const {
+  return first_report_time_.IsInfinite() ||
+         at_time - first_report_time_ < kStartPhase;
 }
 
-void SendSideBandwidthEstimation::UpdateMinHistory(int64_t now_ms) {
+void SendSideBandwidthEstimation::UpdateMinHistory(Timestamp at_time) {
   // Remove old data points from history.
   // Since history precision is in ms, add one so it is able to increase
   // bitrate if it is off by as little as 0.5ms.
   while (!min_bitrate_history_.empty() &&
-         now_ms - min_bitrate_history_.front().first + 1 >
-             kBweIncreaseIntervalMs) {
+         at_time - min_bitrate_history_.front().first + TimeDelta::ms(1) >
+             kBweIncreaseInterval) {
     min_bitrate_history_.pop_front();
   }
 
   // Typical minimum sliding-window algorithm: Pop values higher than current
   // bitrate before pushing it.
   while (!min_bitrate_history_.empty() &&
-         current_bitrate_bps_ <= min_bitrate_history_.back().second) {
+         current_bitrate_ <= min_bitrate_history_.back().second) {
     min_bitrate_history_.pop_back();
   }
 
-  min_bitrate_history_.push_back(std::make_pair(now_ms, current_bitrate_bps_));
+  min_bitrate_history_.push_back(std::make_pair(at_time, current_bitrate_));
 }
 
-void SendSideBandwidthEstimation::CapBitrateToThresholds(int64_t now_ms,
-                                                         uint32_t bitrate_bps) {
-  if (bwe_incoming_ > 0 && bitrate_bps > bwe_incoming_) {
-    bitrate_bps = bwe_incoming_;
+void SendSideBandwidthEstimation::CapBitrateToThresholds(Timestamp at_time,
+                                                         DataRate bitrate) {
+  if (bwe_incoming_ > DataRate::Zero() && bitrate > bwe_incoming_) {
+    bitrate = bwe_incoming_;
   }
-  if (delay_based_bitrate_bps_ > 0 && bitrate_bps > delay_based_bitrate_bps_) {
-    bitrate_bps = delay_based_bitrate_bps_;
+  if (delay_based_bitrate_ > DataRate::Zero() &&
+      bitrate > delay_based_bitrate_) {
+    bitrate = delay_based_bitrate_;
   }
-  if (bitrate_bps > max_bitrate_configured_) {
-    bitrate_bps = max_bitrate_configured_;
+  if (bitrate > max_bitrate_configured_) {
+    bitrate = max_bitrate_configured_;
   }
-  if (bitrate_bps < min_bitrate_configured_) {
-    if (last_low_bitrate_log_ms_ == -1 ||
-        now_ms - last_low_bitrate_log_ms_ > kLowBitrateLogPeriodMs) {
+  if (bitrate < min_bitrate_configured_) {
+    if (last_low_bitrate_log_.IsInfinite() ||
+        at_time - last_low_bitrate_log_ > kLowBitrateLogPeriod) {
       RTC_LOG(LS_WARNING) << "Estimated available bandwidth "
-                          << bitrate_bps / 1000
-                          << " kbps is below configured min bitrate "
-                          << min_bitrate_configured_ / 1000 << " kbps.";
-      last_low_bitrate_log_ms_ = now_ms;
+                          << ToString(bitrate)
+                          << " is below configured min bitrate "
+                          << ToString(min_bitrate_configured_) << ".";
+      last_low_bitrate_log_ = at_time;
     }
-    bitrate_bps = min_bitrate_configured_;
+    bitrate = min_bitrate_configured_;
   }
 
-  if (bitrate_bps != current_bitrate_bps_ ||
+  if (bitrate != current_bitrate_ ||
       last_fraction_loss_ != last_logged_fraction_loss_ ||
-      now_ms - last_rtc_event_log_ms_ > kRtcEventLogPeriodMs) {
+      at_time - last_rtc_event_log_ > kRtcEventLogPeriod) {
     event_log_->Log(absl::make_unique<RtcEventBweUpdateLossBased>(
-        bitrate_bps, last_fraction_loss_,
+        bitrate.bps(), last_fraction_loss_,
         expected_packets_since_last_loss_update_));
     last_logged_fraction_loss_ = last_fraction_loss_;
-    last_rtc_event_log_ms_ = now_ms;
+    last_rtc_event_log_ = at_time;
   }
-  current_bitrate_bps_ = bitrate_bps;
+  current_bitrate_ = bitrate;
 }
 }  // namespace webrtc
diff --git a/modules/bitrate_controller/send_side_bandwidth_estimation.h b/modules/bitrate_controller/send_side_bandwidth_estimation.h
index 54b571e..2c8b4ee 100644
--- a/modules/bitrate_controller/send_side_bandwidth_estimation.h
+++ b/modules/bitrate_controller/send_side_bandwidth_estimation.h
@@ -17,6 +17,7 @@
 #include <utility>
 #include <vector>
 
+#include "absl/types/optional.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 
 namespace webrtc {
@@ -32,83 +33,86 @@
   void CurrentEstimate(int* bitrate, uint8_t* loss, int64_t* rtt) const;
 
   // Call periodically to update estimate.
-  void UpdateEstimate(int64_t now_ms);
+  void UpdateEstimate(Timestamp at_time);
 
   // Call when we receive a RTCP message with TMMBR or REMB.
-  void UpdateReceiverEstimate(int64_t now_ms, uint32_t bandwidth);
+  void UpdateReceiverEstimate(Timestamp at_time, DataRate bandwidth);
 
   // Call when a new delay-based estimate is available.
-  void UpdateDelayBasedEstimate(int64_t now_ms, uint32_t bitrate_bps);
+  void UpdateDelayBasedEstimate(Timestamp at_time, DataRate bitrate);
 
   // Call when we receive a RTCP message with a ReceiveBlock.
   void UpdateReceiverBlock(uint8_t fraction_loss,
-                           int64_t rtt_ms,
+                           TimeDelta rtt_ms,
                            int number_of_packets,
-                           int64_t now_ms);
+                           Timestamp at_time);
 
   // Call when we receive a RTCP message with a ReceiveBlock.
   void UpdatePacketsLost(int packets_lost,
                          int number_of_packets,
-                         int64_t now_ms);
+                         Timestamp at_time);
 
   // Call when we receive a RTCP message with a ReceiveBlock.
-  void UpdateRtt(int64_t rtt, int64_t now_ms);
+  void UpdateRtt(TimeDelta rtt, Timestamp at_time);
 
-  void SetBitrates(int send_bitrate, int min_bitrate, int max_bitrate);
-  void SetSendBitrate(int bitrate);
-  void SetMinMaxBitrate(int min_bitrate, int max_bitrate);
+  void SetBitrates(absl::optional<DataRate> send_bitrate,
+                   DataRate min_bitrate,
+                   DataRate max_bitrate,
+                   Timestamp at_time);
+  void SetSendBitrate(DataRate bitrate, Timestamp at_time);
+  void SetMinMaxBitrate(DataRate min_bitrate, DataRate max_bitrate);
   int GetMinBitrate() const;
 
  private:
   enum UmaState { kNoUpdate, kFirstDone, kDone };
 
-  bool IsInStartPhase(int64_t now_ms) const;
+  bool IsInStartPhase(Timestamp at_time) const;
 
-  void UpdateUmaStatsPacketsLost(int64_t now_ms, int packets_lost);
+  void UpdateUmaStatsPacketsLost(Timestamp at_time, int packets_lost);
 
   // Updates history of min bitrates.
   // After this method returns min_bitrate_history_.front().second contains the
   // min bitrate used during last kBweIncreaseIntervalMs.
-  void UpdateMinHistory(int64_t now_ms);
+  void UpdateMinHistory(Timestamp at_time);
 
-  // Cap |bitrate_bps| to [min_bitrate_configured_, max_bitrate_configured_] and
-  // set |current_bitrate_bps_| to the capped value and updates the event log.
-  void CapBitrateToThresholds(int64_t now_ms, uint32_t bitrate_bps);
+  // Cap |bitrate| to [min_bitrate_configured_, max_bitrate_configured_] and
+  // set |current_bitrate_| to the capped value and updates the event log.
+  void CapBitrateToThresholds(Timestamp at_time, DataRate bitrate);
 
-  std::deque<std::pair<int64_t, uint32_t> > min_bitrate_history_;
+  std::deque<std::pair<Timestamp, DataRate> > min_bitrate_history_;
 
   // incoming filters
   int lost_packets_since_last_loss_update_;
   int expected_packets_since_last_loss_update_;
 
-  uint32_t current_bitrate_bps_;
-  uint32_t min_bitrate_configured_;
-  uint32_t max_bitrate_configured_;
-  int64_t last_low_bitrate_log_ms_;
+  DataRate current_bitrate_;
+  DataRate min_bitrate_configured_;
+  DataRate max_bitrate_configured_;
+  Timestamp last_low_bitrate_log_;
 
   bool has_decreased_since_last_fraction_loss_;
-  int64_t last_feedback_ms_;
-  int64_t last_packet_report_ms_;
-  int64_t last_timeout_ms_;
+  Timestamp last_loss_feedback_;
+  Timestamp last_loss_packet_report_;
+  Timestamp last_timeout_;
   uint8_t last_fraction_loss_;
   uint8_t last_logged_fraction_loss_;
-  int64_t last_round_trip_time_ms_;
+  TimeDelta last_round_trip_time_;
 
-  uint32_t bwe_incoming_;
-  uint32_t delay_based_bitrate_bps_;
-  int64_t time_last_decrease_ms_;
-  int64_t first_report_time_ms_;
+  DataRate bwe_incoming_;
+  DataRate delay_based_bitrate_;
+  Timestamp time_last_decrease_;
+  Timestamp first_report_time_;
   int initially_lost_packets_;
-  int bitrate_at_2_seconds_kbps_;
+  DataRate bitrate_at_2_seconds_;
   UmaState uma_update_state_;
   UmaState uma_rtt_state_;
   std::vector<bool> rampup_uma_stats_updated_;
   RtcEventLog* event_log_;
-  int64_t last_rtc_event_log_ms_;
+  Timestamp last_rtc_event_log_;
   bool in_timeout_experiment_;
   float low_loss_threshold_;
   float high_loss_threshold_;
-  uint32_t bitrate_threshold_bps_;
+  DataRate bitrate_threshold_;
 };
 }  // namespace webrtc
 #endif  // MODULES_BITRATE_CONTROLLER_SEND_SIDE_BANDWIDTH_ESTIMATION_H_
diff --git a/modules/bitrate_controller/send_side_bandwidth_estimation_unittest.cc b/modules/bitrate_controller/send_side_bandwidth_estimation_unittest.cc
index 8d5b08b..becc616 100644
--- a/modules/bitrate_controller/send_side_bandwidth_estimation_unittest.cc
+++ b/modules/bitrate_controller/send_side_bandwidth_estimation_unittest.cc
@@ -35,24 +35,25 @@
 }
 
 void TestProbing(bool use_delay_based) {
-  MockRtcEventLog event_log;
+  testing::NiceMock<MockRtcEventLog> event_log;
   SendSideBandwidthEstimation bwe(&event_log);
-  bwe.SetMinMaxBitrate(100000, 1500000);
-  bwe.SetSendBitrate(200000);
+  int64_t now_ms = 0;
+  bwe.SetMinMaxBitrate(DataRate::bps(100000), DataRate::bps(1500000));
+  bwe.SetSendBitrate(DataRate::bps(200000), Timestamp::ms(now_ms));
 
   const int kRembBps = 1000000;
   const int kSecondRembBps = kRembBps + 500000;
-  int64_t now_ms = 0;
 
-  bwe.UpdateReceiverBlock(0, 50, 1, now_ms);
+  bwe.UpdateReceiverBlock(0, TimeDelta::ms(50), 1, Timestamp::ms(now_ms));
 
   // Initial REMB applies immediately.
   if (use_delay_based) {
-    bwe.UpdateDelayBasedEstimate(now_ms, kRembBps);
+    bwe.UpdateDelayBasedEstimate(Timestamp::ms(now_ms),
+                                 DataRate::bps(kRembBps));
   } else {
-    bwe.UpdateReceiverEstimate(now_ms, kRembBps);
+    bwe.UpdateReceiverEstimate(Timestamp::ms(now_ms), DataRate::bps(kRembBps));
   }
-  bwe.UpdateEstimate(now_ms);
+  bwe.UpdateEstimate(Timestamp::ms(now_ms));
   int bitrate;
   uint8_t fraction_loss;
   int64_t rtt;
@@ -62,11 +63,13 @@
   // Second REMB doesn't apply immediately.
   now_ms += 2001;
   if (use_delay_based) {
-    bwe.UpdateDelayBasedEstimate(now_ms, kSecondRembBps);
+    bwe.UpdateDelayBasedEstimate(Timestamp::ms(now_ms),
+                                 DataRate::bps(kSecondRembBps));
   } else {
-    bwe.UpdateReceiverEstimate(now_ms, kSecondRembBps);
+    bwe.UpdateReceiverEstimate(Timestamp::ms(now_ms),
+                               DataRate::bps(kSecondRembBps));
   }
-  bwe.UpdateEstimate(now_ms);
+  bwe.UpdateEstimate(Timestamp::ms(now_ms));
   bitrate = 0;
   bwe.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
   EXPECT_EQ(kRembBps, bitrate);
@@ -86,17 +89,18 @@
       .Times(1);
   EXPECT_CALL(event_log,
               LogProxy(LossBasedBweUpdateWithBitrateAndLossFraction()))
-      .Times(2);
+      .Times(1);
   SendSideBandwidthEstimation bwe(&event_log);
   static const int kMinBitrateBps = 100000;
   static const int kInitialBitrateBps = 1000000;
-  bwe.SetMinMaxBitrate(kMinBitrateBps, 1500000);
-  bwe.SetSendBitrate(kInitialBitrateBps);
+  int64_t now_ms = 1000;
+  bwe.SetMinMaxBitrate(DataRate::bps(kMinBitrateBps), DataRate::bps(1500000));
+  bwe.SetSendBitrate(DataRate::bps(kInitialBitrateBps), Timestamp::ms(now_ms));
 
   static const uint8_t kFractionLoss = 128;
   static const int64_t kRttMs = 50;
+  now_ms += 10000;
 
-  int64_t now_ms = 0;
   int bitrate_bps;
   uint8_t fraction_loss;
   int64_t rtt_ms;
@@ -106,10 +110,11 @@
   EXPECT_EQ(0, rtt_ms);
 
   // Signal heavy loss to go down in bitrate.
-  bwe.UpdateReceiverBlock(kFractionLoss, kRttMs, 100, now_ms);
+  bwe.UpdateReceiverBlock(kFractionLoss, TimeDelta::ms(kRttMs), 100,
+                          Timestamp::ms(now_ms));
   // Trigger an update 2 seconds later to not be rate limited.
   now_ms += 1000;
-  bwe.UpdateEstimate(now_ms);
+  bwe.UpdateEstimate(Timestamp::ms(now_ms));
 
   bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
   EXPECT_LT(bitrate_bps, kInitialBitrateBps);
@@ -127,7 +132,7 @@
   // Trigger an update 2 seconds later to not be rate limited (but it still
   // shouldn't update).
   now_ms += 1000;
-  bwe.UpdateEstimate(now_ms);
+  bwe.UpdateEstimate(Timestamp::ms(now_ms));
   bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
 
   EXPECT_EQ(last_bitrate_bps, bitrate_bps);
@@ -150,16 +155,18 @@
   uint8_t fraction_loss;
   int64_t rtt_ms;
 
-  bwe.SetMinMaxBitrate(kMinBitrateBps, kMaxBitrateBps);
-  bwe.SetSendBitrate(kInitialBitrateBps);
+  bwe.SetMinMaxBitrate(DataRate::bps(kMinBitrateBps),
+                       DataRate::bps(kMaxBitrateBps));
+  bwe.SetSendBitrate(DataRate::bps(kInitialBitrateBps), Timestamp::ms(now_ms));
 
-  bwe.UpdateDelayBasedEstimate(now_ms, kDelayBasedBitrateBps);
-  bwe.UpdateEstimate(now_ms);
+  bwe.UpdateDelayBasedEstimate(Timestamp::ms(now_ms),
+                               DataRate::bps(kDelayBasedBitrateBps));
+  bwe.UpdateEstimate(Timestamp::ms(now_ms));
   bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
   EXPECT_GE(bitrate_bps, kInitialBitrateBps);
   EXPECT_LE(bitrate_bps, kDelayBasedBitrateBps);
 
-  bwe.SetSendBitrate(kForcedHighBitrate);
+  bwe.SetSendBitrate(DataRate::bps(kForcedHighBitrate), Timestamp::ms(now_ms));
   bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
   EXPECT_EQ(bitrate_bps, kForcedHighBitrate);
 }
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
index 7ad65ce..4ab9694 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
@@ -158,7 +158,7 @@
 
 NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
     NetworkRouteChange msg) {
-  int64_t min_bitrate_bps = GetBpsOrDefault(msg.constraints.min_data_rate, -1);
+  int64_t min_bitrate_bps = GetBpsOrDefault(msg.constraints.min_data_rate, 0);
   int64_t max_bitrate_bps = GetBpsOrDefault(msg.constraints.max_data_rate, -1);
   int64_t start_bitrate_bps =
       GetBpsOrDefault(msg.constraints.starting_rate, -1);
@@ -167,8 +167,10 @@
 
   bandwidth_estimation_ =
       absl::make_unique<SendSideBandwidthEstimation>(event_log_);
-  bandwidth_estimation_->SetBitrates(start_bitrate_bps, min_bitrate_bps,
-                                     max_bitrate_bps);
+  bandwidth_estimation_->SetBitrates(
+      msg.constraints.starting_rate, DataRate::bps(min_bitrate_bps),
+      msg.constraints.max_data_rate.value_or(DataRate::Infinity()),
+      msg.at_time);
   delay_based_bwe_.reset(new DelayBasedBwe(event_log_));
   acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator());
   delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
@@ -206,7 +208,7 @@
     initial_config_.reset();
   }
 
-  bandwidth_estimation_->UpdateEstimate(msg.at_time.ms());
+  bandwidth_estimation_->UpdateEstimate(msg.at_time);
   absl::optional<int64_t> start_time_ms =
       alr_detector_->GetApplicationLimitedRegionStartTime();
   probe_controller_->SetAlrStartTimeMs(start_time_ms);
@@ -225,8 +227,8 @@
     RTC_LOG(LS_ERROR) << "Received REMB for packet feedback only GoogCC";
     return NetworkControlUpdate();
   }
-  bandwidth_estimation_->UpdateReceiverEstimate(msg.receive_time.ms(),
-                                                msg.bandwidth.bps());
+  bandwidth_estimation_->UpdateReceiverEstimate(msg.receive_time,
+                                                msg.bandwidth);
   BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", msg.receive_time.ms(),
                         msg.bandwidth.bps() / 1000);
   return NetworkControlUpdate();
@@ -239,8 +241,7 @@
   if (msg.smoothed) {
     delay_based_bwe_->OnRttUpdate(msg.round_trip_time.ms());
   } else {
-    bandwidth_estimation_->UpdateRtt(msg.round_trip_time.ms(),
-                                     msg.receive_time.ms());
+    bandwidth_estimation_->UpdateRtt(msg.round_trip_time, msg.receive_time);
   }
   return NetworkControlUpdate();
 }
@@ -307,8 +308,10 @@
       min_bitrate_bps, start_bitrate_bps, max_bitrate_bps,
       constraints.at_time.ms()));
 
-  bandwidth_estimation_->SetBitrates(start_bitrate_bps, min_bitrate_bps,
-                                     max_bitrate_bps);
+  bandwidth_estimation_->SetBitrates(
+      starting_rate, DataRate::bps(min_bitrate_bps),
+      constraints.max_data_rate.value_or(DataRate::Infinity()),
+      constraints.at_time);
   if (start_bitrate_bps > 0)
     delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
   delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
@@ -322,7 +325,7 @@
   int64_t total_packets_delta =
       msg.packets_received_delta + msg.packets_lost_delta;
   bandwidth_estimation_->UpdatePacketsLost(
-      msg.packets_lost_delta, total_packets_delta, msg.receive_time.ms());
+      msg.packets_lost_delta, total_packets_delta, msg.receive_time);
   return NetworkControlUpdate();
 }
 
@@ -364,8 +367,7 @@
       feedback_min_rtt = std::min(rtt, feedback_min_rtt);
     }
     if (feedback_min_rtt.IsFinite()) {
-      bandwidth_estimation_->UpdateRtt(feedback_min_rtt.ms(),
-                                       report.feedback_time.ms());
+      bandwidth_estimation_->UpdateRtt(feedback_min_rtt, report.feedback_time);
     }
 
     expected_packets_since_last_loss_update_ +=
@@ -378,7 +380,7 @@
       next_loss_update_ = report.feedback_time + kLossUpdateInterval;
       bandwidth_estimation_->UpdatePacketsLost(
           lost_packets_since_last_loss_update_,
-          expected_packets_since_last_loss_update_, report.feedback_time.ms());
+          expected_packets_since_last_loss_update_, report.feedback_time);
       expected_packets_since_last_loss_update_ = 0;
       lost_packets_since_last_loss_update_ = 0;
     }
@@ -407,12 +409,13 @@
   NetworkControlUpdate update;
   if (result.updated) {
     if (result.probe) {
-      bandwidth_estimation_->SetSendBitrate(result.target_bitrate_bps);
+      bandwidth_estimation_->SetSendBitrate(
+          DataRate::bps(result.target_bitrate_bps), report.feedback_time);
     }
     // Since SetSendBitrate now resets the delay-based estimate, we have to call
     // UpdateDelayBasedEstimate after SetSendBitrate.
-    bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time.ms(),
-                                                    result.target_bitrate_bps);
+    bandwidth_estimation_->UpdateDelayBasedEstimate(
+        report.feedback_time, DataRate::bps(result.target_bitrate_bps));
     // Update the estimate in the ProbeController, in case we want to probe.
     MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
   }
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
index ea561a6..e3f3abf 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
@@ -91,9 +91,10 @@
     return packet_result;
   }
 
-  NetworkRouteChange CreateRouteChange(DataRate start_rate = DataRate::Zero(),
-                                       DataRate min_rate = DataRate::Zero(),
-                                       DataRate max_rate = DataRate::Zero()) {
+  NetworkRouteChange CreateRouteChange(
+      absl::optional<DataRate> start_rate = absl::nullopt,
+      absl::optional<DataRate> min_rate = absl::nullopt,
+      absl::optional<DataRate> max_rate = absl::nullopt) {
     NetworkRouteChange route_change;
     route_change.at_time = current_time_;
     route_change.constraints.at_time = current_time_;
diff --git a/modules/remote_bitrate_estimator/BUILD.gn b/modules/remote_bitrate_estimator/BUILD.gn
index 13fbad3..a8d6850 100644
--- a/modules/remote_bitrate_estimator/BUILD.gn
+++ b/modules/remote_bitrate_estimator/BUILD.gn
@@ -41,6 +41,7 @@
 
   deps = [
     "../..:webrtc_common",
+    "../../api/units:data_rate",
     "../../modules:module_api",
     "../../modules/rtp_rtcp:rtp_rtcp_format",
     "../../rtc_base:checks",
diff --git a/modules/remote_bitrate_estimator/bwe_defines.cc b/modules/remote_bitrate_estimator/bwe_defines.cc
index 35f1d19..6cbe468 100644
--- a/modules/remote_bitrate_estimator/bwe_defines.cc
+++ b/modules/remote_bitrate_estimator/bwe_defines.cc
@@ -26,6 +26,10 @@
   return kMinBitrateBps;
 }
 
+DataRate GetMinBitrate() {
+  return DataRate::bps(GetMinBitrateBps());
+}
+
 }  // namespace congestion_controller
 
 RateControlInput::RateControlInput(
diff --git a/modules/remote_bitrate_estimator/include/bwe_defines.h b/modules/remote_bitrate_estimator/include/bwe_defines.h
index 0d8c49b..d9185de 100644
--- a/modules/remote_bitrate_estimator/include/bwe_defines.h
+++ b/modules/remote_bitrate_estimator/include/bwe_defines.h
@@ -12,6 +12,7 @@
 #define MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_BWE_DEFINES_H_
 
 #include "absl/types/optional.h"
+#include "api/units/data_rate.h"
 
 #define BWE_MAX(a, b) ((a) > (b) ? (a) : (b))
 #define BWE_MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -20,6 +21,7 @@
 
 namespace congestion_controller {
 int GetMinBitrateBps();
+DataRate GetMinBitrate();
 }  // namespace congestion_controller
 
 static const int64_t kBitrateWindowMs = 1000;