Add field trial for vp8 cpu speed configuration for arm.

Bug: none
Change-Id: I90c2475a229a1f10016e2ad84029e19b5a4f9966
Reviewed-on: https://webrtc-review.googlesource.com/c/107340
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25484}
This commit is contained in:
Åsa Persson
2018-11-02 11:38:46 +01:00
committed by Commit Bot
parent 56ef305b67
commit f8ba95ecee
7 changed files with 227 additions and 5 deletions

View File

@ -425,6 +425,7 @@ rtc_static_library("webrtc_vp8") {
"../../rtc_base:checks", "../../rtc_base:checks",
"../../rtc_base:rtc_base_approved", "../../rtc_base:rtc_base_approved",
"../../rtc_base:rtc_numerics", "../../rtc_base:rtc_numerics",
"../../rtc_base/experiments:cpu_speed_experiment",
"../../system_wrappers", "../../system_wrappers",
"../../system_wrappers:field_trial", "../../system_wrappers:field_trial",
"../../system_wrappers:metrics", "../../system_wrappers:metrics",

View File

@ -142,6 +142,7 @@ LibvpxVp8Encoder::LibvpxVp8Encoder()
LibvpxVp8Encoder::LibvpxVp8Encoder(std::unique_ptr<LibvpxInterface> interface) LibvpxVp8Encoder::LibvpxVp8Encoder(std::unique_ptr<LibvpxInterface> interface)
: libvpx_(std::move(interface)), : libvpx_(std::move(interface)),
experimental_cpu_speed_config_arm_(CpuSpeedExperiment::GetConfigs()),
encoded_complete_callback_(nullptr), encoded_complete_callback_(nullptr),
inited_(false), inited_(false),
timestamp_(0), timestamp_(0),
@ -432,10 +433,10 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
} }
cpu_speed_default_ = cpu_speed_[0]; cpu_speed_default_ = cpu_speed_[0];
// Set encoding complexity (cpu_speed) based on resolution and/or platform. // Set encoding complexity (cpu_speed) based on resolution and/or platform.
cpu_speed_[0] = SetCpuSpeed(inst->width, inst->height); cpu_speed_[0] = GetCpuSpeed(inst->width, inst->height);
for (int i = 1; i < number_of_streams; ++i) { for (int i = 1; i < number_of_streams; ++i) {
cpu_speed_[i] = cpu_speed_[i] =
SetCpuSpeed(inst->simulcastStream[number_of_streams - 1 - i].width, GetCpuSpeed(inst->simulcastStream[number_of_streams - 1 - i].width,
inst->simulcastStream[number_of_streams - 1 - i].height); inst->simulcastStream[number_of_streams - 1 - i].height);
} }
configurations_[0].g_w = inst->width; configurations_[0].g_w = inst->width;
@ -507,7 +508,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
return InitAndSetControlSettings(); return InitAndSetControlSettings();
} }
int LibvpxVp8Encoder::SetCpuSpeed(int width, int height) { int LibvpxVp8Encoder::GetCpuSpeed(int width, int height) {
#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || \ #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || \
defined(WEBRTC_ANDROID) defined(WEBRTC_ANDROID)
// On mobile platform, use a lower speed setting for lower resolutions for // On mobile platform, use a lower speed setting for lower resolutions for
@ -516,6 +517,11 @@ int LibvpxVp8Encoder::SetCpuSpeed(int width, int height) {
if (number_of_cores_ <= 3) if (number_of_cores_ <= 3)
return -12; return -12;
if (experimental_cpu_speed_config_arm_) {
return CpuSpeedExperiment::GetValue(width * height,
*experimental_cpu_speed_config_arm_);
}
if (width * height <= 352 * 288) if (width * height <= 352 * 288)
return -8; return -8;
else if (width * height <= 640 * 480) else if (width * height <= 640 * 480)

View File

@ -22,6 +22,7 @@
#include "modules/video_coding/codecs/vp8/include/vp8.h" #include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/codecs/vp8/libvpx_interface.h" #include "modules/video_coding/codecs/vp8/libvpx_interface.h"
#include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_codec_interface.h"
#include "rtc_base/experiments/cpu_speed_experiment.h"
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
@ -61,8 +62,8 @@ class LibvpxVp8Encoder : public VideoEncoder {
private: private:
void SetupTemporalLayers(const VideoCodec& codec); void SetupTemporalLayers(const VideoCodec& codec);
// Set the cpu_speed setting for encoder based on resolution and/or platform. // Get the cpu_speed setting for encoder based on resolution and/or platform.
int SetCpuSpeed(int width, int height); int GetCpuSpeed(int width, int height);
// Determine number of encoder threads to use. // Determine number of encoder threads to use.
int NumberOfThreads(int width, int height, int number_of_cores); int NumberOfThreads(int width, int height, int number_of_cores);
@ -87,6 +88,9 @@ class LibvpxVp8Encoder : public VideoEncoder {
const std::unique_ptr<LibvpxInterface> libvpx_; const std::unique_ptr<LibvpxInterface> libvpx_;
const absl::optional<std::vector<CpuSpeedExperiment::Config>>
experimental_cpu_speed_config_arm_;
EncodedImageCallback* encoded_complete_callback_; EncodedImageCallback* encoded_complete_callback_;
VideoCodec codec_; VideoCodec codec_;
bool inited_; bool inited_;

View File

@ -75,6 +75,18 @@ rtc_static_library("normalize_simulcast_size_experiment") {
] ]
} }
rtc_static_library("cpu_speed_experiment") {
sources = [
"cpu_speed_experiment.cc",
"cpu_speed_experiment.h",
]
deps = [
"../:rtc_base_approved",
"../../system_wrappers:field_trial",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_static_library("rtt_mult_experiment") { rtc_static_library("rtt_mult_experiment") {
sources = [ sources = [
"rtt_mult_experiment.cc", "rtt_mult_experiment.cc",
@ -104,6 +116,7 @@ if (rtc_include_tests) {
sources = [ sources = [
"congestion_controller_experiment_unittest.cc", "congestion_controller_experiment_unittest.cc",
"cpu_speed_experiment_unittest.cc",
"field_trial_parser_unittest.cc", "field_trial_parser_unittest.cc",
"field_trial_units_unittest.cc", "field_trial_units_unittest.cc",
"normalize_simulcast_size_experiment_unittest.cc", "normalize_simulcast_size_experiment_unittest.cc",
@ -112,6 +125,7 @@ if (rtc_include_tests) {
] ]
deps = [ deps = [
":congestion_controller_experiment", ":congestion_controller_experiment",
":cpu_speed_experiment",
":field_trial_parser", ":field_trial_parser",
":normalize_simulcast_size_experiment", ":normalize_simulcast_size_experiment",
":quality_scaling_experiment", ":quality_scaling_experiment",
@ -120,6 +134,7 @@ if (rtc_include_tests) {
"../:rtc_base_tests_utils", "../:rtc_base_tests_utils",
"../../system_wrappers:field_trial", "../../system_wrappers:field_trial",
"../../test:field_trial", "../../test:field_trial",
"../../test:test_support",
] ]
} }
} }

View File

@ -0,0 +1,70 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "rtc_base/experiments/cpu_speed_experiment.h"
#include <string>
#include "rtc_base/logging.h"
#include "system_wrappers/include/field_trial.h"
namespace webrtc {
namespace {
constexpr char kFieldTrial[] = "WebRTC-VP8-CpuSpeed-Arm";
constexpr int kMinSetting = -16;
constexpr int kMaxSetting = -1;
} // namespace
absl::optional<std::vector<CpuSpeedExperiment::Config>>
CpuSpeedExperiment::GetConfigs() {
if (!webrtc::field_trial::IsEnabled(kFieldTrial))
return absl::nullopt;
const std::string group = webrtc::field_trial::FindFullName(kFieldTrial);
if (group.empty())
return absl::nullopt;
std::vector<Config> configs(3);
if (sscanf(group.c_str(), "Enabled-%d,%d,%d,%d,%d,%d", &(configs[0].pixels),
&(configs[0].cpu_speed), &(configs[1].pixels),
&(configs[1].cpu_speed), &(configs[2].pixels),
&(configs[2].cpu_speed)) != 6) {
RTC_LOG(LS_WARNING) << "Too few parameters provided.";
return absl::nullopt;
}
for (const auto& config : configs) {
if (config.cpu_speed < kMinSetting || config.cpu_speed > kMaxSetting) {
RTC_LOG(LS_WARNING) << "Unsupported cpu speed setting, value ignored.";
return absl::nullopt;
}
}
for (size_t i = 1; i < configs.size(); ++i) {
if (configs[i].pixels < configs[i - 1].pixels ||
configs[i].cpu_speed > configs[i - 1].cpu_speed) {
RTC_LOG(LS_WARNING) << "Invalid parameter value provided.";
return absl::nullopt;
}
}
return absl::optional<std::vector<Config>>(configs);
}
int CpuSpeedExperiment::GetValue(int pixels,
const std::vector<Config>& configs) {
for (const auto& config : configs) {
if (pixels <= config.pixels)
return config.cpu_speed;
}
return kMinSetting;
}
} // namespace webrtc

View File

@ -0,0 +1,41 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef RTC_BASE_EXPERIMENTS_CPU_SPEED_EXPERIMENT_H_
#define RTC_BASE_EXPERIMENTS_CPU_SPEED_EXPERIMENT_H_
#include <vector>
#include "absl/types/optional.h"
namespace webrtc {
class CpuSpeedExperiment {
public:
struct Config {
bool operator==(const Config& o) const {
return pixels == o.pixels && cpu_speed == o.cpu_speed;
}
int pixels; // The video frame size.
int cpu_speed; // The |cpu_speed| to be used if the frame size is less
// than or equal to |pixels|.
};
// Returns the configurations from field trial on success.
static absl::optional<std::vector<Config>> GetConfigs();
// Gets the cpu speed from the |configs| based on |pixels|.
static int GetValue(int pixels, const std::vector<Config>& configs);
};
} // namespace webrtc
#endif // RTC_BASE_EXPERIMENTS_CPU_SPEED_EXPERIMENT_H_

View File

@ -0,0 +1,85 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "rtc_base/experiments/cpu_speed_experiment.h"
#include "rtc_base/gunit.h"
#include "test/field_trial.h"
#include "test/gmock.h"
namespace webrtc {
TEST(CpuSpeedExperimentTest, GetConfigsFailsIfNotEnabled) {
EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
}
TEST(CpuSpeedExperimentTest, GetConfigsFailsForTooFewParameters) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-1,2000,-10,3000/");
EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
}
TEST(CpuSpeedExperimentTest, GetConfigs) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-1,2000,-10,3000,-16/");
const absl::optional<std::vector<CpuSpeedExperiment::Config>> kConfigs =
CpuSpeedExperiment::GetConfigs();
ASSERT_TRUE(kConfigs);
EXPECT_THAT(*kConfigs,
::testing::ElementsAre(CpuSpeedExperiment::Config{1000, -1},
CpuSpeedExperiment::Config{2000, -10},
CpuSpeedExperiment::Config{3000, -16}));
}
TEST(CpuSpeedExperimentTest, GetValue) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-5,2000,-10,3000,-12/");
const absl::optional<std::vector<CpuSpeedExperiment::Config>> kConfigs =
CpuSpeedExperiment::GetConfigs();
ASSERT_TRUE(kConfigs);
ASSERT_EQ(3u, (*kConfigs).size());
EXPECT_EQ(-5, CpuSpeedExperiment::GetValue(1, *kConfigs));
EXPECT_EQ(-5, CpuSpeedExperiment::GetValue(1000, *kConfigs));
EXPECT_EQ(-10, CpuSpeedExperiment::GetValue(1000 + 1, *kConfigs));
EXPECT_EQ(-10, CpuSpeedExperiment::GetValue(2000, *kConfigs));
EXPECT_EQ(-12, CpuSpeedExperiment::GetValue(2000 + 1, *kConfigs));
EXPECT_EQ(-12, CpuSpeedExperiment::GetValue(3000, *kConfigs));
EXPECT_EQ(-16, CpuSpeedExperiment::GetValue(3000 + 1, *kConfigs));
}
TEST(CpuSpeedExperimentTest, GetConfigsFailsForTooSmallValue) {
// Supported range: [-16, -1].
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-1,2000,-10,3000,-17/");
EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
}
TEST(CpuSpeedExperimentTest, GetConfigsFailsForTooLargeValue) {
// Supported range: [-16, -1].
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,0,2000,-10,3000,-16/");
EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
}
TEST(CpuSpeedExperimentTest, GetConfigsFailsIfPixelsDecreasing) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-5,999,-10,3000,-16/");
EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
}
TEST(CpuSpeedExperimentTest, GetConfigsFailsIfCpuSpeedIncreasing) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-5,2000,-4,3000,-16/");
EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
}
} // namespace webrtc