From ceab7547f027ea3b5da3389eb018b1d88bd10b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85sa=20Persson?= Date: Mon, 21 Sep 2020 14:57:04 +0200 Subject: [PATCH] Make LibvpxVp8Encoder::GetCpuSpeed() to always read from CpuSpeedExperiment for arm. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CpuSpeedExperiment: Add option to have a separate config for cores below a configurable threshold. Bug: none Change-Id: I51562979f3a89a949d014a1ee6fc0802f3c1dae5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184926 Reviewed-by: Rasmus Brandt Commit-Queue: Åsa Persson Cr-Commit-Position: refs/heads/master@{#32154} --- .../codecs/vp8/libvpx_vp8_encoder.cc | 12 ++-- rtc_base/experiments/cpu_speed_experiment.cc | 27 ++++++--- rtc_base/experiments/cpu_speed_experiment.h | 23 +++++++- .../cpu_speed_experiment_unittest.cc | 56 +++++++++++++------ 4 files changed, 89 insertions(+), 29 deletions(-) diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index 847499c0e4..ceb0a2ec4c 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -729,13 +729,17 @@ int LibvpxVp8Encoder::GetCpuSpeed(int width, int height) { // On mobile platform, use a lower speed setting for lower resolutions for // CPUs with 4 or more cores. RTC_DCHECK_GT(number_of_cores_, 0); + if (experimental_cpu_speed_config_arm_ + .GetValue(width * height, number_of_cores_) + .has_value()) { + return experimental_cpu_speed_config_arm_ + .GetValue(width * height, number_of_cores_) + .value(); + } + if (number_of_cores_ <= 3) return -12; - if (experimental_cpu_speed_config_arm_.GetValue(width * height).has_value()) { - return experimental_cpu_speed_config_arm_.GetValue(width * height).value(); - } - if (width * height <= 352 * 288) return -8; else if (width * height <= 640 * 480) diff --git a/rtc_base/experiments/cpu_speed_experiment.cc b/rtc_base/experiments/cpu_speed_experiment.cc index 3d68b8acca..0f53320093 100644 --- a/rtc_base/experiments/cpu_speed_experiment.cc +++ b/rtc_base/experiments/cpu_speed_experiment.cc @@ -13,7 +13,6 @@ #include #include "rtc_base/experiments/field_trial_list.h" -#include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/logging.h" #include "system_wrappers/include/field_trial.h" @@ -47,29 +46,43 @@ std::vector GetValidOrEmpty( return configs; } + +bool HasLeCores(const std::vector& configs) { + for (const auto& config : configs) { + if (config.cpu_speed_le_cores == 0) + return false; + } + return true; +} } // namespace -CpuSpeedExperiment::CpuSpeedExperiment() { +CpuSpeedExperiment::CpuSpeedExperiment() : cores_("cores") { FieldTrialStructList configs( {FieldTrialStructMember("pixels", [](Config* c) { return &c->pixels; }), FieldTrialStructMember("cpu_speed", - [](Config* c) { return &c->cpu_speed; })}, + [](Config* c) { return &c->cpu_speed; }), + FieldTrialStructMember( + "cpu_speed_le_cores", + [](Config* c) { return &c->cpu_speed_le_cores; })}, {}); - - ParseFieldTrial({&configs}, field_trial::FindFullName(kFieldTrial)); + ParseFieldTrial({&configs, &cores_}, field_trial::FindFullName(kFieldTrial)); configs_ = GetValidOrEmpty(configs.Get()); } CpuSpeedExperiment::~CpuSpeedExperiment() {} -absl::optional CpuSpeedExperiment::GetValue(int pixels) const { +absl::optional CpuSpeedExperiment::GetValue(int pixels, + int num_cores) const { if (configs_.empty()) return absl::nullopt; + bool use_le = HasLeCores(configs_) && cores_ && num_cores <= cores_.Value(); + for (const auto& config : configs_) { if (pixels <= config.pixels) - return absl::optional(config.cpu_speed); + return use_le ? absl::optional(config.cpu_speed_le_cores) + : absl::optional(config.cpu_speed); } return absl::optional(kMinSetting); } diff --git a/rtc_base/experiments/cpu_speed_experiment.h b/rtc_base/experiments/cpu_speed_experiment.h index a788508903..7c7268c559 100644 --- a/rtc_base/experiments/cpu_speed_experiment.h +++ b/rtc_base/experiments/cpu_speed_experiment.h @@ -15,6 +15,8 @@ #include "absl/types/optional.h" +#include "rtc_base/experiments/field_trial_parser.h" + namespace webrtc { class CpuSpeedExperiment { @@ -28,17 +30,34 @@ class CpuSpeedExperiment { // pixels <= 200 -> cpu speed: -2 // pixels <= 300 -> cpu speed: -3 + // WebRTC-VP8-CpuSpeed-Arm/pixels:100|200|300,cpu_speed:-1|-2|-3/, + // cpu_speed_le_cores:-4|-5|-6,cores:3/ + // If |num_cores| > 3 + // pixels <= 100 -> cpu speed: -1 + // pixels <= 200 -> cpu speed: -2 + // pixels <= 300 -> cpu speed: -3 + // else + // pixels <= 100 -> cpu speed: -4 + // pixels <= 200 -> cpu speed: -5 + // pixels <= 300 -> cpu speed: -6 + struct Config { int pixels = 0; // The video frame size. int cpu_speed = 0; // The |cpu_speed| to be used if the frame size is less // than or equal to |pixels|. + // Optional. + int cpu_speed_le_cores = 0; // Same as |cpu_speed| above but only used if + // |num_cores| <= |cores_|. }; - // Gets the cpu speed based on |pixels|. - absl::optional GetValue(int pixels) const; + // Gets the cpu speed based on |pixels| and |num_cores|. + absl::optional GetValue(int pixels, int num_cores) const; private: std::vector configs_; + + // Threshold for when to use |cpu_speed_le_cores|. + FieldTrialOptional cores_; }; } // namespace webrtc diff --git a/rtc_base/experiments/cpu_speed_experiment_unittest.cc b/rtc_base/experiments/cpu_speed_experiment_unittest.cc index 2a73238305..2105da3818 100644 --- a/rtc_base/experiments/cpu_speed_experiment_unittest.cc +++ b/rtc_base/experiments/cpu_speed_experiment_unittest.cc @@ -18,17 +18,17 @@ namespace webrtc { TEST(CpuSpeedExperimentTest, NoValueIfNotEnabled) { CpuSpeedExperiment cpu_speed_config; - EXPECT_FALSE(cpu_speed_config.GetValue(1)); + EXPECT_FALSE(cpu_speed_config.GetValue(1, /*num_cores=*/1)); } TEST(CpuSpeedExperimentTest, GetValue) { webrtc::test::ScopedFieldTrials field_trials( - "WebRTC-VP8-CpuSpeed-Arm/pixels:1000,cpu_speed:-12/"); + "WebRTC-VP8-CpuSpeed-Arm/pixels:1000,cpu_speed:-12,cores:4/"); CpuSpeedExperiment cpu_speed_config; - EXPECT_EQ(-12, cpu_speed_config.GetValue(1)); - EXPECT_EQ(-12, cpu_speed_config.GetValue(1000)); - EXPECT_EQ(-16, cpu_speed_config.GetValue(1001)); + EXPECT_EQ(-12, cpu_speed_config.GetValue(1, /*num_cores=*/1)); + EXPECT_EQ(-12, cpu_speed_config.GetValue(1000, /*num_cores=*/1)); + EXPECT_EQ(-16, cpu_speed_config.GetValue(1001, /*num_cores=*/1)); } TEST(CpuSpeedExperimentTest, GetValueWithList) { @@ -36,13 +36,37 @@ TEST(CpuSpeedExperimentTest, GetValueWithList) { "WebRTC-VP8-CpuSpeed-Arm/pixels:1000|2000|3000,cpu_speed:-1|-10|-16/"); CpuSpeedExperiment cpu_speed_config; - EXPECT_EQ(-1, cpu_speed_config.GetValue(1)); - EXPECT_EQ(-1, cpu_speed_config.GetValue(1000)); - EXPECT_EQ(-10, cpu_speed_config.GetValue(1001)); - EXPECT_EQ(-10, cpu_speed_config.GetValue(2000)); - EXPECT_EQ(-16, cpu_speed_config.GetValue(2001)); - EXPECT_EQ(-16, cpu_speed_config.GetValue(3000)); - EXPECT_EQ(-16, cpu_speed_config.GetValue(3001)); + EXPECT_EQ(-1, cpu_speed_config.GetValue(1, /*num_cores=*/1)); + EXPECT_EQ(-1, cpu_speed_config.GetValue(1000, /*num_cores=*/1)); + EXPECT_EQ(-10, cpu_speed_config.GetValue(1001, /*num_cores=*/1)); + EXPECT_EQ(-10, cpu_speed_config.GetValue(2000, /*num_cores=*/1)); + EXPECT_EQ(-16, cpu_speed_config.GetValue(2001, /*num_cores=*/1)); + EXPECT_EQ(-16, cpu_speed_config.GetValue(3000, /*num_cores=*/1)); + EXPECT_EQ(-16, cpu_speed_config.GetValue(3001, /*num_cores=*/1)); +} + +TEST(CpuSpeedExperimentTest, GetValueWithCores) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-VP8-CpuSpeed-Arm/" + "pixels:1000|2000|3000,cpu_speed:-1|-10|-16," + "cpu_speed_le_cores:-5|-11|-16,cores:2/"); + + CpuSpeedExperiment cpu_speed_config; + EXPECT_EQ(-5, cpu_speed_config.GetValue(1000, /*num_cores=*/1)); + EXPECT_EQ(-11, cpu_speed_config.GetValue(2000, /*num_cores=*/2)); + EXPECT_EQ(-1, cpu_speed_config.GetValue(1000, /*num_cores=*/3)); + EXPECT_EQ(-10, cpu_speed_config.GetValue(2000, /*num_cores=*/4)); +} + +TEST(CpuSpeedExperimentTest, GetValueWithCoresUnconfigured) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-VP8-CpuSpeed-Arm/" + "pixels:1000|2000|3000,cpu_speed:-1|-10|-16," + "cpu_speed_le_cores:-5|-11|-16/"); + + CpuSpeedExperiment cpu_speed_config; + EXPECT_EQ(-1, cpu_speed_config.GetValue(1000, /*num_cores=*/1)); + EXPECT_EQ(-10, cpu_speed_config.GetValue(2000, /*num_cores=*/2)); } TEST(CpuSpeedExperimentTest, GetValueFailsForTooSmallValue) { @@ -51,7 +75,7 @@ TEST(CpuSpeedExperimentTest, GetValueFailsForTooSmallValue) { "WebRTC-VP8-CpuSpeed-Arm/pixels:1000|2000|3000,cpu_speed:-1|-10|-17/"); CpuSpeedExperiment cpu_speed_config; - EXPECT_FALSE(cpu_speed_config.GetValue(1)); + EXPECT_FALSE(cpu_speed_config.GetValue(1, /*num_cores=*/1)); } TEST(CpuSpeedExperimentTest, GetValueFailsForTooLargeValue) { @@ -60,7 +84,7 @@ TEST(CpuSpeedExperimentTest, GetValueFailsForTooLargeValue) { "WebRTC-VP8-CpuSpeed-Arm/pixels:1000|2000|3000,cpu_speed:0|-10|-16/"); CpuSpeedExperiment cpu_speed_config; - EXPECT_FALSE(cpu_speed_config.GetValue(1)); + EXPECT_FALSE(cpu_speed_config.GetValue(1, /*num_cores=*/1)); } TEST(CpuSpeedExperimentTest, GetValueFailsIfPixelsDecreases) { @@ -68,7 +92,7 @@ TEST(CpuSpeedExperimentTest, GetValueFailsIfPixelsDecreases) { "WebRTC-VP8-CpuSpeed-Arm/pixels:1000|999|3000,cpu_speed:-5|-10|-16/"); CpuSpeedExperiment cpu_speed_config; - EXPECT_FALSE(cpu_speed_config.GetValue(1)); + EXPECT_FALSE(cpu_speed_config.GetValue(1, /*num_cores=*/1)); } TEST(CpuSpeedExperimentTest, GetValueFailsIfCpuSpeedIncreases) { @@ -76,7 +100,7 @@ TEST(CpuSpeedExperimentTest, GetValueFailsIfCpuSpeedIncreases) { "WebRTC-VP8-CpuSpeed-Arm/pixels:1000|2000|3000,cpu_speed:-5|-4|-16/"); CpuSpeedExperiment cpu_speed_config; - EXPECT_FALSE(cpu_speed_config.GetValue(1)); + EXPECT_FALSE(cpu_speed_config.GetValue(1, /*num_cores=*/1)); } } // namespace webrtc