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