Index: webrtc/video/vie_encoder.cc |
diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc |
index a9e7e097c1d9d97cc87a8938bf918cbf4595aa6c..7af207984d9966ec38330e3c11854da8062fbb81 100644 |
--- a/webrtc/video/vie_encoder.cc |
+++ b/webrtc/video/vie_encoder.cc |
@@ -226,9 +226,8 @@ class ViEEncoder::EncodeTask : public rtc::QueuedTask { |
bool Run() override { |
RTC_DCHECK_RUN_ON(&vie_encoder_->encoder_queue_); |
RTC_DCHECK_GT(vie_encoder_->posted_frames_waiting_for_encode_.Value(), 0); |
- vie_encoder_->stats_proxy_->OnIncomingFrame( |
- frame_.width(), frame_.height(), |
- vie_encoder_->cpu_restricted_counter_ != 0); |
+ vie_encoder_->stats_proxy_->OnIncomingFrame(frame_.width(), |
+ frame_.height()); |
++vie_encoder_->captured_frame_count_; |
if (--vie_encoder_->posted_frames_waiting_for_encode_ == 0) { |
vie_encoder_->EncodeVideoFrame(frame_, time_when_posted_ms_); |
@@ -339,6 +338,11 @@ class ViEEncoder::VideoSourceProxy { |
source_->AddOrUpdateSink(vie_encoder_, sink_wants_); |
} |
+ bool CanScaleResolution() { |
+ rtc::CritScope lock(&crit_); |
+ return !resolution_scaling_disabled_; |
+ } |
+ |
private: |
rtc::CriticalSection crit_; |
rtc::SequencedTaskChecker main_checker_; |
@@ -363,12 +367,13 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
settings_(settings), |
codec_type_(PayloadNameToCodecType(settings.payload_name)), |
video_sender_(Clock::GetRealTimeClock(), this, this), |
- disable_resolution_scaling_(false), |
+ enable_quality_scaling_(false), |
overuse_detector_(Clock::GetRealTimeClock(), |
GetCpuOveruseOptions(settings.full_overuse_time), |
this, |
encoder_timing, |
stats_proxy), |
+ quality_scaler_(new QualityScaler(this)), |
stats_proxy_(stats_proxy), |
pre_encode_callback_(pre_encode_callback), |
module_process_thread_(nullptr), |
@@ -382,7 +387,6 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
has_received_rpsi_(false), |
picture_id_rpsi_(0), |
clock_(Clock::GetRealTimeClock()), |
- cpu_restricted_counter_(0), |
last_frame_width_(0), |
last_frame_height_(0), |
last_captured_timestamp_(0), |
@@ -414,6 +418,8 @@ void ViEEncoder::Stop() { |
video_sender_.RegisterExternalEncoder(nullptr, settings_.payload_type, |
false); |
overuse_detector_.StopCheckForOveruse(); |
+ if (enable_quality_scaling_) |
+ quality_scaler_->Stop(); |
shutdown_event_.Set(); |
}); |
@@ -437,14 +443,9 @@ void ViEEncoder::SetSource(rtc::VideoSourceInterface<VideoFrame>* source, |
bool disable_resolution_scaling) { |
RTC_DCHECK_RUN_ON(&thread_checker_); |
source_proxy_->SetSource(source, disable_resolution_scaling); |
- encoder_queue_.PostTask([this, disable_resolution_scaling] { |
- RTC_DCHECK_RUN_ON(&encoder_queue_); |
- if (disable_resolution_scaling_ != disable_resolution_scaling) { |
- stats_proxy_->SetCpuRestrictedResolution(!disable_resolution_scaling && |
- cpu_restricted_counter_ != 0); |
- } |
- disable_resolution_scaling_ = disable_resolution_scaling; |
- }); |
+ stats_proxy_->SetResolutionRestrictionStats( |
+ !disable_resolution_scaling && scale_counter_[kQuality] > 0, |
+ !disable_resolution_scaling && scale_counter_[kCpu] > 0); |
} |
void ViEEncoder::SetSink(EncoderSink* sink, bool rotation_applied) { |
@@ -517,10 +518,6 @@ void ViEEncoder::ReconfigureEncoder() { |
} |
rate_allocator_.reset(new SimulcastRateAllocator(codec)); |
- if (stats_proxy_) { |
- stats_proxy_->OnEncoderReconfigured(encoder_config_, |
- rate_allocator_->GetPreferedBitrate()); |
- } |
pending_encoder_reconfiguration_ = false; |
if (stats_proxy_) { |
@@ -529,6 +526,19 @@ void ViEEncoder::ReconfigureEncoder() { |
} |
sink_->OnEncoderConfigurationChanged( |
std::move(streams), encoder_config_.min_transmit_bitrate_bps); |
+ |
+ const auto scaling_settings = settings_.encoder->GetQPThresholds(); |
+ enable_quality_scaling_ = scaling_settings.enabled; |
+ if (enable_quality_scaling_) { |
+ LOG(LS_INFO) << "Initializing quality scaler."; |
+ if (quality_scaler_) |
+ quality_scaler_->Stop(); |
+ if (scaling_settings.thresholds) { |
+ quality_scaler_->Init(*(scaling_settings.thresholds)); |
+ } else { |
+ quality_scaler_->Init(codec_type_); |
+ } |
+ } |
} |
void ViEEncoder::OnFrame(const VideoFrame& video_frame) { |
@@ -688,9 +698,11 @@ EncodedImageCallback::Result ViEEncoder::OnEncodedImage( |
int64_t time_sent = clock_->TimeInMilliseconds(); |
uint32_t timestamp = encoded_image._timeStamp; |
- encoder_queue_.PostTask([this, timestamp, time_sent] { |
+ encoder_queue_.PostTask([this, timestamp, time_sent, encoded_image] { |
perkj_webrtc
2016/10/26 15:53:50
This may contain invalid pointers. Copy only the v
kthelgason
2016/10/26 19:02:50
Sorry, I'm not following. Can you elaborate?
|
RTC_DCHECK_RUN_ON(&encoder_queue_); |
overuse_detector_.FrameSent(timestamp, time_sent); |
+ if (enable_quality_scaling_) |
+ quality_scaler_->ReportQP(encoded_image.qp_); |
}); |
return result; |
} |
@@ -767,46 +779,66 @@ void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps, |
} |
} |
-void ViEEncoder::OveruseDetected() { |
+void ViEEncoder::ScaleDown(ScaleReason reason) { |
RTC_DCHECK_RUN_ON(&encoder_queue_); |
- |
- if (disable_resolution_scaling_) |
- return; |
- |
- if (cpu_restricted_counter_ >= kMaxCpuDowngrades) { |
- return; |
- } |
// Request lower resolution if the current resolution is lower than last time |
// we asked for the resolution to be lowered. |
- // Update stats accordingly. |
int current_pixel_count = last_frame_height_ * last_frame_width_; |
- if (current_pixel_count < |
+ if (current_pixel_count >= |
max_pixel_count_.value_or(current_pixel_count + 1)) { |
- max_pixel_count_ = rtc::Optional<int>(current_pixel_count); |
- max_pixel_count_step_up_ = rtc::Optional<int>(); |
- stats_proxy_->OnCpuRestrictedResolutionChanged(true); |
- ++cpu_restricted_counter_; |
- source_proxy_->RequestResolutionLowerThan(current_pixel_count); |
+ return; |
+ } |
+ if (!source_proxy_->CanScaleResolution()) |
+ return; |
+ max_pixel_count_ = rtc::Optional<int>(current_pixel_count); |
+ max_pixel_count_step_up_ = rtc::Optional<int>(); |
+ |
+ switch (reason) { |
+ case kQuality: |
+ if (!enable_quality_scaling_) |
+ return; |
+ stats_proxy_->OnQualityRestrictedResolutionChanged(true); |
+ break; |
+ case kCpu: |
+ if (scale_counter_[reason] >= kMaxCpuDowngrades) |
+ return; |
+ // Update stats accordingly. |
+ stats_proxy_->OnCpuRestrictedResolutionChanged(true); |
+ break; |
} |
+ ++scale_counter_[reason]; |
+ source_proxy_->RequestResolutionLowerThan(current_pixel_count); |
} |
-void ViEEncoder::NormalUsage() { |
+void ViEEncoder::ScaleUp(ScaleReason reason) { |
RTC_DCHECK_RUN_ON(&encoder_queue_); |
- if (disable_resolution_scaling_) |
- return; |
- |
- int current_pixel_count = last_frame_height_ * last_frame_width_; |
+ RTC_DCHECK_GE(scale_counter_[reason], 0); |
// Request higher resolution if we are cpu restricted and the the current |
// resolution is higher than last time we requested higher resolution. |
- // Update stats accordingly. |
- if (cpu_restricted_counter_ > 0 && |
- current_pixel_count > max_pixel_count_step_up_.value_or(0)) { |
- max_pixel_count_ = rtc::Optional<int>(); |
- max_pixel_count_step_up_ = rtc::Optional<int>(current_pixel_count); |
- --cpu_restricted_counter_; |
- stats_proxy_->OnCpuRestrictedResolutionChanged(cpu_restricted_counter_ > 0); |
- source_proxy_->RequestHigherResolutionThan(current_pixel_count); |
+ if (scale_counter_[reason] == 0) |
+ return; |
+ if (!source_proxy_->CanScaleResolution()) |
+ return; |
+ int current_pixel_count = last_frame_height_ * last_frame_width_; |
+ if (current_pixel_count <= max_pixel_count_step_up_.value_or(0)) |
+ return; |
+ max_pixel_count_ = rtc::Optional<int>(); |
+ max_pixel_count_step_up_ = rtc::Optional<int>(current_pixel_count); |
+ switch (reason) { |
+ case kQuality: |
+ if (!enable_quality_scaling_) |
+ return; |
+ stats_proxy_->OnQualityRestrictedResolutionChanged( |
+ scale_counter_[reason] > 1); |
+ break; |
+ case kCpu: |
+ // Update stats accordingly. |
+ stats_proxy_->OnCpuRestrictedResolutionChanged(scale_counter_[reason] > |
+ 1); |
+ break; |
} |
+ --scale_counter_[reason]; |
+ source_proxy_->RequestHigherResolutionThan(current_pixel_count); |
} |
} // namespace webrtc |