[Overuse] Setting the target bitrate through the interface.
The poorly named SetEncoderStartBitrate() is renamed
SetEncoderTargetBitrate() and added to the abstract resource adaptation
module interface.
The so-called "start bitrate" was updated to match the target bitrate,
so this was only ever a "start bitrate" until we had any estimates. The
variable is renamed in VideoStreamEncoder as well, and usage of optional
types are introduced to avoid magical values in a few places in the
existing code.
Bug: webrtc:11222
Change-Id: Idde92f68f34616aa3c34ab77a791fdbe7ea7af26
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/166880
Reviewed-by: Evan Shrubsole <eshr@google.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30347}
diff --git a/call/adaptation/resource_adaptation_module_interface.h b/call/adaptation/resource_adaptation_module_interface.h
index bc64b8e..61380b9 100644
--- a/call/adaptation/resource_adaptation_module_interface.h
+++ b/call/adaptation/resource_adaptation_module_interface.h
@@ -11,6 +11,7 @@
#ifndef CALL_ADAPTATION_RESOURCE_ADAPTATION_MODULE_INTERFACE_H_
#define CALL_ADAPTATION_RESOURCE_ADAPTATION_MODULE_INTERFACE_H_
+#include "absl/types/optional.h"
#include "api/rtp_parameters.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_config.h"
@@ -84,6 +85,8 @@
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;
// 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 bd27eda..1ba33e1 100644
--- a/video/overuse_frame_detector_resource_adaptation_module.cc
+++ b/video/overuse_frame_detector_resource_adaptation_module.cc
@@ -357,7 +357,7 @@
overuse_detector_(std::move(overuse_detector)),
overuse_detector_is_started_(false),
target_frame_rate_(absl::nullopt),
- encoder_start_bitrate_bps_(0),
+ target_bitrate_bps_(absl::nullopt),
is_quality_scaler_enabled_(false),
encoder_settings_(absl::nullopt),
encoder_stats_observer_(encoder_stats_observer) {
@@ -426,6 +426,11 @@
MaybeUpdateTargetFrameRate();
}
+void OveruseFrameDetectorResourceAdaptationModule::SetEncoderTargetBitrate(
+ absl::optional<uint32_t> target_bitrate_bps) {
+ target_bitrate_bps_ = target_bitrate_bps;
+}
+
void OveruseFrameDetectorResourceAdaptationModule::
ResetVideoSourceRestrictions() {
last_adaptation_request_.reset();
@@ -472,11 +477,6 @@
last_frame_pixel_count_ = last_frame_pixel_count;
}
-void OveruseFrameDetectorResourceAdaptationModule::SetEncoderStartBitrateBps(
- uint32_t encoder_start_bitrate_bps) {
- encoder_start_bitrate_bps_ = encoder_start_bitrate_bps;
-}
-
void OveruseFrameDetectorResourceAdaptationModule::SetIsQualityScalerEnabled(
bool is_quality_scaler_enabled) {
is_quality_scaler_enabled_ = is_quality_scaler_enabled;
@@ -516,7 +516,7 @@
if (reason == kQuality &&
!balanced_settings_.CanAdaptUp(GetVideoCodecTypeOrGeneric(),
*last_frame_pixel_count_,
- encoder_start_bitrate_bps_)) {
+ target_bitrate_bps_.value_or(0))) {
return;
}
// Try scale up framerate, if higher.
@@ -537,7 +537,7 @@
if (reason == kQuality &&
!balanced_settings_.CanAdaptUpResolution(
GetVideoCodecTypeOrGeneric(), *last_frame_pixel_count_,
- encoder_start_bitrate_bps_)) {
+ target_bitrate_bps_.value_or(0))) {
return;
}
// Scale up resolution.
@@ -548,7 +548,7 @@
// limits specified by encoder capabilities.
if (reason == kQuality &&
!CanAdaptUpResolution(*last_frame_pixel_count_,
- encoder_start_bitrate_bps_)) {
+ 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 efc2ec8..f4080bd 100644
--- a/video/overuse_frame_detector_resource_adaptation_module.h
+++ b/video/overuse_frame_detector_resource_adaptation_module.h
@@ -73,6 +73,8 @@
void SetDegradationPreference(
DegradationPreference degradation_preference) override;
void SetEncoderSettings(EncoderSettings encoder_settings) override;
+ void SetEncoderTargetBitrate(
+ absl::optional<uint32_t> target_bitrate_bps) override;
void ResetVideoSourceRestrictions() override;
// Input to the OveruseFrameDetector, which are required for this module to
@@ -92,7 +94,6 @@
// resource adaptation module. Unify code paths where possible. Do we really
// need this many public methods?
void SetLastFramePixelCount(absl::optional<int> last_frame_pixel_count);
- void SetEncoderStartBitrateBps(uint32_t encoder_start_bitrate_bps);
// Inform the detector whether or not the quality scaler is enabled. This
// helps GetActiveCounts() return absl::nullopt when appropriate.
// TODO(hbos): This feels really hacky, can we report the right values without
@@ -215,7 +216,7 @@
const std::unique_ptr<OveruseFrameDetector> overuse_detector_;
bool overuse_detector_is_started_;
absl::optional<double> target_frame_rate_;
- uint32_t encoder_start_bitrate_bps_;
+ absl::optional<uint32_t> target_bitrate_bps_;
bool is_quality_scaler_enabled_;
absl::optional<EncoderSettings> encoder_settings_;
VideoStreamEncoderObserver* const encoder_stats_observer_;
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 65e81c1..486143c 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -279,7 +279,7 @@
pending_encoder_creation_(false),
crop_width_(0),
crop_height_(0),
- encoder_start_bitrate_bps_(0),
+ encoder_target_bitrate_bps_(absl::nullopt),
set_start_bitrate_bps_(0),
set_start_bitrate_time_ms_(0),
has_seen_first_bwe_drop_(false),
@@ -405,9 +405,11 @@
void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) {
encoder_queue_.PostTask([this, start_bitrate_bps] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
- encoder_start_bitrate_bps_ = start_bitrate_bps;
- resource_adaptation_module_->SetEncoderStartBitrateBps(
- encoder_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();
});
@@ -619,8 +621,8 @@
}
RTC_LOG(LS_INFO) << log_stream.str();
- codec.startBitrate =
- std::max(encoder_start_bitrate_bps_ / 1000, codec.minBitrate);
+ codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000,
+ codec.minBitrate);
codec.startBitrate = std::min(codec.startBitrate, codec.maxBitrate);
codec.expect_encode_from_texture = last_frame_info_->is_texture;
// Make sure the start bit rate is sane...
@@ -1617,11 +1619,11 @@
// On significant changes to BWE at the start of the call,
// enable frame drops to quickly react to jumps in available bandwidth.
- if (encoder_start_bitrate_bps_ != 0 &&
+ if (encoder_target_bitrate_bps_.has_value() &&
!has_seen_first_significant_bwe_change_ && quality_scaler_ &&
initial_framedrop_on_bwe_enabled_ &&
- abs_diff(target_bitrate.bps(), encoder_start_bitrate_bps_) >=
- kFramedropThreshold * encoder_start_bitrate_bps_) {
+ abs_diff(target_bitrate.bps(), encoder_target_bitrate_bps_.value()) >=
+ kFramedropThreshold * encoder_target_bitrate_bps_.value()) {
// Reset initial framedrop feature when first real BW estimate arrives.
// TODO(kthelgason): Update BitrateAllocator to not call OnBitrateUpdated
// without an actual BW estimate.
@@ -1659,11 +1661,10 @@
link_allocation, target_bitrate, stable_target_bitrate};
SetEncoderRates(UpdateBitrateAllocationAndNotifyObserver(new_rate_settings));
- encoder_start_bitrate_bps_ = target_bitrate.bps() != 0
- ? target_bitrate.bps()
- : encoder_start_bitrate_bps_;
- resource_adaptation_module_->SetEncoderStartBitrateBps(
- encoder_start_bitrate_bps_);
+ if (target_bitrate.bps() != 0)
+ encoder_target_bitrate_bps_ = target_bitrate.bps();
+ resource_adaptation_module_->SetEncoderTargetBitrate(
+ encoder_target_bitrate_bps_);
if (video_suspension_changed) {
RTC_LOG(LS_INFO) << "Video suspend state changed to: "
@@ -1681,7 +1682,7 @@
bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const {
if (initial_framedrop_ >= kMaxInitialFramedrop ||
- encoder_start_bitrate_bps_ == 0) {
+ !encoder_target_bitrate_bps_.has_value()) {
return false;
}
@@ -1690,13 +1691,13 @@
if (encoder_bitrate_limits.has_value()) {
// Use bitrate limits provided by encoder.
- return encoder_start_bitrate_bps_ <
+ return encoder_target_bitrate_bps_.value() <
static_cast<uint32_t>(encoder_bitrate_limits->min_start_bitrate_bps);
}
- if (encoder_start_bitrate_bps_ < 300000 /* qvga */) {
+ if (encoder_target_bitrate_bps_.value() < 300000 /* qvga */) {
return pixel_count > 320 * 240;
- } else if (encoder_start_bitrate_bps_ < 500000 /* vga */) {
+ } else if (encoder_target_bitrate_bps_.value() < 500000 /* vga */) {
return pixel_count > 640 * 480;
}
return false;
@@ -1713,7 +1714,8 @@
if (quality_rampup_experiment_.BwHigh(now_ms, bw_kbps)) {
// Verify that encoder is at max bitrate and the QP is low.
- if (encoder_start_bitrate_bps_ == send_codec_.maxBitrate * 1000 &&
+ if (encoder_target_bitrate_bps_.value_or(0) ==
+ send_codec_.maxBitrate * 1000 &&
quality_scaler_->QpFastFilterLow()) {
return true;
}
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index bd76ee5..5ac6db8 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -251,7 +251,8 @@
RTC_GUARDED_BY(&encoder_queue_);
int crop_width_ RTC_GUARDED_BY(&encoder_queue_);
int crop_height_ RTC_GUARDED_BY(&encoder_queue_);
- uint32_t encoder_start_bitrate_bps_ 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_);