Adds field trial to set per-layer speed for libvpx vp9.
The trial name WebRTC-VP9-PerLayerSpeed is used to a) set encoding speed per spatial layer, based on resolution b) allow explicitly overriding speed per layer, for testing Additionally, this CL updates the vp9 wrapper in preparation for injectable trials. Bug: webrtc:11551, webrtc:11926 Change-Id: I2bb3a664feaef60483ffc241b71070284d3e0172 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/186400 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32294}
This commit is contained in:
@ -556,6 +556,8 @@ rtc_library("webrtc_vp9") {
|
|||||||
":webrtc_vp9_helpers",
|
":webrtc_vp9_helpers",
|
||||||
"../../api:fec_controller_api",
|
"../../api:fec_controller_api",
|
||||||
"../../api:scoped_refptr",
|
"../../api:scoped_refptr",
|
||||||
|
"../../api/transport:field_trial_based_config",
|
||||||
|
"../../api/transport:webrtc_key_value_config",
|
||||||
"../../api/video:video_frame",
|
"../../api/video:video_frame",
|
||||||
"../../api/video:video_frame_i010",
|
"../../api/video:video_frame_i010",
|
||||||
"../../api/video:video_rtp_headers",
|
"../../api/video:video_rtp_headers",
|
||||||
@ -565,13 +567,17 @@ rtc_library("webrtc_vp9") {
|
|||||||
"../../media:rtc_vp9_profile",
|
"../../media:rtc_vp9_profile",
|
||||||
"../../rtc_base",
|
"../../rtc_base",
|
||||||
"../../rtc_base:checks",
|
"../../rtc_base:checks",
|
||||||
|
"../../rtc_base/experiments:field_trial_parser",
|
||||||
"../../rtc_base/experiments:rate_control_settings",
|
"../../rtc_base/experiments:rate_control_settings",
|
||||||
"../../rtc_base/synchronization:mutex",
|
"../../rtc_base/synchronization:mutex",
|
||||||
"../../system_wrappers:field_trial",
|
"../../system_wrappers:field_trial",
|
||||||
"../rtp_rtcp:rtp_rtcp_format",
|
"../rtp_rtcp:rtp_rtcp_format",
|
||||||
"//third_party/libyuv",
|
"//third_party/libyuv",
|
||||||
]
|
]
|
||||||
absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
|
absl_deps = [
|
||||||
|
"//third_party/abseil-cpp/absl/memory",
|
||||||
|
"//third_party/abseil-cpp/absl/strings:strings",
|
||||||
|
]
|
||||||
if (rtc_build_libvpx) {
|
if (rtc_build_libvpx) {
|
||||||
deps += [ rtc_libvpx_dir ]
|
deps += [ rtc_libvpx_dir ]
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
#include "absl/strings/match.h"
|
||||||
|
#include "api/transport/field_trial_based_config.h"
|
||||||
#include "api/video/color_space.h"
|
#include "api/video/color_space.h"
|
||||||
#include "api/video/i010_buffer.h"
|
#include "api/video/i010_buffer.h"
|
||||||
#include "common_video/include/video_frame_buffer.h"
|
#include "common_video/include/video_frame_buffer.h"
|
||||||
@ -27,12 +29,12 @@
|
|||||||
#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h"
|
#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h"
|
||||||
#include "modules/video_coding/utility/vp9_uncompressed_header_parser.h"
|
#include "modules/video_coding/utility/vp9_uncompressed_header_parser.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
#include "rtc_base/experiments/rate_control_settings.h"
|
#include "rtc_base/experiments/rate_control_settings.h"
|
||||||
#include "rtc_base/keep_ref_until_done.h"
|
#include "rtc_base/keep_ref_until_done.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/time_utils.h"
|
#include "rtc_base/time_utils.h"
|
||||||
#include "rtc_base/trace_event.h"
|
#include "rtc_base/trace_event.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
#include "third_party/libyuv/include/libyuv/convert.h"
|
#include "third_party/libyuv/include/libyuv/convert.h"
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#include "vpx/vp8dx.h"
|
#include "vpx/vp8dx.h"
|
||||||
@ -221,6 +223,10 @@ void VP9EncoderImpl::EncoderOutputCodedPacketCallback(vpx_codec_cx_pkt* pkt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
VP9EncoderImpl::VP9EncoderImpl(const cricket::VideoCodec& codec)
|
VP9EncoderImpl::VP9EncoderImpl(const cricket::VideoCodec& codec)
|
||||||
|
: VP9EncoderImpl(codec, FieldTrialBasedConfig()) {}
|
||||||
|
|
||||||
|
VP9EncoderImpl::VP9EncoderImpl(const cricket::VideoCodec& codec,
|
||||||
|
const WebRtcKeyValueConfig& trials)
|
||||||
: encoded_image_(),
|
: encoded_image_(),
|
||||||
encoded_complete_callback_(nullptr),
|
encoded_complete_callback_(nullptr),
|
||||||
profile_(
|
profile_(
|
||||||
@ -239,27 +245,32 @@ VP9EncoderImpl::VP9EncoderImpl(const cricket::VideoCodec& codec)
|
|||||||
num_spatial_layers_(0),
|
num_spatial_layers_(0),
|
||||||
num_active_spatial_layers_(0),
|
num_active_spatial_layers_(0),
|
||||||
first_active_layer_(0),
|
first_active_layer_(0),
|
||||||
layer_deactivation_requires_key_frame_(
|
layer_deactivation_requires_key_frame_(absl::StartsWith(
|
||||||
field_trial::IsEnabled("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation")),
|
trials.Lookup("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation"),
|
||||||
|
"Enabled")),
|
||||||
is_svc_(false),
|
is_svc_(false),
|
||||||
inter_layer_pred_(InterLayerPredMode::kOn),
|
inter_layer_pred_(InterLayerPredMode::kOn),
|
||||||
external_ref_control_(false), // Set in InitEncode because of tests.
|
external_ref_control_(false), // Set in InitEncode because of tests.
|
||||||
trusted_rate_controller_(RateControlSettings::ParseFromFieldTrials()
|
trusted_rate_controller_(
|
||||||
.LibvpxVp9TrustedRateController()),
|
RateControlSettings::ParseFromKeyValueConfig(&trials)
|
||||||
|
.LibvpxVp9TrustedRateController()),
|
||||||
dynamic_rate_settings_(
|
dynamic_rate_settings_(
|
||||||
RateControlSettings::ParseFromFieldTrials().Vp9DynamicRateSettings()),
|
RateControlSettings::ParseFromKeyValueConfig(&trials)
|
||||||
|
.Vp9DynamicRateSettings()),
|
||||||
layer_buffering_(false),
|
layer_buffering_(false),
|
||||||
full_superframe_drop_(true),
|
full_superframe_drop_(true),
|
||||||
first_frame_in_picture_(true),
|
first_frame_in_picture_(true),
|
||||||
ss_info_needed_(false),
|
ss_info_needed_(false),
|
||||||
force_all_active_layers_(false),
|
force_all_active_layers_(false),
|
||||||
is_flexible_mode_(false),
|
is_flexible_mode_(false),
|
||||||
variable_framerate_experiment_(ParseVariableFramerateConfig(
|
variable_framerate_experiment_(ParseVariableFramerateConfig(trials)),
|
||||||
"WebRTC-VP9VariableFramerateScreenshare")),
|
|
||||||
variable_framerate_controller_(
|
variable_framerate_controller_(
|
||||||
variable_framerate_experiment_.framerate_limit),
|
variable_framerate_experiment_.framerate_limit),
|
||||||
quality_scaler_experiment_(
|
quality_scaler_experiment_(ParseQualityScalerConfig(trials)),
|
||||||
ParseQualityScalerConfig("WebRTC-VP9QualityScaler")),
|
external_ref_ctrl_(
|
||||||
|
!absl::StartsWith(trials.Lookup("WebRTC-Vp9ExternalRefCtrl"),
|
||||||
|
"Disabled")),
|
||||||
|
per_layer_speed_(ParsePerLayerSpeed(trials)),
|
||||||
num_steady_state_frames_(0),
|
num_steady_state_frames_(0),
|
||||||
config_changed_(true) {
|
config_changed_(true) {
|
||||||
codec_ = {};
|
codec_ = {};
|
||||||
@ -270,8 +281,7 @@ VP9EncoderImpl::~VP9EncoderImpl() {
|
|||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VP9EncoderImpl::SetFecControllerOverride(
|
void VP9EncoderImpl::SetFecControllerOverride(FecControllerOverride*) {
|
||||||
FecControllerOverride* fec_controller_override) {
|
|
||||||
// Ignored.
|
// Ignored.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,11 +625,10 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
|
|||||||
|
|
||||||
// External reference control is required for different frame rate on spatial
|
// External reference control is required for different frame rate on spatial
|
||||||
// layers because libvpx generates rtp incompatible references in this case.
|
// layers because libvpx generates rtp incompatible references in this case.
|
||||||
external_ref_control_ =
|
external_ref_control_ = external_ref_ctrl_ ||
|
||||||
!field_trial::IsDisabled("WebRTC-Vp9ExternalRefCtrl") ||
|
(num_spatial_layers_ > 1 &&
|
||||||
(num_spatial_layers_ > 1 &&
|
codec_.mode == VideoCodecMode::kScreensharing) ||
|
||||||
codec_.mode == VideoCodecMode::kScreensharing) ||
|
inter_layer_pred_ == InterLayerPredMode::kOn;
|
||||||
inter_layer_pred_ == InterLayerPredMode::kOn;
|
|
||||||
|
|
||||||
if (num_temporal_layers_ == 1) {
|
if (num_temporal_layers_ == 1) {
|
||||||
gof_.SetGofInfoVP9(kTemporalStructureMode1);
|
gof_.SetGofInfoVP9(kTemporalStructureMode1);
|
||||||
@ -756,6 +765,22 @@ int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
|
|||||||
RTC_LOG(LS_ERROR) << "Init error: " << vpx_codec_err_to_string(rv);
|
RTC_LOG(LS_ERROR) << "Init error: " << vpx_codec_err_to_string(rv);
|
||||||
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_CPUUSED, cpu_speed_);
|
||||||
vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
||||||
rc_max_intra_target_);
|
rc_max_intra_target_);
|
||||||
@ -1652,7 +1677,8 @@ size_t VP9EncoderImpl::SteadyStateSize(int sid, int tid) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
VP9EncoderImpl::VariableFramerateExperiment
|
VP9EncoderImpl::VariableFramerateExperiment
|
||||||
VP9EncoderImpl::ParseVariableFramerateConfig(std::string group_name) {
|
VP9EncoderImpl::ParseVariableFramerateConfig(
|
||||||
|
const WebRtcKeyValueConfig& trials) {
|
||||||
FieldTrialFlag enabled = FieldTrialFlag("Enabled");
|
FieldTrialFlag enabled = FieldTrialFlag("Enabled");
|
||||||
FieldTrialParameter<double> framerate_limit("min_fps", 5.0);
|
FieldTrialParameter<double> framerate_limit("min_fps", 5.0);
|
||||||
FieldTrialParameter<int> qp("min_qp", 32);
|
FieldTrialParameter<int> qp("min_qp", 32);
|
||||||
@ -1661,7 +1687,7 @@ VP9EncoderImpl::ParseVariableFramerateConfig(std::string group_name) {
|
|||||||
"frames_before_steady_state", 5);
|
"frames_before_steady_state", 5);
|
||||||
ParseFieldTrial({&enabled, &framerate_limit, &qp, &undershoot_percentage,
|
ParseFieldTrial({&enabled, &framerate_limit, &qp, &undershoot_percentage,
|
||||||
&frames_before_steady_state},
|
&frames_before_steady_state},
|
||||||
field_trial::FindFullName(group_name));
|
trials.Lookup("WebRTC-VP9VariableFramerateScreenshare"));
|
||||||
VariableFramerateExperiment config;
|
VariableFramerateExperiment config;
|
||||||
config.enabled = enabled.Get();
|
config.enabled = enabled.Get();
|
||||||
config.framerate_limit = framerate_limit.Get();
|
config.framerate_limit = framerate_limit.Get();
|
||||||
@ -1674,12 +1700,12 @@ VP9EncoderImpl::ParseVariableFramerateConfig(std::string group_name) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
VP9EncoderImpl::QualityScalerExperiment
|
VP9EncoderImpl::QualityScalerExperiment
|
||||||
VP9EncoderImpl::ParseQualityScalerConfig(std::string group_name) {
|
VP9EncoderImpl::ParseQualityScalerConfig(const WebRtcKeyValueConfig& trials) {
|
||||||
FieldTrialFlag disabled = FieldTrialFlag("Disabled");
|
FieldTrialFlag disabled = FieldTrialFlag("Disabled");
|
||||||
FieldTrialParameter<int> low_qp("low_qp", kLowVp9QpThreshold);
|
FieldTrialParameter<int> low_qp("low_qp", kLowVp9QpThreshold);
|
||||||
FieldTrialParameter<int> high_qp("hihg_qp", kHighVp9QpThreshold);
|
FieldTrialParameter<int> high_qp("hihg_qp", kHighVp9QpThreshold);
|
||||||
ParseFieldTrial({&disabled, &low_qp, &high_qp},
|
ParseFieldTrial({&disabled, &low_qp, &high_qp},
|
||||||
field_trial::FindFullName(group_name));
|
trials.Lookup("WebRTC-VP9QualityScaler"));
|
||||||
QualityScalerExperiment config;
|
QualityScalerExperiment config;
|
||||||
config.enabled = !disabled.Get();
|
config.enabled = !disabled.Get();
|
||||||
RTC_LOG(LS_INFO) << "Webrtc quality scaler for vp9 is "
|
RTC_LOG(LS_INFO) << "Webrtc quality scaler for vp9 is "
|
||||||
@ -1690,6 +1716,20 @@ VP9EncoderImpl::ParseQualityScalerConfig(std::string group_name) {
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
VP9EncoderImpl::SpeedSettings VP9EncoderImpl::ParsePerLayerSpeed(
|
||||||
|
const WebRtcKeyValueConfig& trials) {
|
||||||
|
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) {
|
void VP9EncoderImpl::MaybeRewrapRawWithFormat(const vpx_img_fmt fmt) {
|
||||||
if (!raw_) {
|
if (!raw_) {
|
||||||
raw_ = vpx_img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, nullptr);
|
raw_ = vpx_img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, nullptr);
|
||||||
@ -1702,14 +1742,16 @@ void VP9EncoderImpl::MaybeRewrapRawWithFormat(const vpx_img_fmt fmt) {
|
|||||||
// else no-op since the image is already in the right format.
|
// else no-op since the image is already in the right format.
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9DecoderImpl::VP9DecoderImpl()
|
VP9DecoderImpl::VP9DecoderImpl() : VP9DecoderImpl(FieldTrialBasedConfig()) {}
|
||||||
|
VP9DecoderImpl::VP9DecoderImpl(const WebRtcKeyValueConfig& trials)
|
||||||
: decode_complete_callback_(nullptr),
|
: decode_complete_callback_(nullptr),
|
||||||
inited_(false),
|
inited_(false),
|
||||||
decoder_(nullptr),
|
decoder_(nullptr),
|
||||||
key_frame_required_(true),
|
key_frame_required_(true),
|
||||||
preferred_output_format_(field_trial::IsEnabled("WebRTC-NV12Decode")
|
preferred_output_format_(
|
||||||
? VideoFrameBuffer::Type::kNV12
|
absl::StartsWith(trials.Lookup("WebRTC-NV12Decode"), "Enabled")
|
||||||
: VideoFrameBuffer::Type::kI420) {}
|
? VideoFrameBuffer::Type::kNV12
|
||||||
|
: VideoFrameBuffer::Type::kI420) {}
|
||||||
|
|
||||||
VP9DecoderImpl::~VP9DecoderImpl() {
|
VP9DecoderImpl::~VP9DecoderImpl() {
|
||||||
inited_ = true; // in order to do the actual release
|
inited_ = true; // in order to do the actual release
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/fec_controller_override.h"
|
#include "api/fec_controller_override.h"
|
||||||
|
#include "api/transport/webrtc_key_value_config.h"
|
||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "common_video/include/video_frame_buffer_pool.h"
|
#include "common_video/include/video_frame_buffer_pool.h"
|
||||||
#include "media/base/vp9_profile.h"
|
#include "media/base/vp9_profile.h"
|
||||||
@ -35,6 +36,8 @@ namespace webrtc {
|
|||||||
class VP9EncoderImpl : public VP9Encoder {
|
class VP9EncoderImpl : public VP9Encoder {
|
||||||
public:
|
public:
|
||||||
explicit VP9EncoderImpl(const cricket::VideoCodec& codec);
|
explicit VP9EncoderImpl(const cricket::VideoCodec& codec);
|
||||||
|
VP9EncoderImpl(const cricket::VideoCodec& codec,
|
||||||
|
const WebRtcKeyValueConfig& trials);
|
||||||
|
|
||||||
~VP9EncoderImpl() override;
|
~VP9EncoderImpl() override;
|
||||||
|
|
||||||
@ -176,7 +179,7 @@ class VP9EncoderImpl : public VP9Encoder {
|
|||||||
int frames_before_steady_state;
|
int frames_before_steady_state;
|
||||||
} variable_framerate_experiment_;
|
} variable_framerate_experiment_;
|
||||||
static VariableFramerateExperiment ParseVariableFramerateConfig(
|
static VariableFramerateExperiment ParseVariableFramerateConfig(
|
||||||
std::string group_name);
|
const WebRtcKeyValueConfig& trials);
|
||||||
FramerateController variable_framerate_controller_;
|
FramerateController variable_framerate_controller_;
|
||||||
|
|
||||||
const struct QualityScalerExperiment {
|
const struct QualityScalerExperiment {
|
||||||
@ -185,7 +188,14 @@ class VP9EncoderImpl : public VP9Encoder {
|
|||||||
bool enabled;
|
bool enabled;
|
||||||
} quality_scaler_experiment_;
|
} quality_scaler_experiment_;
|
||||||
static QualityScalerExperiment ParseQualityScalerConfig(
|
static QualityScalerExperiment ParseQualityScalerConfig(
|
||||||
std::string group_name);
|
const WebRtcKeyValueConfig& trials);
|
||||||
|
const bool external_ref_ctrl_;
|
||||||
|
|
||||||
|
const struct SpeedSettings {
|
||||||
|
bool enabled;
|
||||||
|
int layers[kMaxSpatialLayers];
|
||||||
|
} per_layer_speed_;
|
||||||
|
static SpeedSettings ParsePerLayerSpeed(const WebRtcKeyValueConfig& trials);
|
||||||
|
|
||||||
int num_steady_state_frames_;
|
int num_steady_state_frames_;
|
||||||
// Only set config when this flag is set.
|
// Only set config when this flag is set.
|
||||||
@ -195,6 +205,7 @@ class VP9EncoderImpl : public VP9Encoder {
|
|||||||
class VP9DecoderImpl : public VP9Decoder {
|
class VP9DecoderImpl : public VP9Decoder {
|
||||||
public:
|
public:
|
||||||
VP9DecoderImpl();
|
VP9DecoderImpl();
|
||||||
|
explicit VP9DecoderImpl(const WebRtcKeyValueConfig& trials);
|
||||||
|
|
||||||
virtual ~VP9DecoderImpl();
|
virtual ~VP9DecoderImpl();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user