Move quality scaler into adaptation module
This allows for further refactoring, eventually moving all of quality scaler out of video stream encoder. Bug: webrtc:11222 Change-Id: Id121608da56f57549a616ccc5f141bb598668b40 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/167728 Commit-Queue: Evan Shrubsole <eshr@google.com> Reviewed-by: Henrik Boström <hbos@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30417}
This commit is contained in:

committed by
Commit Bot

parent
1cf15bfe55
commit
cf0595234c
@ -359,7 +359,7 @@ OveruseFrameDetectorResourceAdaptationModule::
|
||||
last_input_frame_size_(absl::nullopt),
|
||||
target_frame_rate_(absl::nullopt),
|
||||
target_bitrate_bps_(absl::nullopt),
|
||||
is_quality_scaler_enabled_(false),
|
||||
quality_scaler_(nullptr),
|
||||
encoder_settings_(absl::nullopt),
|
||||
encoder_stats_observer_(encoder_stats_observer) {
|
||||
RTC_DCHECK(adaptation_listener_);
|
||||
@ -480,9 +480,14 @@ void OveruseFrameDetectorResourceAdaptationModule::OnEncodeCompleted(
|
||||
encode_duration_us);
|
||||
}
|
||||
|
||||
void OveruseFrameDetectorResourceAdaptationModule::SetIsQualityScalerEnabled(
|
||||
bool is_quality_scaler_enabled) {
|
||||
is_quality_scaler_enabled_ = is_quality_scaler_enabled;
|
||||
void OveruseFrameDetectorResourceAdaptationModule::UpdateQualityScalerSettings(
|
||||
absl::optional<VideoEncoder::QpThresholds> qp_thresholds) {
|
||||
if (qp_thresholds.has_value()) {
|
||||
quality_scaler_ =
|
||||
std::make_unique<QualityScaler>(this, qp_thresholds.value());
|
||||
} else {
|
||||
quality_scaler_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
|
||||
@ -824,11 +829,11 @@ OveruseFrameDetectorResourceAdaptationModule::GetActiveCounts(
|
||||
break;
|
||||
case kQuality:
|
||||
if (!IsFramerateScalingEnabled(degradation_preference_) ||
|
||||
!is_quality_scaler_enabled_) {
|
||||
!quality_scaler_) {
|
||||
counts.num_framerate_reductions = absl::nullopt;
|
||||
}
|
||||
if (!IsResolutionScalingEnabled(degradation_preference_) ||
|
||||
!is_quality_scaler_enabled_) {
|
||||
!quality_scaler_) {
|
||||
counts.num_resolution_reductions = absl::nullopt;
|
||||
}
|
||||
break;
|
||||
|
@ -63,6 +63,7 @@ class OveruseFrameDetectorResourceAdaptationModule
|
||||
DegradationPreference degradation_preference() const {
|
||||
return degradation_preference_;
|
||||
}
|
||||
QualityScaler* quality_scaler() const { return quality_scaler_.get(); }
|
||||
|
||||
// ResourceAdaptationModuleInterface implementation.
|
||||
void StartResourceAdaptation(
|
||||
@ -85,12 +86,9 @@ class OveruseFrameDetectorResourceAdaptationModule
|
||||
int64_t capture_time_us,
|
||||
absl::optional<int> encode_duration_us) override;
|
||||
|
||||
// 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
|
||||
// this boolean? It would be really easy to report the wrong thing if this
|
||||
// method is called incorrectly.
|
||||
void SetIsQualityScalerEnabled(bool is_quality_scaler_enabled);
|
||||
// Use nullopt to disable quality scaling.
|
||||
void UpdateQualityScalerSettings(
|
||||
absl::optional<VideoEncoder::QpThresholds> qp_thresholds);
|
||||
|
||||
class AdaptCounter final {
|
||||
public:
|
||||
@ -209,7 +207,7 @@ class OveruseFrameDetectorResourceAdaptationModule
|
||||
absl::optional<int> last_input_frame_size_;
|
||||
absl::optional<double> target_frame_rate_;
|
||||
absl::optional<uint32_t> target_bitrate_bps_;
|
||||
bool is_quality_scaler_enabled_;
|
||||
std::unique_ptr<QualityScaler> quality_scaler_;
|
||||
absl::optional<EncoderSettings> encoder_settings_;
|
||||
VideoStreamEncoderObserver* const encoder_stats_observer_;
|
||||
};
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/video/encoded_image.h"
|
||||
#include "api/video/i420_buffer.h"
|
||||
#include "api/video/video_bitrate_allocator_factory.h"
|
||||
@ -341,8 +342,7 @@ void VideoStreamEncoder::Stop() {
|
||||
rate_allocator_ = nullptr;
|
||||
bitrate_observer_ = nullptr;
|
||||
ReleaseEncoder();
|
||||
quality_scaler_ = nullptr;
|
||||
resource_adaptation_module_->SetIsQualityScalerEnabled(false);
|
||||
resource_adaptation_module_->UpdateQualityScalerSettings(absl::nullopt);
|
||||
shutdown_event_.Set();
|
||||
});
|
||||
|
||||
@ -786,7 +786,7 @@ void VideoStreamEncoder::ConfigureQualityScaler(
|
||||
scaling_settings.thresholds;
|
||||
|
||||
if (quality_scaling_allowed) {
|
||||
if (quality_scaler_ == nullptr) {
|
||||
if (resource_adaptation_module_->quality_scaler() == nullptr) {
|
||||
// Quality scaler has not already been configured.
|
||||
|
||||
// Use experimental thresholds if available.
|
||||
@ -795,28 +795,24 @@ void VideoStreamEncoder::ConfigureQualityScaler(
|
||||
experimental_thresholds = QualityScalingExperiment::GetQpThresholds(
|
||||
encoder_config_.codec_type);
|
||||
}
|
||||
// Since the interface is non-public, std::make_unique can't do this
|
||||
// upcast.
|
||||
AdaptationObserverInterface* observer = resource_adaptation_module_.get();
|
||||
quality_scaler_ = std::make_unique<QualityScaler>(
|
||||
observer, experimental_thresholds ? *experimental_thresholds
|
||||
resource_adaptation_module_->UpdateQualityScalerSettings(
|
||||
experimental_thresholds ? *experimental_thresholds
|
||||
: *(scaling_settings.thresholds));
|
||||
resource_adaptation_module_->SetIsQualityScalerEnabled(true);
|
||||
initial_framedrop_ = 0;
|
||||
}
|
||||
} else {
|
||||
quality_scaler_.reset(nullptr);
|
||||
resource_adaptation_module_->SetIsQualityScalerEnabled(false);
|
||||
resource_adaptation_module_->UpdateQualityScalerSettings(absl::nullopt);
|
||||
initial_framedrop_ = kMaxInitialFramedrop;
|
||||
}
|
||||
|
||||
QualityScaler* quality_scaler = resource_adaptation_module_->quality_scaler();
|
||||
if (resource_adaptation_module_->degradation_preference() ==
|
||||
DegradationPreference::BALANCED &&
|
||||
quality_scaler_ && last_frame_info_) {
|
||||
quality_scaler && last_frame_info_) {
|
||||
absl::optional<VideoEncoder::QpThresholds> thresholds =
|
||||
resource_adaptation_module_->GetQpThresholds();
|
||||
if (thresholds) {
|
||||
quality_scaler_->SetQpThresholds(*thresholds);
|
||||
quality_scaler->SetQpThresholds(*thresholds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1553,8 +1549,10 @@ void VideoStreamEncoder::OnDroppedFrame(DropReason reason) {
|
||||
VideoStreamEncoderObserver::DropReason::kMediaOptimization);
|
||||
encoder_queue_.PostTask([this] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
if (quality_scaler_)
|
||||
quality_scaler_->ReportDroppedFrameByMediaOpt();
|
||||
QualityScaler* quality_scaler =
|
||||
resource_adaptation_module_->quality_scaler();
|
||||
if (quality_scaler)
|
||||
quality_scaler->ReportDroppedFrameByMediaOpt();
|
||||
});
|
||||
break;
|
||||
case DropReason::kDroppedByEncoder:
|
||||
@ -1562,8 +1560,10 @@ void VideoStreamEncoder::OnDroppedFrame(DropReason reason) {
|
||||
VideoStreamEncoderObserver::DropReason::kEncoder);
|
||||
encoder_queue_.PostTask([this] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
if (quality_scaler_)
|
||||
quality_scaler_->ReportDroppedFrameByEncoder();
|
||||
QualityScaler* quality_scaler =
|
||||
resource_adaptation_module_->quality_scaler();
|
||||
if (quality_scaler)
|
||||
quality_scaler->ReportDroppedFrameByEncoder();
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -1607,7 +1607,8 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
|
||||
<< " rtt " << round_trip_time_ms;
|
||||
|
||||
if (set_start_bitrate_bps_ > 0 && !has_seen_first_bwe_drop_ &&
|
||||
quality_scaler_ && quality_scaler_settings_.InitialBitrateIntervalMs() &&
|
||||
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() &&
|
||||
@ -1680,7 +1681,8 @@ bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const {
|
||||
}
|
||||
|
||||
bool VideoStreamEncoder::TryQualityRampup(int64_t now_ms) {
|
||||
if (!quality_scaler_)
|
||||
QualityScaler* quality_scaler = resource_adaptation_module_->quality_scaler();
|
||||
if (!quality_scaler)
|
||||
return false;
|
||||
|
||||
uint32_t bw_kbps = last_encoder_rate_settings_
|
||||
@ -1692,7 +1694,7 @@ bool VideoStreamEncoder::TryQualityRampup(int64_t now_ms) {
|
||||
// Verify that encoder is at max bitrate and the QP is low.
|
||||
if (encoder_target_bitrate_bps_.value_or(0) ==
|
||||
send_codec_.maxBitrate * 1000 &&
|
||||
quality_scaler_->QpFastFilterLow()) {
|
||||
quality_scaler->QpFastFilterLow()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1764,8 +1766,9 @@ void VideoStreamEncoder::RunPostEncode(const EncodedImage& encoded_image,
|
||||
encoded_image.Timestamp(), time_sent_us,
|
||||
encoded_image.capture_time_ms_ * rtc::kNumMicrosecsPerMillisec,
|
||||
encode_duration_us);
|
||||
if (quality_scaler_ && encoded_image.qp_ >= 0)
|
||||
quality_scaler_->ReportQp(encoded_image.qp_, time_sent_us);
|
||||
QualityScaler* quality_scaler = resource_adaptation_module_->quality_scaler();
|
||||
if (quality_scaler && encoded_image.qp_ >= 0)
|
||||
quality_scaler->ReportQp(encoded_image.qp_, time_sent_us);
|
||||
if (bitrate_adjuster_) {
|
||||
bitrate_adjuster_->OnEncodedFrame(encoded_image, temporal_index);
|
||||
}
|
||||
|
@ -226,9 +226,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
||||
const RateControlSettings rate_control_settings_;
|
||||
const QualityScalerSettings quality_scaler_settings_;
|
||||
|
||||
std::unique_ptr<QualityScaler> quality_scaler_ RTC_GUARDED_BY(&encoder_queue_)
|
||||
RTC_PT_GUARDED_BY(&encoder_queue_);
|
||||
|
||||
VideoStreamEncoderObserver* const encoder_stats_observer_;
|
||||
// |thread_checker_| checks that public methods that are related to lifetime
|
||||
// of VideoStreamEncoder are called on the same thread.
|
||||
|
Reference in New Issue
Block a user