1 /*
2 * Copyright 2020 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 "video/adaptation/quality_rampup_experiment_helper.h"
12
13 #include <memory>
14 #include <utility>
15
16 #include "rtc_base/logging.h"
17
18 namespace webrtc {
19
QualityRampUpExperimentHelper(QualityRampUpExperimentListener * experiment_listener,Clock * clock,QualityRampupExperiment experiment)20 QualityRampUpExperimentHelper::QualityRampUpExperimentHelper(
21 QualityRampUpExperimentListener* experiment_listener,
22 Clock* clock,
23 QualityRampupExperiment experiment)
24 : experiment_listener_(experiment_listener),
25 clock_(clock),
26 quality_rampup_experiment_(std::move(experiment)),
27 cpu_adapted_(false),
28 qp_resolution_adaptations_(0) {
29 RTC_DCHECK(experiment_listener_);
30 RTC_DCHECK(clock_);
31 }
32
33 std::unique_ptr<QualityRampUpExperimentHelper>
CreateIfEnabled(QualityRampUpExperimentListener * experiment_listener,Clock * clock)34 QualityRampUpExperimentHelper::CreateIfEnabled(
35 QualityRampUpExperimentListener* experiment_listener,
36 Clock* clock) {
37 QualityRampupExperiment experiment = QualityRampupExperiment::ParseSettings();
38 if (experiment.Enabled()) {
39 return std::unique_ptr<QualityRampUpExperimentHelper>(
40 new QualityRampUpExperimentHelper(experiment_listener, clock,
41 experiment));
42 }
43 return nullptr;
44 }
45
ConfigureQualityRampupExperiment(bool reset,absl::optional<uint32_t> pixels,absl::optional<DataRate> max_bitrate)46 void QualityRampUpExperimentHelper::ConfigureQualityRampupExperiment(
47 bool reset,
48 absl::optional<uint32_t> pixels,
49 absl::optional<DataRate> max_bitrate) {
50 if (reset)
51 quality_rampup_experiment_.Reset();
52 if (pixels && max_bitrate)
53 quality_rampup_experiment_.SetMaxBitrate(*pixels, max_bitrate->kbps());
54 }
55
PerformQualityRampupExperiment(rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource,DataRate bandwidth,DataRate encoder_target_bitrate,absl::optional<DataRate> max_bitrate)56 void QualityRampUpExperimentHelper::PerformQualityRampupExperiment(
57 rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource,
58 DataRate bandwidth,
59 DataRate encoder_target_bitrate,
60 absl::optional<DataRate> max_bitrate) {
61 if (!quality_scaler_resource->is_started() || !max_bitrate)
62 return;
63
64 int64_t now_ms = clock_->TimeInMilliseconds();
65
66 bool try_quality_rampup = false;
67 if (quality_rampup_experiment_.BwHigh(now_ms, bandwidth.kbps())) {
68 // Verify that encoder is at max bitrate and the QP is low.
69 if (encoder_target_bitrate == *max_bitrate &&
70 quality_scaler_resource->QpFastFilterLow()) {
71 try_quality_rampup = true;
72 }
73 }
74 if (try_quality_rampup && qp_resolution_adaptations_ > 0 && !cpu_adapted_) {
75 experiment_listener_->OnQualityRampUp();
76 }
77 }
78
cpu_adapted(bool cpu_adapted)79 void QualityRampUpExperimentHelper::cpu_adapted(bool cpu_adapted) {
80 cpu_adapted_ = cpu_adapted;
81 }
82
qp_resolution_adaptations(int qp_resolution_adaptations)83 void QualityRampUpExperimentHelper::qp_resolution_adaptations(
84 int qp_resolution_adaptations) {
85 qp_resolution_adaptations_ = qp_resolution_adaptations;
86 }
87
88 } // namespace webrtc
89