Field trial to control SVC frame dropping mode in libvpx VP9 encoder
Example: "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/Enabled,layer_drop_mode:1,max_consec_drop:7/" It is only possible to enable LAYER_DROP (layer_drop_mode=1) for now. All other modes are ignored. Max consecutive frame drops (max_consec_drop) value from the field is always applied if the field trial is enabled. LAYER_DROP requires flexible mode (is_flexible_mode_=true) which can be enabled by means of WebRTC-Vp9InterLayerPred: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/media/engine/webrtc_video_engine.cc;l=976 Bug: webrtc:15827, b/320629637 Change-Id: I9c4d4838b11547e608d863198b109cb1485902d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335041 Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/main@{#41755}
This commit is contained in:
parent
54d9cd002c
commit
052bc3af92
@ -95,6 +95,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([
|
||||
FieldTrial('WebRTC-LibaomAv1Encoder-MaxConsecFrameDrop',
|
||||
'webrtc:15821',
|
||||
date(2024, 4, 1)),
|
||||
FieldTrial('WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig',
|
||||
'webrtc:15827',
|
||||
date(2024, 9, 1)),
|
||||
FieldTrial('WebRTC-Pacer-FastRetransmissions',
|
||||
'chromium:1354491',
|
||||
date(2024, 4, 1)),
|
||||
|
||||
@ -266,7 +266,8 @@ LibvpxVp9Encoder::LibvpxVp9Encoder(const cricket::VideoCodec& codec,
|
||||
"Disabled")),
|
||||
performance_flags_(ParsePerformanceFlagsFromTrials(trials)),
|
||||
num_steady_state_frames_(0),
|
||||
config_changed_(true) {
|
||||
config_changed_(true),
|
||||
svc_frame_drop_config_(ParseSvcFrameDropConfig(trials)) {
|
||||
codec_ = {};
|
||||
memset(&svc_params_, 0, sizeof(vpx_svc_extra_cfg_t));
|
||||
}
|
||||
@ -924,11 +925,24 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) {
|
||||
svc_drop_frame_.framedrop_thresh[i] = config_->rc_dropframe_thresh;
|
||||
}
|
||||
} else {
|
||||
// Configure encoder to drop entire superframe whenever it needs to drop
|
||||
// a layer. This mode is preferred over per-layer dropping which causes
|
||||
// quality flickering and is not compatible with RTP non-flexible mode.
|
||||
svc_drop_frame_.framedrop_mode = FULL_SUPERFRAME_DROP;
|
||||
svc_drop_frame_.max_consec_drop = std::numeric_limits<int>::max();
|
||||
if (svc_frame_drop_config_.enabled &&
|
||||
svc_frame_drop_config_.layer_drop_mode == LAYER_DROP &&
|
||||
is_flexible_mode_ && svc_controller_ &&
|
||||
(inter_layer_pred_ == InterLayerPredMode::kOff ||
|
||||
inter_layer_pred_ == InterLayerPredMode::kOnKeyPic)) {
|
||||
// SVC controller is required since it properly accounts for dropped
|
||||
// refs (unlike SetReferences(), which assumes full superframe drop).
|
||||
svc_drop_frame_.framedrop_mode = LAYER_DROP;
|
||||
} else {
|
||||
// Configure encoder to drop entire superframe whenever it needs to drop
|
||||
// a layer. This mode is preferred over per-layer dropping which causes
|
||||
// quality flickering and is not compatible with RTP non-flexible mode.
|
||||
svc_drop_frame_.framedrop_mode = FULL_SUPERFRAME_DROP;
|
||||
}
|
||||
svc_drop_frame_.max_consec_drop =
|
||||
svc_frame_drop_config_.enabled
|
||||
? svc_frame_drop_config_.max_consec_drop
|
||||
: std::numeric_limits<int>::max();
|
||||
for (size_t i = 0; i < num_spatial_layers_; ++i) {
|
||||
svc_drop_frame_.framedrop_thresh[i] = config_->rc_dropframe_thresh;
|
||||
}
|
||||
@ -1910,6 +1924,26 @@ LibvpxVp9Encoder::ParseQualityScalerConfig(const FieldTrialsView& trials) {
|
||||
return config;
|
||||
}
|
||||
|
||||
LibvpxVp9Encoder::SvcFrameDropConfig LibvpxVp9Encoder::ParseSvcFrameDropConfig(
|
||||
const FieldTrialsView& trials) {
|
||||
FieldTrialFlag enabled = FieldTrialFlag("Enabled");
|
||||
FieldTrialParameter<int> layer_drop_mode("layer_drop_mode",
|
||||
FULL_SUPERFRAME_DROP);
|
||||
FieldTrialParameter<int> max_consec_drop("max_consec_drop",
|
||||
std::numeric_limits<int>::max());
|
||||
ParseFieldTrial({&enabled, &layer_drop_mode, &max_consec_drop},
|
||||
trials.Lookup("WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig"));
|
||||
SvcFrameDropConfig config;
|
||||
config.enabled = enabled.Get();
|
||||
config.layer_drop_mode = layer_drop_mode.Get();
|
||||
config.max_consec_drop = max_consec_drop.Get();
|
||||
RTC_LOG(LS_INFO) << "Libvpx VP9 encoder SVC frame drop config: "
|
||||
<< (config.enabled ? "enabled" : "disabled")
|
||||
<< " layer_drop_mode " << config.layer_drop_mode
|
||||
<< " max_consec_drop " << config.max_consec_drop;
|
||||
return config;
|
||||
}
|
||||
|
||||
void LibvpxVp9Encoder::UpdatePerformanceFlags() {
|
||||
flat_map<int, PerformanceFlags::ParameterSet> params_by_resolution;
|
||||
if (codec_.GetVideoEncoderComplexity() ==
|
||||
|
||||
@ -236,6 +236,14 @@ class LibvpxVp9Encoder : public VP9Encoder {
|
||||
bool config_changed_;
|
||||
|
||||
const LibvpxVp9EncoderInfoSettings encoder_info_override_;
|
||||
|
||||
const struct SvcFrameDropConfig {
|
||||
bool enabled;
|
||||
int layer_drop_mode; // SVC_LAYER_DROP_MODE
|
||||
int max_consec_drop;
|
||||
} svc_frame_drop_config_;
|
||||
static SvcFrameDropConfig ParseSvcFrameDropConfig(
|
||||
const FieldTrialsView& trials);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -2459,4 +2459,113 @@ TEST(Vp9SpeedSettingsTrialsTest, DefaultPerLayerFlagsWithSvc) {
|
||||
}
|
||||
}
|
||||
|
||||
struct SvcFrameDropConfigTestParameters {
|
||||
bool flexible_mode;
|
||||
absl::optional<ScalabilityMode> scalability_mode;
|
||||
std::string field_trial;
|
||||
int expected_framedrop_mode;
|
||||
int expected_max_consec_drop;
|
||||
};
|
||||
|
||||
class TestVp9ImplSvcFrameDropConfig
|
||||
: public ::testing::TestWithParam<SvcFrameDropConfigTestParameters> {};
|
||||
|
||||
TEST_P(TestVp9ImplSvcFrameDropConfig, SvcFrameDropConfig) {
|
||||
SvcFrameDropConfigTestParameters test_params = GetParam();
|
||||
auto* const vpx = new NiceMock<MockLibvpxInterface>();
|
||||
LibvpxVp9Encoder encoder(
|
||||
cricket::CreateVideoCodec(cricket::kVp9CodecName),
|
||||
absl::WrapUnique<LibvpxInterface>(vpx),
|
||||
test::ExplicitKeyValueConfig(test_params.field_trial));
|
||||
|
||||
vpx_image_t img;
|
||||
ON_CALL(*vpx, img_wrap).WillByDefault(GetWrapImageFunction(&img));
|
||||
|
||||
EXPECT_CALL(*vpx,
|
||||
codec_control(_, VP9E_SET_SVC_FRAME_DROP_LAYER,
|
||||
SafeMatcherCast<vpx_svc_frame_drop_t*>(AllOf(
|
||||
Field(&vpx_svc_frame_drop_t::framedrop_mode,
|
||||
test_params.expected_framedrop_mode),
|
||||
Field(&vpx_svc_frame_drop_t::max_consec_drop,
|
||||
test_params.expected_max_consec_drop)))));
|
||||
|
||||
VideoCodec settings = DefaultCodecSettings();
|
||||
settings.VP9()->flexibleMode = test_params.flexible_mode;
|
||||
if (test_params.scalability_mode.has_value()) {
|
||||
settings.SetScalabilityMode(*test_params.scalability_mode);
|
||||
}
|
||||
settings.VP9()->numberOfSpatialLayers =
|
||||
3; // to execute SVC code paths even when scalability_mode is not set.
|
||||
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder.InitEncode(&settings, kSettings));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
All,
|
||||
TestVp9ImplSvcFrameDropConfig,
|
||||
::testing::Values(
|
||||
// Flexible mode is disabled. Layer drop is not allowed. Ignore
|
||||
// layer_drop_mode from field trial.
|
||||
SvcFrameDropConfigTestParameters{
|
||||
.flexible_mode = false,
|
||||
.scalability_mode = ScalabilityMode::kL3T3_KEY,
|
||||
.field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/"
|
||||
"Enabled,layer_drop_mode:1,max_consec_drop:7/",
|
||||
.expected_framedrop_mode = FULL_SUPERFRAME_DROP,
|
||||
.expected_max_consec_drop = 7},
|
||||
// Flexible mode is enabled but the field trial is not set. Use default
|
||||
// settings.
|
||||
SvcFrameDropConfigTestParameters{
|
||||
.flexible_mode = true,
|
||||
.scalability_mode = ScalabilityMode::kL3T3_KEY,
|
||||
.field_trial = "",
|
||||
.expected_framedrop_mode = FULL_SUPERFRAME_DROP,
|
||||
.expected_max_consec_drop = std::numeric_limits<int>::max()},
|
||||
// Flexible mode is enabled but the field trial is disabled. Use default
|
||||
// settings.
|
||||
SvcFrameDropConfigTestParameters{
|
||||
.flexible_mode = true,
|
||||
.scalability_mode = ScalabilityMode::kL3T3_KEY,
|
||||
.field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/"
|
||||
"Disabled,layer_drop_mode:1,max_consec_drop:7/",
|
||||
.expected_framedrop_mode = FULL_SUPERFRAME_DROP,
|
||||
.expected_max_consec_drop = std::numeric_limits<int>::max()},
|
||||
// Flexible mode is enabled, layer drop is enabled, KSVC. Apply config
|
||||
// from field trial.
|
||||
SvcFrameDropConfigTestParameters{
|
||||
.flexible_mode = true,
|
||||
.scalability_mode = ScalabilityMode::kL3T3_KEY,
|
||||
.field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/"
|
||||
"Enabled,layer_drop_mode:1,max_consec_drop:7/",
|
||||
.expected_framedrop_mode = LAYER_DROP,
|
||||
.expected_max_consec_drop = 7},
|
||||
// Flexible mode is enabled, layer drop is enabled, simulcast. Apply
|
||||
// config from field trial.
|
||||
SvcFrameDropConfigTestParameters{
|
||||
.flexible_mode = true,
|
||||
.scalability_mode = ScalabilityMode::kS3T3,
|
||||
.field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/"
|
||||
"Enabled,layer_drop_mode:1,max_consec_drop:7/",
|
||||
.expected_framedrop_mode = LAYER_DROP,
|
||||
.expected_max_consec_drop = 7},
|
||||
// Flexible mode is enabled, layer drop is enabled, full SVC. Apply
|
||||
// config from field trial.
|
||||
SvcFrameDropConfigTestParameters{
|
||||
.flexible_mode = false,
|
||||
.scalability_mode = ScalabilityMode::kL3T3,
|
||||
.field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/"
|
||||
"Enabled,layer_drop_mode:1,max_consec_drop:7/",
|
||||
.expected_framedrop_mode = FULL_SUPERFRAME_DROP,
|
||||
.expected_max_consec_drop = 7},
|
||||
// Flexible mode is enabled, layer-drop is enabled, scalability mode is
|
||||
// not set (i.e., SVC controller is not enabled). Ignore layer_drop_mode
|
||||
// from field trial.
|
||||
SvcFrameDropConfigTestParameters{
|
||||
.flexible_mode = true,
|
||||
.scalability_mode = absl::nullopt,
|
||||
.field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/"
|
||||
"Enabled,layer_drop_mode:1,max_consec_drop:7/",
|
||||
.expected_framedrop_mode = FULL_SUPERFRAME_DROP,
|
||||
.expected_max_consec_drop = 7}));
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user