Reduce VP9 complexity for 1080p and up.

This CL changes the default speed settings for TL0/TL[1-2] from
7/8 to 9/9 at 1080p resolutions and up. We also disable the denoiser
at these resolutions.
Settings can be overriden using existing WebRTC-VP9-PerformanceFlags
field trial.

Bug: webrtc:13888
Change-Id: I70f19efdace88d70bbb90bc6dd5149653eb079c8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257141
Reviewed-by: Ying Wang <yinwa@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36379}
This commit is contained in:
Erik Språng
2022-03-30 14:06:13 +02:00
committed by WebRTC LUCI CQ
parent a75a9c35b7
commit 3be87e9afd
2 changed files with 47 additions and 14 deletions

View File

@ -184,6 +184,17 @@ vpx_svc_ref_frame_config_t Vp9References(
return ref_config; return ref_config;
} }
bool AllowDenoising() {
// Do not enable the denoiser on ARM since optimization is pending.
// Denoiser is on by default on other platforms.
#if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \
!defined(ANDROID)
return true;
#else
return false;
#endif
}
} // namespace } // namespace
void LibvpxVp9Encoder::EncoderOutputCodedPacketCallback(vpx_codec_cx_pkt* pkt, void LibvpxVp9Encoder::EncoderOutputCodedPacketCallback(vpx_codec_cx_pkt* pkt,
@ -386,6 +397,15 @@ bool LibvpxVp9Encoder::SetSvcRates(
} }
} }
if (seen_active_layer && performance_flags_.use_per_layer_speed) {
bool denoiser_on =
AllowDenoising() &&
performance_flags_by_spatial_index_[num_active_spatial_layers_ - 1]
.denoiser_on;
libvpx_->codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY,
denoiser_on ? 1 : 0);
}
if (higher_layers_enabled && !force_key_frame_) { if (higher_layers_enabled && !force_key_frame_) {
// Prohibit drop of all layers for the next frame, so newly enabled // Prohibit drop of all layers for the next frame, so newly enabled
// layer would have a valid spatial reference. // layer would have a valid spatial reference.
@ -775,6 +795,10 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) {
} }
} }
UpdatePerformanceFlags();
RTC_DCHECK_EQ(performance_flags_by_spatial_index_.size(),
static_cast<size_t>(num_spatial_layers_));
SvcRateAllocator init_allocator(codec_); SvcRateAllocator init_allocator(codec_);
current_bitrate_allocation_ = current_bitrate_allocation_ =
init_allocator.Allocate(VideoBitrateAllocationParameters( init_allocator.Allocate(VideoBitrateAllocationParameters(
@ -791,9 +815,6 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED; return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
} }
UpdatePerformanceFlags();
RTC_DCHECK_EQ(performance_flags_by_spatial_index_.size(),
static_cast<size_t>(num_spatial_layers_));
if (performance_flags_.use_per_layer_speed) { if (performance_flags_.use_per_layer_speed) {
for (int si = 0; si < num_spatial_layers_; ++si) { for (int si = 0; si < num_spatial_layers_; ++si) {
svc_params_.speed_per_layer[si] = svc_params_.speed_per_layer[si] =
@ -801,6 +822,12 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) {
svc_params_.loopfilter_ctrl[si] = svc_params_.loopfilter_ctrl[si] =
performance_flags_by_spatial_index_[si].deblock_mode; performance_flags_by_spatial_index_[si].deblock_mode;
} }
bool denoiser_on =
AllowDenoising() &&
performance_flags_by_spatial_index_[num_spatial_layers_ - 1]
.denoiser_on;
libvpx_->codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY,
denoiser_on ? 1 : 0);
} }
libvpx_->codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT, libvpx_->codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
@ -888,13 +915,10 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) {
// Turn on row-based multithreading. // Turn on row-based multithreading.
libvpx_->codec_control(encoder_, VP9E_SET_ROW_MT, 1); libvpx_->codec_control(encoder_, VP9E_SET_ROW_MT, 1);
#if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ if (AllowDenoising() && !performance_flags_.use_per_layer_speed) {
!defined(ANDROID) libvpx_->codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY,
// Do not enable the denoiser on ARM since optimization is pending. inst->VP9().denoisingOn ? 1 : 0);
// Denoiser is on by default on other platforms. }
libvpx_->codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY,
inst->VP9().denoisingOn ? 1 : 0);
#endif
if (codec_.mode == VideoCodecMode::kScreensharing) { if (codec_.mode == VideoCodecMode::kScreensharing) {
// Adjust internal parameters to screen content. // Adjust internal parameters to screen content.
@ -1885,7 +1909,9 @@ LibvpxVp9Encoder::ParsePerformanceFlagsFromTrials(
FieldTrialStructMember("base_layer_speed", FieldTrialStructMember("base_layer_speed",
[](Params* p) { return &p->base_layer_speed; }), [](Params* p) { return &p->base_layer_speed; }),
FieldTrialStructMember("deblock_mode", FieldTrialStructMember("deblock_mode",
[](Params* p) { return &p->deblock_mode; })}, [](Params* p) { return &p->deblock_mode; }),
FieldTrialStructMember("denoiser",
[](Params* p) { return &p->denoiser_on; })},
{}); {});
FieldTrialFlag per_layer_speed("use_per_layer_speed"); FieldTrialFlag per_layer_speed("use_per_layer_speed");
@ -1926,18 +1952,24 @@ LibvpxVp9Encoder::GetDefaultPerformanceFlags() {
flags.use_per_layer_speed = true; flags.use_per_layer_speed = true;
#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID) #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID)
// Speed 8 on all layers for all resolutions. // Speed 8 on all layers for all resolutions.
flags.settings_by_resolution[0] = {8, 8, 0}; flags.settings_by_resolution[0] = {8, 8, 0, true};
#else #else
// For smaller resolutions, use lower speed setting for the temporal base // For smaller resolutions, use lower speed setting for the temporal base
// layer (get some coding gain at the cost of increased encoding complexity). // layer (get some coding gain at the cost of increased encoding complexity).
// Set encoder Speed 5 for TL0, encoder Speed 8 for upper temporal layers, and // Set encoder Speed 5 for TL0, encoder Speed 8 for upper temporal layers, and
// disable deblocking for upper-most temporal layers. // disable deblocking for upper-most temporal layers.
flags.settings_by_resolution[0] = {5, 8, 1}; flags.settings_by_resolution[0] = {5, 8, 1, true};
// Use speed 7 for QCIF and above. // Use speed 7 for QCIF and above.
// Set encoder Speed 7 for TL0, encoder Speed 8 for upper temporal layers, and // Set encoder Speed 7 for TL0, encoder Speed 8 for upper temporal layers, and
// enable deblocking for all temporal layers. // enable deblocking for all temporal layers.
flags.settings_by_resolution[352 * 288] = {7, 8, 0}; flags.settings_by_resolution[352 * 288] = {7, 8, 0, true};
// For very high resolution (1080p and up), turn the speed all the way up
// since this is very CPU intensive. Also disable denoising to save CPU, at
// these resolutions denoising appear less effective and hopefully you also
// have a less noisy video source at this point.
flags.settings_by_resolution[1920 * 1080] = {9, 9, 0, false};
#endif #endif
return flags; return flags;
} }

View File

@ -220,6 +220,7 @@ class LibvpxVp9Encoder : public VP9Encoder {
// 1 = disable deblock for top-most TL // 1 = disable deblock for top-most TL
// 2 = disable deblock for all TLs // 2 = disable deblock for all TLs
int deblock_mode = 0; int deblock_mode = 0;
bool denoiser_on = true;
}; };
// Map from min pixel count to settings for that resolution and above. // Map from min pixel count to settings for that resolution and above.
// E.g. if you want some settings A if below wvga (640x360) and some other // E.g. if you want some settings A if below wvga (640x360) and some other