Move initial quality experiment to adaptation module
Bug: webrtc:11222
Change-Id: Iaa33bd6369a11f91e677b015eb2db412d0fbff23
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168053
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Evan Shrubsole <eshr@google.com>
Cr-Commit-Position: refs/heads/master@{#30456}
diff --git a/call/adaptation/resource_adaptation_module_interface.h b/call/adaptation/resource_adaptation_module_interface.h
index 9496842..4efb7ac 100644
--- a/call/adaptation/resource_adaptation_module_interface.h
+++ b/call/adaptation/resource_adaptation_module_interface.h
@@ -86,8 +86,11 @@
virtual void SetDegradationPreference(
DegradationPreference degradation_preference) = 0;
virtual void SetEncoderSettings(EncoderSettings encoder_settings) = 0;
- virtual void SetEncoderTargetBitrate(
- absl::optional<uint32_t> target_bitrate_bps) = 0;
+ // TODO(bugs.webrtc.org/11222): This function shouldn't be needed, start
+ // bitrates should be apart of the constructor ideally. See the comment on
+ // VideoStreamEncoderInterface::SetStartBitrate.
+ virtual void SetStartBitrate(DataRate start_bitrate) = 0;
+ virtual void SetTargetBitrate(DataRate target_bitrate) = 0;
// Removes all restrictions; the module will need to adapt all over again.
// TODO(hbos): It's not clear why anybody should be able to tell the module to
// reset like this; can we get rid of this method?
diff --git a/video/overuse_frame_detector_resource_adaptation_module.cc b/video/overuse_frame_detector_resource_adaptation_module.cc
index cf93309..f0f9815 100644
--- a/video/overuse_frame_detector_resource_adaptation_module.cc
+++ b/video/overuse_frame_detector_resource_adaptation_module.cc
@@ -346,11 +346,13 @@
OveruseFrameDetectorResourceAdaptationModule::
OveruseFrameDetectorResourceAdaptationModule(
+ Clock* clock,
bool experiment_cpu_load_estimator,
std::unique_ptr<OveruseFrameDetector> overuse_detector,
VideoStreamEncoderObserver* encoder_stats_observer,
ResourceAdaptationModuleListener* adaptation_listener)
: adaptation_listener_(adaptation_listener),
+ clock_(clock),
experiment_cpu_load_estimator_(experiment_cpu_load_estimator),
has_input_video_(false),
degradation_preference_(DegradationPreference::DISABLED),
@@ -362,9 +364,10 @@
overuse_detector_is_started_(false),
last_input_frame_size_(absl::nullopt),
target_frame_rate_(absl::nullopt),
- target_bitrate_bps_(absl::nullopt),
+ encoder_target_bitrate_bps_(absl::nullopt),
quality_scaler_(nullptr),
quality_scaling_experiment_enabled_(QualityScalingExperiment::Enabled()),
+ quality_scaler_settings_(QualityScalerSettings::ParseFromFieldTrials()),
encoder_settings_(absl::nullopt),
encoder_stats_observer_(encoder_stats_observer),
initial_framedrop_(0) {
@@ -432,9 +435,37 @@
MaybeUpdateTargetFrameRate();
}
-void OveruseFrameDetectorResourceAdaptationModule::SetEncoderTargetBitrate(
- absl::optional<uint32_t> target_bitrate_bps) {
- target_bitrate_bps_ = target_bitrate_bps;
+void OveruseFrameDetectorResourceAdaptationModule::SetStartBitrate(
+ DataRate start_bitrate) {
+ if (!start_bitrate.IsZero())
+ encoder_target_bitrate_bps_ = start_bitrate.bps();
+ start_bitrate_.set_start_bitrate_ = start_bitrate;
+ start_bitrate_.set_start_bitrate_time_ms_ = clock_->TimeInMicroseconds();
+}
+
+void OveruseFrameDetectorResourceAdaptationModule::SetTargetBitrate(
+ DataRate target_bitrate) {
+ if (!target_bitrate.IsZero())
+ encoder_target_bitrate_bps_ = target_bitrate.bps();
+
+ // Check for bwe drop experiment
+ if (start_bitrate_.set_start_bitrate_ > DataRate::Zero() &&
+ !start_bitrate_.has_seen_first_bwe_drop_ && quality_scaler_ &&
+ quality_scaler_settings_.InitialBitrateIntervalMs() &&
+ quality_scaler_settings_.InitialBitrateFactor()) {
+ int64_t diff_ms = clock_->TimeInMilliseconds() -
+ start_bitrate_.set_start_bitrate_time_ms_;
+ if (diff_ms < quality_scaler_settings_.InitialBitrateIntervalMs().value() &&
+ (target_bitrate <
+ (start_bitrate_.set_start_bitrate_ *
+ quality_scaler_settings_.InitialBitrateFactor().value()))) {
+ RTC_LOG(LS_INFO) << "Reset initial_framedrop_. Start bitrate: "
+ << start_bitrate_.set_start_bitrate_.bps()
+ << ", target bitrate: " << target_bitrate.bps();
+ initial_framedrop_ = 0;
+ start_bitrate_.has_seen_first_bwe_drop_ = true;
+ }
+ }
}
void OveruseFrameDetectorResourceAdaptationModule::
@@ -515,10 +546,6 @@
return initial_framedrop_ < kMaxInitialFramedrop;
}
-void OveruseFrameDetectorResourceAdaptationModule::ResetInitialFrameDropping() {
- initial_framedrop_ = 0;
-}
-
void OveruseFrameDetectorResourceAdaptationModule::UpdateQualityScalerSettings(
absl::optional<VideoEncoder::QpThresholds> qp_thresholds) {
if (qp_thresholds.has_value()) {
@@ -608,9 +635,9 @@
case DegradationPreference::BALANCED: {
// Check if quality should be increased based on bitrate.
if (reason == kQuality &&
- !balanced_settings_.CanAdaptUp(GetVideoCodecTypeOrGeneric(),
- LastInputFrameSizeOrDefault(),
- target_bitrate_bps_.value_or(0))) {
+ !balanced_settings_.CanAdaptUp(
+ GetVideoCodecTypeOrGeneric(), LastInputFrameSizeOrDefault(),
+ encoder_target_bitrate_bps_.value_or(0))) {
return;
}
// Try scale up framerate, if higher.
@@ -631,7 +658,7 @@
if (reason == kQuality &&
!balanced_settings_.CanAdaptUpResolution(
GetVideoCodecTypeOrGeneric(), LastInputFrameSizeOrDefault(),
- target_bitrate_bps_.value_or(0))) {
+ encoder_target_bitrate_bps_.value_or(0))) {
return;
}
// Scale up resolution.
@@ -642,7 +669,7 @@
// limits specified by encoder capabilities.
if (reason == kQuality &&
!CanAdaptUpResolution(LastInputFrameSizeOrDefault(),
- target_bitrate_bps_.value_or(0))) {
+ encoder_target_bitrate_bps_.value_or(0))) {
return;
}
diff --git a/video/overuse_frame_detector_resource_adaptation_module.h b/video/overuse_frame_detector_resource_adaptation_module.h
index 12471c7b..8767607 100644
--- a/video/overuse_frame_detector_resource_adaptation_module.h
+++ b/video/overuse_frame_detector_resource_adaptation_module.h
@@ -27,6 +27,8 @@
#include "api/video_codecs/video_encoder_config.h"
#include "call/adaptation/resource_adaptation_module_interface.h"
#include "rtc_base/experiments/balanced_degradation_settings.h"
+#include "rtc_base/experiments/quality_scaler_settings.h"
+#include "system_wrappers/include/clock.h"
#include "video/overuse_frame_detector.h"
namespace webrtc {
@@ -54,6 +56,7 @@
// The module can be constructed on any sequence, but must be initialized and
// used on a single sequence, e.g. the encoder queue.
OveruseFrameDetectorResourceAdaptationModule(
+ Clock* clock,
bool experiment_cpu_load_estimator,
std::unique_ptr<OveruseFrameDetector> overuse_detector,
VideoStreamEncoderObserver* encoder_stats_observer,
@@ -73,8 +76,8 @@
void SetDegradationPreference(
DegradationPreference degradation_preference) override;
void SetEncoderSettings(EncoderSettings encoder_settings) override;
- void SetEncoderTargetBitrate(
- absl::optional<uint32_t> target_bitrate_bps) override;
+ void SetStartBitrate(DataRate start_bitrate) override;
+ void SetTargetBitrate(DataRate target_bitrate) override;
void ResetVideoSourceRestrictions() override;
void OnFrame(const VideoFrame& frame) override;
@@ -87,8 +90,6 @@
absl::optional<int> encode_duration_us) override;
void OnFrameDropped(EncodedImageCallback::DropReason reason) override;
bool DropInitialFrames() const;
- // TODO(eshr): Remove once all qp-scaling is in this class.
- void ResetInitialFrameDropping();
// TODO(eshr): This can be made private if we configure on
// SetDegredationPreference and SetEncoderSettings.
@@ -159,6 +160,12 @@
enum class Mode { kAdaptUp, kAdaptDown } mode_;
};
+ struct StartBitrate {
+ bool has_seen_first_bwe_drop_ = false;
+ DataRate set_start_bitrate_ = DataRate::Zero();
+ int64_t set_start_bitrate_time_ms_ = 0;
+ };
+
CpuOveruseOptions GetCpuOveruseOptions() const;
VideoCodecType GetVideoCodecTypeOrGeneric() const;
int LastInputFrameSizeOrDefault() const;
@@ -184,6 +191,7 @@
bool CanAdaptUpResolution(int pixels, uint32_t bitrate_bps) const;
ResourceAdaptationModuleListener* const adaptation_listener_;
+ Clock* clock_;
const bool experiment_cpu_load_estimator_;
// The restrictions that |adaptation_listener_| is informed of.
VideoSourceRestrictions video_source_restrictions_;
@@ -205,9 +213,12 @@
bool overuse_detector_is_started_;
absl::optional<int> last_input_frame_size_;
absl::optional<double> target_frame_rate_;
- absl::optional<uint32_t> target_bitrate_bps_;
+ // This is the last non-zero target bitrate for the encoder.
+ absl::optional<uint32_t> encoder_target_bitrate_bps_;
std::unique_ptr<QualityScaler> quality_scaler_;
const bool quality_scaling_experiment_enabled_;
+ const QualityScalerSettings quality_scaler_settings_;
+ StartBitrate start_bitrate_;
absl::optional<EncoderSettings> encoder_settings_;
VideoStreamEncoderObserver* const encoder_stats_observer_;
// Counts how many frames we've dropped in the initial framedrop phase.
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index cef407a..fe27bc0 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -264,9 +264,6 @@
crop_width_(0),
crop_height_(0),
encoder_target_bitrate_bps_(absl::nullopt),
- set_start_bitrate_bps_(0),
- set_start_bitrate_time_ms_(0),
- has_seen_first_bwe_drop_(false),
max_data_payload_length_(0),
encoder_paused_and_dropped_frame_(false),
was_encode_called_since_last_initialization_(false),
@@ -303,6 +300,7 @@
/*source=*/nullptr)),
resource_adaptation_module_(
std::make_unique<OveruseFrameDetectorResourceAdaptationModule>(
+ clock_,
settings_.experiment_cpu_load_estimator,
std::move(overuse_detector),
encoder_stats_observer,
@@ -391,10 +389,8 @@
encoder_target_bitrate_bps_ =
start_bitrate_bps != 0 ? absl::optional<uint32_t>(start_bitrate_bps)
: absl::nullopt;
- resource_adaptation_module_->SetEncoderTargetBitrate(
- encoder_target_bitrate_bps_);
- set_start_bitrate_bps_ = start_bitrate_bps;
- set_start_bitrate_time_ms_ = clock_->TimeInMilliseconds();
+ resource_adaptation_module_->SetStartBitrate(
+ DataRate::bps(start_bitrate_bps));
});
}
@@ -1537,23 +1533,6 @@
<< " packet loss " << static_cast<int>(fraction_lost)
<< " rtt " << round_trip_time_ms;
- if (set_start_bitrate_bps_ > 0 && !has_seen_first_bwe_drop_ &&
- resource_adaptation_module_->quality_scaler() &&
- quality_scaler_settings_.InitialBitrateIntervalMs() &&
- quality_scaler_settings_.InitialBitrateFactor()) {
- int64_t diff_ms = clock_->TimeInMilliseconds() - set_start_bitrate_time_ms_;
- if (diff_ms < quality_scaler_settings_.InitialBitrateIntervalMs().value() &&
- (target_bitrate.bps() <
- (set_start_bitrate_bps_ *
- quality_scaler_settings_.InitialBitrateFactor().value()))) {
- RTC_LOG(LS_INFO) << "Reset initial_framedrop_. Start bitrate: "
- << set_start_bitrate_bps_
- << ", target bitrate: " << target_bitrate.bps();
- resource_adaptation_module_->ResetInitialFrameDropping();
- has_seen_first_bwe_drop_ = true;
- }
- }
-
if (encoder_) {
encoder_->OnPacketLossRateUpdate(static_cast<float>(fraction_lost) / 256.f);
encoder_->OnRttUpdate(round_trip_time_ms);
@@ -1571,8 +1550,8 @@
if (target_bitrate.bps() != 0)
encoder_target_bitrate_bps_ = target_bitrate.bps();
- resource_adaptation_module_->SetEncoderTargetBitrate(
- encoder_target_bitrate_bps_);
+
+ resource_adaptation_module_->SetTargetBitrate(target_bitrate);
if (video_suspension_changed) {
RTC_LOG(LS_INFO) << "Video suspend state changed to: "
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index 1258054..bba2d8d 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -248,9 +248,6 @@
int crop_height_ RTC_GUARDED_BY(&encoder_queue_);
absl::optional<uint32_t> encoder_target_bitrate_bps_
RTC_GUARDED_BY(&encoder_queue_);
- int set_start_bitrate_bps_ RTC_GUARDED_BY(&encoder_queue_);
- int64_t set_start_bitrate_time_ms_ RTC_GUARDED_BY(&encoder_queue_);
- bool has_seen_first_bwe_drop_ RTC_GUARDED_BY(&encoder_queue_);
size_t max_data_payload_length_ RTC_GUARDED_BY(&encoder_queue_);
absl::optional<EncoderRateSettings> last_encoder_rate_settings_
RTC_GUARDED_BY(&encoder_queue_);