xref: /aosp_15_r20/external/webrtc/modules/congestion_controller/goog_cc/alr_detector.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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