Removed WebRTC-NetworkCondition-EncoderSwitch field trial.

Bug: webrtc:12474
Change-Id: I50b3219c0dc9d8a63ff097ee6a71c04fe903aea9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/211663
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33449}
This commit is contained in:
philipel 2021-03-12 15:00:51 +01:00 committed by Commit Bot
parent 7c7885c016
commit fd87944042
3 changed files with 4 additions and 295 deletions

View File

@ -633,10 +633,8 @@ VideoStreamEncoder::VideoStreamEncoder(
next_frame_types_(1, VideoFrameType::kVideoFrameDelta),
frame_encode_metadata_writer_(this),
experiment_groups_(GetExperimentGroups()),
encoder_switch_experiment_(ParseEncoderSwitchFieldTrial()),
automatic_animation_detection_experiment_(
ParseAutomatincAnimationDetectionFieldTrial()),
encoder_switch_requested_(false),
input_state_provider_(encoder_stats_observer),
video_stream_adapter_(
std::make_unique<VideoStreamAdapter>(&input_state_provider_,
@ -847,19 +845,6 @@ void VideoStreamEncoder::ReconfigureEncoder() {
// Running on the encoder queue.
RTC_DCHECK(pending_encoder_reconfiguration_);
if (!encoder_selector_ &&
encoder_switch_experiment_.IsPixelCountBelowThreshold(
last_frame_info_->width * last_frame_info_->height) &&
!encoder_switch_requested_ && settings_.encoder_switch_request_callback) {
EncoderSwitchRequestCallback::Config conf;
conf.codec_name = encoder_switch_experiment_.to_codec;
conf.param = encoder_switch_experiment_.to_param;
conf.value = encoder_switch_experiment_.to_value;
QueueRequestEncoderSwitch(conf);
encoder_switch_requested_ = true;
}
bool encoder_reset_required = false;
if (pending_encoder_creation_) {
// Destroy existing encoder instance before creating a new one. Otherwise
@ -1101,8 +1086,6 @@ void VideoStreamEncoder::ReconfigureEncoder() {
}
send_codec_ = codec;
encoder_switch_experiment_.SetCodec(send_codec_.codecType);
// Keep the same encoder, as long as the video_format is unchanged.
// Encoder creation block is split in two since EncoderInfo needed to start
// CPU adaptation with the correct settings should be polled after
@ -2045,22 +2028,10 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
const bool video_is_suspended = target_bitrate == DataRate::Zero();
const bool video_suspension_changed = video_is_suspended != EncoderPaused();
if (!video_is_suspended && settings_.encoder_switch_request_callback) {
if (encoder_selector_) {
if (auto encoder =
encoder_selector_->OnAvailableBitrate(link_allocation)) {
QueueRequestEncoderSwitch(*encoder);
}
} else if (encoder_switch_experiment_.IsBitrateBelowThreshold(
target_bitrate) &&
!encoder_switch_requested_) {
EncoderSwitchRequestCallback::Config conf;
conf.codec_name = encoder_switch_experiment_.to_codec;
conf.param = encoder_switch_experiment_.to_param;
conf.value = encoder_switch_experiment_.to_value;
QueueRequestEncoderSwitch(conf);
encoder_switch_requested_ = true;
if (!video_is_suspended && settings_.encoder_switch_request_callback &&
encoder_selector_) {
if (auto encoder = encoder_selector_->OnAvailableBitrate(link_allocation)) {
QueueRequestEncoderSwitch(*encoder);
}
}
@ -2229,113 +2200,6 @@ void VideoStreamEncoder::ReleaseEncoder() {
TRACE_EVENT0("webrtc", "VCMGenericEncoder::Release");
}
bool VideoStreamEncoder::EncoderSwitchExperiment::IsBitrateBelowThreshold(
const DataRate& target_bitrate) {
DataRate rate = DataRate::KilobitsPerSec(
bitrate_filter.Apply(1.0, target_bitrate.kbps()));
return current_thresholds.bitrate && rate < *current_thresholds.bitrate;
}
bool VideoStreamEncoder::EncoderSwitchExperiment::IsPixelCountBelowThreshold(
int pixel_count) const {
return current_thresholds.pixel_count &&
pixel_count < *current_thresholds.pixel_count;
}
void VideoStreamEncoder::EncoderSwitchExperiment::SetCodec(
VideoCodecType codec) {
auto it = codec_thresholds.find(codec);
if (it == codec_thresholds.end()) {
current_thresholds = {};
} else {
current_thresholds = it->second;
}
}
VideoStreamEncoder::EncoderSwitchExperiment
VideoStreamEncoder::ParseEncoderSwitchFieldTrial() const {
EncoderSwitchExperiment result;
// Each "codec threshold" have the format
// "<codec name>;<bitrate kbps>;<pixel count>", and are separated by the "|"
// character.
webrtc::FieldTrialOptional<std::string> codec_thresholds_string{
"codec_thresholds"};
webrtc::FieldTrialOptional<std::string> to_codec{"to_codec"};
webrtc::FieldTrialOptional<std::string> to_param{"to_param"};
webrtc::FieldTrialOptional<std::string> to_value{"to_value"};
webrtc::FieldTrialOptional<double> window{"window"};
webrtc::ParseFieldTrial(
{&codec_thresholds_string, &to_codec, &to_param, &to_value, &window},
webrtc::field_trial::FindFullName(
"WebRTC-NetworkCondition-EncoderSwitch"));
if (!codec_thresholds_string || !to_codec || !window) {
return {};
}
result.bitrate_filter.Reset(1.0 - 1.0 / *window);
result.to_codec = *to_codec;
result.to_param = to_param.GetOptional();
result.to_value = to_value.GetOptional();
std::vector<std::string> codecs_thresholds;
if (rtc::split(*codec_thresholds_string, '|', &codecs_thresholds) == 0) {
return {};
}
for (const std::string& codec_threshold : codecs_thresholds) {
std::vector<std::string> thresholds_split;
if (rtc::split(codec_threshold, ';', &thresholds_split) != 3) {
return {};
}
VideoCodecType codec = PayloadStringToCodecType(thresholds_split[0]);
int bitrate_kbps;
rtc::FromString(thresholds_split[1], &bitrate_kbps);
int pixel_count;
rtc::FromString(thresholds_split[2], &pixel_count);
if (bitrate_kbps > 0) {
result.codec_thresholds[codec].bitrate =
DataRate::KilobitsPerSec(bitrate_kbps);
}
if (pixel_count > 0) {
result.codec_thresholds[codec].pixel_count = pixel_count;
}
if (!result.codec_thresholds[codec].bitrate &&
!result.codec_thresholds[codec].pixel_count) {
return {};
}
}
rtc::StringBuilder ss;
ss << "Successfully parsed WebRTC-NetworkCondition-EncoderSwitch field "
"trial."
" to_codec:"
<< result.to_codec << " to_param:" << result.to_param.value_or("<none>")
<< " to_value:" << result.to_value.value_or("<none>")
<< " codec_thresholds:";
for (auto kv : result.codec_thresholds) {
std::string codec_name = CodecTypeToPayloadString(kv.first);
std::string bitrate = kv.second.bitrate
? std::to_string(kv.second.bitrate->kbps())
: "<none>";
std::string pixels = kv.second.pixel_count
? std::to_string(*kv.second.pixel_count)
: "<none>";
ss << " (" << codec_name << ":" << bitrate << ":" << pixels << ")";
}
RTC_LOG(LS_INFO) << ss.str();
return result;
}
VideoStreamEncoder::AutomaticAnimationDetectionExperiment
VideoStreamEncoder::ParseAutomatincAnimationDetectionFieldTrial() const {
AutomaticAnimationDetectionExperiment result;

View File

@ -352,38 +352,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// experiment group numbers incremented by 1.
const std::array<uint8_t, 2> experiment_groups_;
struct EncoderSwitchExperiment {
struct Thresholds {
absl::optional<DataRate> bitrate;
absl::optional<int> pixel_count;
};
// Codec --> switching thresholds
std::map<VideoCodecType, Thresholds> codec_thresholds;
// To smooth out the target bitrate so that we don't trigger a switch
// too easily.
rtc::ExpFilter bitrate_filter{1.0};
// Codec/implementation to switch to
std::string to_codec;
absl::optional<std::string> to_param;
absl::optional<std::string> to_value;
// Thresholds for the currently used codecs.
Thresholds current_thresholds;
// Updates the |bitrate_filter|, so not const.
bool IsBitrateBelowThreshold(const DataRate& target_bitrate);
bool IsPixelCountBelowThreshold(int pixel_count) const;
void SetCodec(VideoCodecType codec);
};
EncoderSwitchExperiment ParseEncoderSwitchFieldTrial() const;
EncoderSwitchExperiment encoder_switch_experiment_
RTC_GUARDED_BY(&encoder_queue_);
struct AutomaticAnimationDetectionExperiment {
bool enabled = false;
int min_duration_ms = 2000;
@ -404,10 +372,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
AutomaticAnimationDetectionExperiment
automatic_animation_detection_experiment_ RTC_GUARDED_BY(&encoder_queue_);
// An encoder switch is only requested once, this variable is used to keep
// track of whether a request has been made or not.
bool encoder_switch_requested_ RTC_GUARDED_BY(&encoder_queue_);
// Provies video stream input states: current resolution and frame rate.
VideoStreamInputStateProvider input_state_provider_;

View File

@ -7340,125 +7340,6 @@ struct MockEncoderSwitchRequestCallback : public EncoderSwitchRequestCallback {
(override));
};
TEST_F(VideoStreamEncoderTest, BitrateEncoderSwitch) {
constexpr int kDontCare = 100;
StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
video_send_config_.encoder_settings.encoder_switch_request_callback =
&switch_callback;
VideoEncoderConfig encoder_config = video_encoder_config_.Copy();
encoder_config.codec_type = kVideoCodecVP8;
webrtc::test::ScopedFieldTrials field_trial(
"WebRTC-NetworkCondition-EncoderSwitch/"
"codec_thresholds:VP8;100;-1|H264;-1;30000,"
"to_codec:AV1,to_param:ping,to_value:pong,window:2.0/");
// Reset encoder for new configuration to take effect.
ConfigureEncoder(std::move(encoder_config));
// Send one frame to trigger ReconfigureEncoder.
video_source_.IncomingCapturedFrame(
CreateFrame(kDontCare, kDontCare, kDontCare));
using Config = EncoderSwitchRequestCallback::Config;
EXPECT_CALL(switch_callback, RequestEncoderSwitch(Matcher<const Config&>(
AllOf(Field(&Config::codec_name, "AV1"),
Field(&Config::param, "ping"),
Field(&Config::value, "pong")))));
video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
/*target_bitrate=*/DataRate::KilobitsPerSec(50),
/*stable_target_bitrate=*/DataRate::KilobitsPerSec(kDontCare),
/*link_allocation=*/DataRate::KilobitsPerSec(kDontCare),
/*fraction_lost=*/0,
/*rtt_ms=*/0,
/*cwnd_reduce_ratio=*/0);
AdvanceTime(TimeDelta::Millis(0));
video_stream_encoder_->Stop();
}
TEST_F(VideoStreamEncoderTest, VideoSuspendedNoEncoderSwitch) {
constexpr int kDontCare = 100;
StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
video_send_config_.encoder_settings.encoder_switch_request_callback =
&switch_callback;
VideoEncoderConfig encoder_config = video_encoder_config_.Copy();
encoder_config.codec_type = kVideoCodecVP8;
webrtc::test::ScopedFieldTrials field_trial(
"WebRTC-NetworkCondition-EncoderSwitch/"
"codec_thresholds:VP8;100;-1|H264;-1;30000,"
"to_codec:AV1,to_param:ping,to_value:pong,window:2.0/");
// Reset encoder for new configuration to take effect.
ConfigureEncoder(std::move(encoder_config));
// Send one frame to trigger ReconfigureEncoder.
video_source_.IncomingCapturedFrame(
CreateFrame(kDontCare, kDontCare, kDontCare));
using Config = EncoderSwitchRequestCallback::Config;
EXPECT_CALL(switch_callback, RequestEncoderSwitch(Matcher<const Config&>(_)))
.Times(0);
video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
/*target_bitrate=*/DataRate::KilobitsPerSec(0),
/*stable_target_bitrate=*/DataRate::KilobitsPerSec(0),
/*link_allocation=*/DataRate::KilobitsPerSec(kDontCare),
/*fraction_lost=*/0,
/*rtt_ms=*/0,
/*cwnd_reduce_ratio=*/0);
video_stream_encoder_->Stop();
}
TEST_F(VideoStreamEncoderTest, ResolutionEncoderSwitch) {
constexpr int kSufficientBitrateToNotDrop = 1000;
constexpr int kHighRes = 500;
constexpr int kLowRes = 100;
StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
video_send_config_.encoder_settings.encoder_switch_request_callback =
&switch_callback;
webrtc::test::ScopedFieldTrials field_trial(
"WebRTC-NetworkCondition-EncoderSwitch/"
"codec_thresholds:VP8;120;-1|H264;-1;30000,"
"to_codec:AV1,to_param:ping,to_value:pong,window:2.0/");
VideoEncoderConfig encoder_config = video_encoder_config_.Copy();
encoder_config.codec_type = kVideoCodecH264;
// Reset encoder for new configuration to take effect.
ConfigureEncoder(std::move(encoder_config));
// The VideoStreamEncoder needs some bitrate before it can start encoding,
// setting some bitrate so that subsequent calls to WaitForEncodedFrame does
// not fail.
video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
/*target_bitrate=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
/*stable_target_bitrate=*/
DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
/*link_allocation=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
/*fraction_lost=*/0,
/*rtt_ms=*/0,
/*cwnd_reduce_ratio=*/0);
// Send one frame to trigger ReconfigureEncoder.
video_source_.IncomingCapturedFrame(CreateFrame(1, kHighRes, kHighRes));
WaitForEncodedFrame(1);
using Config = EncoderSwitchRequestCallback::Config;
EXPECT_CALL(switch_callback, RequestEncoderSwitch(Matcher<const Config&>(
AllOf(Field(&Config::codec_name, "AV1"),
Field(&Config::param, "ping"),
Field(&Config::value, "pong")))));
video_source_.IncomingCapturedFrame(CreateFrame(2, kLowRes, kLowRes));
WaitForEncodedFrame(2);
video_stream_encoder_->Stop();
}
TEST_F(VideoStreamEncoderTest, EncoderSelectorCurrentEncoderIsSignaled) {
constexpr int kDontCare = 100;
StrictMock<MockEncoderSelector> encoder_selector;