Revert "Adds experimental libvpx VP9 speed settings."
This reverts commit 6e7167456b5eba36c7985d6a74f1d191958d4e0f.
Reason for revert: Unexpected perf change
Original change's description:
> Adds experimental libvpx VP9 speed settings.
>
> Using the field trial WebRTC-VP9-PerformanceFlags, this CL allows you to
> configure the libvpx VP9 encoder with a list of flags to affect the
> quality vs speed tradeoff. This CL adds support for:
>
> * Speed (effort), for the temporal base layer frames
> * Speed for higher (non-base) layer frames
> * De-blocking (as part of the loopfilter) enabled for:
> 0 = all frames
> 1 = all but frames from the highest temporal layer
> 2 = no frames
>
> Each entry in the list has a threshold in min number of pixels needed
> for settings in the entry to apply.
>
> Example: Two spatial layers (180p, 360p) with three temporal
> layers are configured. Field trial "WebRTC-VP9-PerformanceFlags" set to:
> "min_pixel_count:0|129600,base_layer_speed:5|8,high_layer_speed:7|8,deblock_mode:1|2"
> This translates to:
> S0:
> - TL0: Speed 5, deblocked
> - TL1: Speed 8, deblocked
> - TL2: Speed 8, not deblocked
> S1:
> - TL0: Speed 7, not deblocked
> - TL1: Speed 8, not deblocked
> - TL2: Speed 8, not deblocked
>
> Bug: webrtc:11551
> Change-Id: Ieef6816d3e0831ff53348ecc4a90260e2ef10422
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/188461
> Reviewed-by: Michael Horowitz <mhoro@webrtc.org>
> Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
> Commit-Queue: Erik Språng <sprang@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#32749}
TBR=sprang@webrtc.org,ssilkin@webrtc.org,mhoro@webrtc.org
Change-Id: If910963441ac1a0e002aac7066791c7cc7764a1a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:11551
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196344
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32762}
diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc
index acf5e21..c2b1f50 100644
--- a/modules/video_coding/codecs/vp9/vp9_impl.cc
+++ b/modules/video_coding/codecs/vp9/vp9_impl.cc
@@ -32,7 +32,6 @@
#include "modules/video_coding/svc/scalable_video_controller_no_layering.h"
#include "modules/video_coding/utility/vp9_uncompressed_header_parser.h"
#include "rtc_base/checks.h"
-#include "rtc_base/experiments/field_trial_list.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/experiments/rate_control_settings.h"
#include "rtc_base/keep_ref_until_done.h"
@@ -66,6 +65,20 @@
constexpr int kLowVp9QpThreshold = 149;
constexpr int kHighVp9QpThreshold = 205;
+// Only positive speeds, range for real-time coding currently is: 5 - 8.
+// Lower means slower/better quality, higher means fastest/lower quality.
+int GetCpuSpeed(int width, int height) {
+#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID)
+ return 8;
+#else
+ // For smaller resolutions, use lower speed setting (get some coding gain at
+ // the cost of increased encoding complexity).
+ if (width * height <= 352 * 288)
+ return 5;
+ else
+ return 7;
+#endif
+}
// Helper class for extracting VP9 colorspace.
ColorSpace ExtractVP9ColorSpace(vpx_color_space_t space_t,
vpx_color_range_t range_t,
@@ -268,6 +281,7 @@
ParseSdpForVP9Profile(codec.params).value_or(VP9Profile::kProfile0)),
inited_(false),
timestamp_(0),
+ cpu_speed_(3),
rc_max_intra_target_(0),
encoder_(nullptr),
config_(nullptr),
@@ -304,7 +318,7 @@
external_ref_ctrl_(
!absl::StartsWith(trials.Lookup("WebRTC-Vp9ExternalRefCtrl"),
"Disabled")),
- performance_flags_(ParsePerformanceFlagsFromTrials(trials)),
+ per_layer_speed_(ParsePerLayerSpeed(trials)),
num_steady_state_frames_(0),
config_changed_(true) {
codec_ = {};
@@ -441,6 +455,8 @@
first_active_layer_ = 0;
bool seen_active_layer = false;
bool expect_no_more_active_layers = false;
+ int highest_active_width = 0;
+ int highest_active_height = 0;
for (int i = 0; i < num_spatial_layers_; ++i) {
if (config_->ss_target_bitrate[i] > 0) {
RTC_DCHECK(!expect_no_more_active_layers) << "Only middle layer is "
@@ -450,6 +466,12 @@
}
num_active_spatial_layers_ = i + 1;
seen_active_layer = true;
+ highest_active_width =
+ (svc_params_.scaling_factor_num[i] * config_->g_w) /
+ svc_params_.scaling_factor_den[i];
+ highest_active_height =
+ (svc_params_.scaling_factor_num[i] * config_->g_h) /
+ svc_params_.scaling_factor_den[i];
} else {
expect_no_more_active_layers = seen_active_layer;
}
@@ -477,6 +499,7 @@
svc_controller_->OnRatesUpdated(allocation);
}
current_bitrate_allocation_ = bitrate_allocation;
+ cpu_speed_ = GetCpuSpeed(highest_active_width, highest_active_height);
config_changed_ = true;
return true;
}
@@ -642,6 +665,8 @@
config_->g_threads =
NumberOfThreads(config_->g_w, config_->g_h, settings.number_of_cores);
+ cpu_speed_ = GetCpuSpeed(config_->g_w, config_->g_h);
+
is_flexible_mode_ = inst->VP9().flexibleMode;
inter_layer_pred_ = inst->VP9().interLayerPred;
@@ -802,16 +827,22 @@
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
- UpdatePerformanceFlags();
- RTC_DCHECK_EQ(performance_flags_by_spatial_index_.size(),
- static_cast<size_t>(num_spatial_layers_));
- for (int si = 0; si < std::min<int>(num_spatial_layers_, 1); ++si) {
- svc_params_.speed_per_layer[si] =
- performance_flags_by_spatial_index_[si].base_layer_speed;
- svc_params_.loopfilter_ctrl[si] =
- performance_flags_by_spatial_index_[si].deblock_mode;
+ if (per_layer_speed_.enabled) {
+ for (int i = 0; i < num_spatial_layers_; ++i) {
+ if (codec_.spatialLayers[i].active) {
+ continue;
+ }
+
+ if (per_layer_speed_.layers[i] != -1) {
+ svc_params_.speed_per_layer[i] = per_layer_speed_.layers[i];
+ } else {
+ svc_params_.speed_per_layer[i] = GetCpuSpeed(
+ codec_.spatialLayers[i].width, codec_.spatialLayers[i].height);
+ }
+ }
}
+ vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_);
vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
rc_max_intra_target_);
vpx_codec_control(encoder_, VP9E_SET_AQ_MODE,
@@ -823,9 +854,6 @@
if (is_svc_) {
vpx_codec_control(encoder_, VP9E_SET_SVC, 1);
vpx_codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_);
- } else {
- vpx_codec_control(encoder_, VP8E_SET_CPUUSED,
- performance_flags_by_spatial_index_[0].base_layer_speed);
}
if (num_spatial_layers_ > 1) {
@@ -1040,24 +1068,6 @@
}
}
- if (is_svc_) {
- // Update speed settings that might depend on temporal index.
- bool speed_updated = false;
- for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
- const int target_speed =
- layer_id.temporal_layer_id_per_spatial[sl_idx] == 0
- ? performance_flags_by_spatial_index_[sl_idx].base_layer_speed
- : performance_flags_by_spatial_index_[sl_idx].high_layer_speed;
- if (svc_params_.speed_per_layer[sl_idx] != target_speed) {
- svc_params_.speed_per_layer[sl_idx] = target_speed;
- speed_updated = true;
- }
- }
- if (speed_updated) {
- vpx_codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_);
- }
- }
-
vpx_codec_control(encoder_, VP9E_SET_SVC_LAYER_ID, &layer_id);
if (num_spatial_layers_ > 1) {
@@ -1070,6 +1080,7 @@
if (vpx_codec_enc_config_set(encoder_, config_)) {
return WEBRTC_VIDEO_CODEC_ERROR;
}
+ vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_);
config_changed_ = false;
}
@@ -1815,92 +1826,18 @@
return config;
}
-void VP9EncoderImpl::UpdatePerformanceFlags() {
- const auto find_speed = [&](int min_pixel_count) {
- auto it = std::lower_bound(
- performance_flags_.begin(), performance_flags_.end(), min_pixel_count,
- [](const PerformanceFlags& lhs, int min_pixel_count) {
- return lhs.min_pixel_count < min_pixel_count;
- });
- return it == performance_flags_.begin() ? *it : *std::prev(it);
- };
-
- performance_flags_by_spatial_index_.clear();
- if (is_svc_) {
- for (int si = 0; si < num_spatial_layers_; ++si) {
- performance_flags_by_spatial_index_.push_back(find_speed(
- codec_.spatialLayers[si].width * codec_.spatialLayers[si].height));
- }
- } else {
- performance_flags_by_spatial_index_.push_back(
- find_speed(codec_.width * codec_.height));
- }
-}
-
// static
-std::vector<VP9EncoderImpl::PerformanceFlags>
-VP9EncoderImpl::ParsePerformanceFlagsFromTrials(
+VP9EncoderImpl::SpeedSettings VP9EncoderImpl::ParsePerLayerSpeed(
const WebRtcKeyValueConfig& trials) {
- FieldTrialStructList<PerformanceFlags> trials_list(
- {FieldTrialStructMember(
- "min_pixel_count",
- [](PerformanceFlags* c) { return &c->min_pixel_count; }),
- FieldTrialStructMember(
- "high_layer_speed",
- [](PerformanceFlags* c) { return &c->high_layer_speed; }),
- FieldTrialStructMember(
- "base_layer_speed",
- [](PerformanceFlags* c) { return &c->base_layer_speed; }),
- FieldTrialStructMember(
- "deblock_mode",
- [](PerformanceFlags* c) { return &c->deblock_mode; })},
- {});
-
- ParseFieldTrial({&trials_list}, trials.Lookup("WebRTC-VP9-PerformanceFlags"));
- std::vector<VP9EncoderImpl::PerformanceFlags> configs;
- constexpr int kMinSpeed = 1;
- constexpr int kMaxSpeed = 9;
- for (auto& f : trials_list.Get()) {
- if (f.base_layer_speed < kMinSpeed || f.base_layer_speed > kMaxSpeed ||
- f.high_layer_speed < kMinSpeed || f.high_layer_speed > kMaxSpeed ||
- f.deblock_mode < 0 || f.deblock_mode > 2) {
- RTC_LOG(LS_WARNING) << "Ignoring invalid performance flags: "
- << "min_pixel_count = " << f.min_pixel_count
- << ", high_layer_speed = " << f.high_layer_speed
- << ", base_layer_speed = " << f.base_layer_speed
- << ", deblock_mode = " << f.deblock_mode;
- continue;
- }
- configs.push_back(f);
- }
-
- if (configs.empty()) {
- return GetDefaultPerformanceFlags();
- }
-
- std::sort(configs.begin(), configs.end(),
- [](const PerformanceFlags& lhs, const PerformanceFlags& rhs) {
- return lhs.min_pixel_count < rhs.min_pixel_count;
- });
- return configs;
-}
-
-// static
-std::vector<VP9EncoderImpl::PerformanceFlags>
-VP9EncoderImpl::GetDefaultPerformanceFlags() {
- std::vector<VP9EncoderImpl::PerformanceFlags> default_config;
-#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID)
- // Speed 8 on all layers for all resolutions.
- default_config.push_back({0, 8, 8, 0});
-#else
- // For smaller resolutions, use lower speed setting (get some coding gain at
- // the cost of increased encoding complexity).
- default_config.push_back({0, 5, 5, 0});
-
- // Use speed 7 for QCIF and above.
- default_config.push_back({352 * 288, 7, 7, 0});
-#endif
- return default_config;
+ FieldTrialFlag enabled("enabled");
+ FieldTrialParameter<int> speeds[kMaxSpatialLayers]{
+ {"s0", -1}, {"s1", -1}, {"s2", -1}, {"s3", -1}, {"s4", -1}};
+ ParseFieldTrial(
+ {&enabled, &speeds[0], &speeds[1], &speeds[2], &speeds[3], &speeds[4]},
+ trials.Lookup("WebRTC-VP9-PerLayerSpeed"));
+ return SpeedSettings{enabled.Get(),
+ {speeds[0].Get(), speeds[1].Get(), speeds[2].Get(),
+ speeds[3].Get(), speeds[4].Get()}};
}
void VP9EncoderImpl::MaybeRewrapRawWithFormat(const vpx_img_fmt fmt) {
diff --git a/modules/video_coding/codecs/vp9/vp9_impl.h b/modules/video_coding/codecs/vp9/vp9_impl.h
index 0ed5e62..14c3ca8 100644
--- a/modules/video_coding/codecs/vp9/vp9_impl.h
+++ b/modules/video_coding/codecs/vp9/vp9_impl.h
@@ -112,6 +112,7 @@
const VP9Profile profile_;
bool inited_;
int64_t timestamp_;
+ int cpu_speed_;
uint32_t rc_max_intra_target_;
vpx_codec_ctx_t* encoder_;
vpx_codec_enc_cfg_t* config_;
@@ -193,28 +194,11 @@
const WebRtcKeyValueConfig& trials);
const bool external_ref_ctrl_;
- // Flags that can affect speed vs quality tradeoff, and are configureable per
- // resolution ranges.
- struct PerformanceFlags {
- // Min number of pixels needed for this config to be valid.
- int min_pixel_count = 0;
-
- int base_layer_speed = -1; // Speed setting for TL0.
- int high_layer_speed = -1; // Speed setting for TL1-TL3.
- // 0 = deblock all temporal layers (TL)
- // 1 = disable deblock for top-most TL
- // 2 = disable deblock for all TLs
- int deblock_mode = 0;
- };
- // Performance flags, ordered by |min_pixel_count|.
- const std::vector<PerformanceFlags> performance_flags_;
- // Caching of of |speed_configs_|, where index i maps to the resolution as
- // specified in |codec_.spatialLayer[i]|.
- std::vector<PerformanceFlags> performance_flags_by_spatial_index_;
- void UpdatePerformanceFlags();
- static std::vector<PerformanceFlags> ParsePerformanceFlagsFromTrials(
- const WebRtcKeyValueConfig& trials);
- static std::vector<PerformanceFlags> GetDefaultPerformanceFlags();
+ const struct SpeedSettings {
+ bool enabled;
+ int layers[kMaxSpatialLayers];
+ } per_layer_speed_;
+ static SpeedSettings ParsePerLayerSpeed(const WebRtcKeyValueConfig& trials);
int num_steady_state_frames_;
// Only set config when this flag is set.