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}
This commit is contained in:
Evan Shrubsole 2020-02-04 16:26:38 +01:00 committed by Commit Bot
parent 0f6bcd18b2
commit 7c3a1fc082
5 changed files with 66 additions and 49 deletions

View File

@ -86,8 +86,11 @@ class ResourceAdaptationModuleInterface {
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?

View File

@ -346,11 +346,13 @@ OveruseFrameDetectorResourceAdaptationModule::AdaptCounter::ToString(
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 @@ OveruseFrameDetectorResourceAdaptationModule::
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 @@ void OveruseFrameDetectorResourceAdaptationModule::SetEncoderSettings(
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 @@ bool OveruseFrameDetectorResourceAdaptationModule::DropInitialFrames() const {
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 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
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 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
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 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
// limits specified by encoder capabilities.
if (reason == kQuality &&
!CanAdaptUpResolution(LastInputFrameSizeOrDefault(),
target_bitrate_bps_.value_or(0))) {
encoder_target_bitrate_bps_.value_or(0))) {
return;
}

View File

@ -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 @@ class OveruseFrameDetectorResourceAdaptationModule
// 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 @@ class OveruseFrameDetectorResourceAdaptationModule
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 @@ class OveruseFrameDetectorResourceAdaptationModule
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 @@ class OveruseFrameDetectorResourceAdaptationModule
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 @@ class OveruseFrameDetectorResourceAdaptationModule
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 @@ class OveruseFrameDetectorResourceAdaptationModule
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.

View File

@ -264,9 +264,6 @@ VideoStreamEncoder::VideoStreamEncoder(
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 @@ VideoStreamEncoder::VideoStreamEncoder(
/*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 @@ void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) {
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 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
<< " 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 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
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: "

View File

@ -248,9 +248,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
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_);