1 /*
2 * Copyright (c) 2016 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 #include "modules/congestion_controller/goog_cc/alr_detector.h"
12
13 #include <cstdint>
14 #include <cstdio>
15 #include <memory>
16
17 #include "api/rtc_event_log/rtc_event.h"
18 #include "api/rtc_event_log/rtc_event_log.h"
19 #include "logging/rtc_event_log/events/rtc_event_alr_state.h"
20 #include "rtc_base/checks.h"
21 #include "rtc_base/numerics/safe_conversions.h"
22 #include "rtc_base/time_utils.h"
23
24 namespace webrtc {
25
26 namespace {
GetConfigFromTrials(const WebRtcKeyValueConfig * key_value_config)27 AlrDetectorConfig GetConfigFromTrials(
28 const WebRtcKeyValueConfig* key_value_config) {
29 RTC_CHECK(AlrExperimentSettings::MaxOneFieldTrialEnabled(*key_value_config));
30 absl::optional<AlrExperimentSettings> experiment_settings =
31 AlrExperimentSettings::CreateFromFieldTrial(
32 *key_value_config,
33 AlrExperimentSettings::kScreenshareProbingBweExperimentName);
34 if (!experiment_settings) {
35 experiment_settings = AlrExperimentSettings::CreateFromFieldTrial(
36 *key_value_config,
37 AlrExperimentSettings::kStrictPacingAndProbingExperimentName);
38 }
39 AlrDetectorConfig conf;
40 if (experiment_settings) {
41 conf.bandwidth_usage_ratio =
42 experiment_settings->alr_bandwidth_usage_percent / 100.0;
43 conf.start_budget_level_ratio =
44 experiment_settings->alr_start_budget_level_percent / 100.0;
45 conf.stop_budget_level_ratio =
46 experiment_settings->alr_stop_budget_level_percent / 100.0;
47 }
48 conf.Parser()->Parse(
49 key_value_config->Lookup("WebRTC-AlrDetectorParameters"));
50 return conf;
51 }
52 } // namespace
53
Parser()54 std::unique_ptr<StructParametersParser> AlrDetectorConfig::Parser() {
55 return StructParametersParser::Create( //
56 "bw_usage", &bandwidth_usage_ratio, //
57 "start", &start_budget_level_ratio, //
58 "stop", &stop_budget_level_ratio);
59 }
60
AlrDetector(AlrDetectorConfig config,RtcEventLog * event_log)61 AlrDetector::AlrDetector(AlrDetectorConfig config, RtcEventLog* event_log)
62 : conf_(config), alr_budget_(0, true), event_log_(event_log) {}
63
AlrDetector(const WebRtcKeyValueConfig * key_value_config)64 AlrDetector::AlrDetector(const WebRtcKeyValueConfig* key_value_config)
65 : AlrDetector(GetConfigFromTrials(key_value_config), nullptr) {}
66
AlrDetector(const WebRtcKeyValueConfig * key_value_config,RtcEventLog * event_log)67 AlrDetector::AlrDetector(const WebRtcKeyValueConfig* key_value_config,
68 RtcEventLog* event_log)
69 : AlrDetector(GetConfigFromTrials(key_value_config), event_log) {}
~AlrDetector()70 AlrDetector::~AlrDetector() {}
71
OnBytesSent(size_t bytes_sent,int64_t send_time_ms)72 void AlrDetector::OnBytesSent(size_t bytes_sent, int64_t send_time_ms) {
73 if (!last_send_time_ms_.has_value()) {
74 last_send_time_ms_ = send_time_ms;
75 // Since the duration for sending the bytes is unknwon, return without
76 // updating alr state.
77 return;
78 }
79 int64_t delta_time_ms = send_time_ms - *last_send_time_ms_;
80 last_send_time_ms_ = send_time_ms;
81
82 alr_budget_.UseBudget(bytes_sent);
83 alr_budget_.IncreaseBudget(delta_time_ms);
84 bool state_changed = false;
85 if (alr_budget_.budget_ratio() > conf_.start_budget_level_ratio &&
86 !alr_started_time_ms_) {
87 alr_started_time_ms_.emplace(rtc::TimeMillis());
88 state_changed = true;
89 } else if (alr_budget_.budget_ratio() < conf_.stop_budget_level_ratio &&
90 alr_started_time_ms_) {
91 state_changed = true;
92 alr_started_time_ms_.reset();
93 }
94 if (event_log_ && state_changed) {
95 event_log_->Log(
96 std::make_unique<RtcEventAlrState>(alr_started_time_ms_.has_value()));
97 }
98 }
99
SetEstimatedBitrate(int bitrate_bps)100 void AlrDetector::SetEstimatedBitrate(int bitrate_bps) {
101 RTC_DCHECK(bitrate_bps);
102 int target_rate_kbps =
103 static_cast<double>(bitrate_bps) * conf_.bandwidth_usage_ratio / 1000;
104 alr_budget_.set_target_rate_kbps(target_rate_kbps);
105 }
106
GetApplicationLimitedRegionStartTime() const107 absl::optional<int64_t> AlrDetector::GetApplicationLimitedRegionStartTime()
108 const {
109 return alr_started_time_ms_;
110 }
111
112 } // namespace webrtc
113