1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 *
10 */
11
12#include "webrtc/modules/bitrate_controller/bitrate_controller_impl.h"
13
14#include <algorithm>
15#include <utility>
16
17#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
18
19namespace webrtc {
20
21class BitrateControllerImpl::RtcpBandwidthObserverImpl
22    : public RtcpBandwidthObserver {
23 public:
24  explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
25      : owner_(owner) {
26  }
27  virtual ~RtcpBandwidthObserverImpl() {
28  }
29  // Received RTCP REMB or TMMBR.
30  void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
31    owner_->OnReceivedEstimatedBitrate(bitrate);
32  }
33  // Received RTCP receiver block.
34  void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
35                                    int64_t rtt,
36                                    int64_t now_ms) override {
37    if (report_blocks.empty())
38      return;
39
40    int fraction_lost_aggregate = 0;
41    int total_number_of_packets = 0;
42
43    // Compute the a weighted average of the fraction loss from all report
44    // blocks.
45    for (ReportBlockList::const_iterator it = report_blocks.begin();
46        it != report_blocks.end(); ++it) {
47      std::map<uint32_t, uint32_t>::iterator seq_num_it =
48          ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC);
49
50      int number_of_packets = 0;
51      if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end())
52        number_of_packets = it->extendedHighSeqNum -
53            seq_num_it->second;
54
55      fraction_lost_aggregate += number_of_packets * it->fractionLost;
56      total_number_of_packets += number_of_packets;
57
58      // Update last received for this SSRC.
59      ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] =
60          it->extendedHighSeqNum;
61    }
62    if (total_number_of_packets == 0)
63      fraction_lost_aggregate = 0;
64    else
65      fraction_lost_aggregate  = (fraction_lost_aggregate +
66          total_number_of_packets / 2) / total_number_of_packets;
67    if (fraction_lost_aggregate > 255)
68      return;
69
70    owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
71                                         total_number_of_packets, now_ms);
72  }
73
74 private:
75  std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;
76  BitrateControllerImpl* owner_;
77};
78
79BitrateController* BitrateController::CreateBitrateController(
80    Clock* clock,
81    BitrateObserver* observer) {
82  return new BitrateControllerImpl(clock, observer);
83}
84
85BitrateControllerImpl::BitrateControllerImpl(Clock* clock,
86                                             BitrateObserver* observer)
87    : clock_(clock),
88      observer_(observer),
89      last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
90      bandwidth_estimation_(),
91      reserved_bitrate_bps_(0),
92      last_bitrate_bps_(0),
93      last_fraction_loss_(0),
94      last_rtt_ms_(0),
95      last_reserved_bitrate_bps_(0) {
96  // This calls the observer_, which means that the observer provided by the
97  // user must be ready to accept a bitrate update when it constructs the
98  // controller. We do this to avoid having to keep synchronized initial values
99  // in both the controller and the allocator.
100  MaybeTriggerOnNetworkChanged();
101}
102
103RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
104  return new RtcpBandwidthObserverImpl(this);
105}
106
107void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
108  {
109    rtc::CritScope cs(&critsect_);
110    bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
111  }
112  MaybeTriggerOnNetworkChanged();
113}
114
115void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
116                                             int max_bitrate_bps) {
117  {
118    rtc::CritScope cs(&critsect_);
119    bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
120  }
121  MaybeTriggerOnNetworkChanged();
122}
123
124void BitrateControllerImpl::SetReservedBitrate(uint32_t reserved_bitrate_bps) {
125  {
126    rtc::CritScope cs(&critsect_);
127    reserved_bitrate_bps_ = reserved_bitrate_bps;
128  }
129  MaybeTriggerOnNetworkChanged();
130}
131
132void BitrateControllerImpl::SetEventLog(RtcEventLog* event_log) {
133  rtc::CritScope cs(&critsect_);
134  bandwidth_estimation_.SetEventLog(event_log);
135}
136
137void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
138  {
139    rtc::CritScope cs(&critsect_);
140    bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(),
141                                                 bitrate);
142  }
143  MaybeTriggerOnNetworkChanged();
144}
145
146int64_t BitrateControllerImpl::TimeUntilNextProcess() {
147  const int64_t kBitrateControllerUpdateIntervalMs = 25;
148  rtc::CritScope cs(&critsect_);
149  int64_t time_since_update_ms =
150      clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
151  return std::max<int64_t>(
152      kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
153}
154
155int32_t BitrateControllerImpl::Process() {
156  if (TimeUntilNextProcess() > 0)
157    return 0;
158  {
159    rtc::CritScope cs(&critsect_);
160    bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
161  }
162  MaybeTriggerOnNetworkChanged();
163  last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
164  return 0;
165}
166
167void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
168    uint8_t fraction_loss,
169    int64_t rtt,
170    int number_of_packets,
171    int64_t now_ms) {
172  {
173    rtc::CritScope cs(&critsect_);
174    bandwidth_estimation_.UpdateReceiverBlock(fraction_loss, rtt,
175                                              number_of_packets, now_ms);
176  }
177  MaybeTriggerOnNetworkChanged();
178}
179
180void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
181  uint32_t bitrate;
182  uint8_t fraction_loss;
183  int64_t rtt;
184  if (GetNetworkParameters(&bitrate, &fraction_loss, &rtt))
185    observer_->OnNetworkChanged(bitrate, fraction_loss, rtt);
186}
187
188bool BitrateControllerImpl::GetNetworkParameters(uint32_t* bitrate,
189                                                 uint8_t* fraction_loss,
190                                                 int64_t* rtt) {
191  rtc::CritScope cs(&critsect_);
192  int current_bitrate;
193  bandwidth_estimation_.CurrentEstimate(&current_bitrate, fraction_loss, rtt);
194  *bitrate = current_bitrate;
195  *bitrate -= std::min(*bitrate, reserved_bitrate_bps_);
196  *bitrate =
197      std::max<uint32_t>(*bitrate, bandwidth_estimation_.GetMinBitrate());
198
199  bool new_bitrate = false;
200  if (*bitrate != last_bitrate_bps_ || *fraction_loss != last_fraction_loss_ ||
201      *rtt != last_rtt_ms_ ||
202      last_reserved_bitrate_bps_ != reserved_bitrate_bps_) {
203    last_bitrate_bps_ = *bitrate;
204    last_fraction_loss_ = *fraction_loss;
205    last_rtt_ms_ = *rtt;
206    last_reserved_bitrate_bps_ = reserved_bitrate_bps_;
207    new_bitrate = true;
208  }
209  return new_bitrate;
210}
211
212bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
213  rtc::CritScope cs(&critsect_);
214  int bitrate;
215  uint8_t fraction_loss;
216  int64_t rtt;
217  bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
218  if (bitrate > 0) {
219    bitrate = bitrate - std::min<int>(bitrate, reserved_bitrate_bps_);
220    bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
221    *bandwidth = bitrate;
222    return true;
223  }
224  return false;
225}
226}  // namespace webrtc
227