| Index: webrtc/video/vie_encoder.cc
|
| diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc
|
| index 2287a7e3bb911b74d1889a3113b5c193a03d79b7..524c3482442c5d1370b8ba672d246e130ef14268 100644
|
| --- a/webrtc/video/vie_encoder.cc
|
| +++ b/webrtc/video/vie_encoder.cc
|
| @@ -72,6 +72,22 @@ uint32_t MaximumFrameSizeForBitrate(uint32_t kbps) {
|
| return std::numeric_limits<uint32_t>::max();
|
| }
|
|
|
| +bool IsResolutionScalingEnabled(
|
| + VideoSendStream::DegradationPreference degradation_preference) {
|
| + return degradation_preference ==
|
| + VideoSendStream::DegradationPreference::kMaintainFramerate ||
|
| + degradation_preference ==
|
| + VideoSendStream::DegradationPreference::kBalanced;
|
| +}
|
| +
|
| +bool IsFramerateScalingEnabled(
|
| + VideoSendStream::DegradationPreference degradation_preference) {
|
| + return degradation_preference ==
|
| + VideoSendStream::DegradationPreference::kMaintainResolution ||
|
| + degradation_preference ==
|
| + VideoSendStream::DegradationPreference::kBalanced;
|
| +}
|
| +
|
| } // namespace
|
|
|
| class ViEEncoder::ConfigureEncoderTask : public rtc::QueuedTask {
|
| @@ -419,8 +435,7 @@ void ViEEncoder::SetBitrateObserver(
|
|
|
| void ViEEncoder::SetSource(
|
| rtc::VideoSourceInterface<VideoFrame>* source,
|
| - const VideoSendStream::VideoSendStream::DegradationPreference&
|
| - degradation_preference) {
|
| + const VideoSendStream::DegradationPreference& degradation_preference) {
|
| RTC_DCHECK_RUN_ON(&thread_checker_);
|
| source_proxy_->SetSource(source, degradation_preference);
|
| encoder_queue_.PostTask([this, degradation_preference] {
|
| @@ -546,27 +561,24 @@ void ViEEncoder::ConfigureQualityScaler() {
|
| const bool quality_scaling_allowed =
|
| degradation_preference_allows_scaling && scaling_settings.enabled;
|
|
|
| - const std::vector<int>& scale_counters = GetScaleCounters();
|
| - stats_proxy_->SetCpuScalingStats(
|
| - degradation_preference_allows_scaling ? scale_counters[kCpu] : -1);
|
| - stats_proxy_->SetQualityScalingStats(
|
| - quality_scaling_allowed ? scale_counters[kQuality] : -1);
|
| -
|
| if (quality_scaling_allowed) {
|
| - // Abort if quality scaler has already been configured.
|
| - if (quality_scaler_.get() != nullptr)
|
| - return;
|
| - // Drop frames and scale down until desired quality is achieved.
|
| - if (scaling_settings.thresholds) {
|
| - quality_scaler_.reset(
|
| - new QualityScaler(this, *(scaling_settings.thresholds)));
|
| - } else {
|
| - quality_scaler_.reset(new QualityScaler(this, codec_type_));
|
| + if (quality_scaler_.get() == nullptr) {
|
| + // Quality scaler has not already been configured.
|
| + // Drop frames and scale down until desired quality is achieved.
|
| + if (scaling_settings.thresholds) {
|
| + quality_scaler_.reset(
|
| + new QualityScaler(this, *(scaling_settings.thresholds)));
|
| + } else {
|
| + quality_scaler_.reset(new QualityScaler(this, codec_type_));
|
| + }
|
| }
|
| } else {
|
| quality_scaler_.reset(nullptr);
|
| initial_rampup_ = kMaxInitialFramedrop;
|
| }
|
| +
|
| + stats_proxy_->SetAdaptationStats(GetActiveCounts(kCpu),
|
| + GetActiveCounts(kQuality));
|
| }
|
|
|
| void ViEEncoder::OnFrame(const VideoFrame& video_frame) {
|
| @@ -799,6 +811,7 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
|
| last_frame_info_->pixel_count(),
|
| stats_proxy_->GetStats().input_frame_rate,
|
| AdaptationRequest::Mode::kAdaptDown};
|
| +
|
| bool downgrade_requested =
|
| last_adaptation_request_ &&
|
| last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown;
|
| @@ -836,8 +849,7 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
|
| }
|
|
|
| if (reason == kCpu) {
|
| - const int cpu_scale_counter = GetScaleCounters()[reason];
|
| - if (cpu_scale_counter >= max_downgrades)
|
| + if (GetConstAdaptCounter().TotalCount(kCpu) >= max_downgrades)
|
| return;
|
| }
|
|
|
| @@ -850,11 +862,13 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
|
| return;
|
| }
|
| LOG(LS_INFO) << "Scaling down resolution.";
|
| + GetAdaptCounter().IncrementResolution(reason, 1);
|
| break;
|
| case VideoSendStream::DegradationPreference::kMaintainResolution:
|
| source_proxy_->RequestFramerateLowerThan(
|
| adaptation_request.framerate_fps_);
|
| LOG(LS_INFO) << "Scaling down framerate.";
|
| + GetAdaptCounter().IncrementFramerate(reason, 1);
|
| break;
|
| case VideoSendStream::DegradationPreference::kDegradationDisabled:
|
| RTC_NOTREACHED();
|
| @@ -862,32 +876,20 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
|
|
|
| last_adaptation_request_.emplace(adaptation_request);
|
|
|
| - IncrementScaleCounter(reason, 1);
|
| -
|
| - // Update stats.
|
| - const std::vector<int>& scale_counters = GetScaleCounters();
|
| - switch (reason) {
|
| - case kQuality:
|
| - stats_proxy_->OnQualityRestrictedResolutionChanged(
|
| - scale_counters[reason]);
|
| - break;
|
| - case kCpu:
|
| - stats_proxy_->OnCpuRestrictedResolutionChanged(true);
|
| - break;
|
| - }
|
| + UpdateAdaptationStats(reason);
|
|
|
| - for (size_t i = 0; i < kScaleReasonSize; ++i) {
|
| - LOG(LS_INFO) << "Scaled " << scale_counters[i]
|
| - << " times for reason: " << (i ? "cpu" : "quality");
|
| - }
|
| + LOG(LS_INFO) << GetConstAdaptCounter().ToString();
|
| }
|
|
|
| void ViEEncoder::AdaptUp(AdaptReason reason) {
|
| RTC_DCHECK_RUN_ON(&encoder_queue_);
|
| - int scale_counter = GetScaleCounters()[reason];
|
| - if (scale_counter == 0)
|
| +
|
| + const AdaptCounter& adapt_counter = GetConstAdaptCounter();
|
| + int num_downgrades = adapt_counter.TotalCount(reason);
|
| + if (num_downgrades == 0)
|
| return;
|
| - RTC_DCHECK_GT(scale_counter, 0);
|
| + RTC_DCHECK_GT(num_downgrades, 0);
|
| +
|
| AdaptationRequest adaptation_request = {
|
| last_frame_info_->pixel_count(),
|
| stats_proxy_->GetStats().input_frame_rate,
|
| @@ -896,6 +898,7 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
|
| bool adapt_up_requested =
|
| last_adaptation_request_ &&
|
| last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp;
|
| +
|
| switch (degradation_preference_) {
|
| case VideoSendStream::DegradationPreference::kBalanced:
|
| FALLTHROUGH();
|
| @@ -916,20 +919,11 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
|
| return;
|
| }
|
|
|
| - // Decrease counter of how many times we have scaled down, for this
|
| - // degradation preference mode and reason.
|
| - IncrementScaleCounter(reason, -1);
|
| -
|
| - // Get a sum of how many times have scaled down, in total, for this
|
| - // degradation preference mode. If it is 0, remove any restraints.
|
| - const std::vector<int>& scale_counters = GetScaleCounters();
|
| - const int scale_sum =
|
| - std::accumulate(scale_counters.begin(), scale_counters.end(), 0);
|
| switch (degradation_preference_) {
|
| case VideoSendStream::DegradationPreference::kBalanced:
|
| FALLTHROUGH();
|
| case VideoSendStream::DegradationPreference::kMaintainFramerate:
|
| - if (scale_sum == 0) {
|
| + if (adapt_counter.TotalCount() == 1) {
|
| LOG(LS_INFO) << "Removing resolution down-scaling setting.";
|
| source_proxy_->RequestHigherResolutionThan(
|
| std::numeric_limits<int>::max());
|
| @@ -938,9 +932,10 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
|
| adaptation_request.input_pixel_count_);
|
| LOG(LS_INFO) << "Scaling up resolution.";
|
| }
|
| + GetAdaptCounter().IncrementResolution(reason, -1);
|
| break;
|
| case VideoSendStream::DegradationPreference::kMaintainResolution:
|
| - if (scale_sum == 0) {
|
| + if (adapt_counter.TotalCount() == 1) {
|
| LOG(LS_INFO) << "Removing framerate down-scaling setting.";
|
| source_proxy_->RequestHigherFramerateThan(
|
| std::numeric_limits<int>::max());
|
| @@ -949,6 +944,7 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
|
| adaptation_request.framerate_fps_);
|
| LOG(LS_INFO) << "Scaling up framerate.";
|
| }
|
| + GetAdaptCounter().IncrementFramerate(reason, -1);
|
| break;
|
| case VideoSendStream::DegradationPreference::kDegradationDisabled:
|
| RTC_NOTREACHED();
|
| @@ -956,40 +952,120 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
|
|
|
| last_adaptation_request_.emplace(adaptation_request);
|
|
|
| - // Update stats.
|
| + UpdateAdaptationStats(reason);
|
| +
|
| + LOG(LS_INFO) << adapt_counter.ToString();
|
| +}
|
| +
|
| +void ViEEncoder::UpdateAdaptationStats(AdaptReason reason) {
|
| switch (reason) {
|
| + case kCpu:
|
| + stats_proxy_->OnCpuAdaptationChanged(GetActiveCounts(kCpu),
|
| + GetActiveCounts(kQuality));
|
| + break;
|
| case kQuality:
|
| - stats_proxy_->OnQualityRestrictedResolutionChanged(
|
| - scale_counters[reason]);
|
| + stats_proxy_->OnQualityAdaptationChanged(GetActiveCounts(kCpu),
|
| + GetActiveCounts(kQuality));
|
| break;
|
| + }
|
| +}
|
| +
|
| +ViEEncoder::AdaptCounts ViEEncoder::GetActiveCounts(AdaptReason reason) {
|
| + ViEEncoder::AdaptCounts counts = GetConstAdaptCounter().Counts(reason);
|
| + switch (reason) {
|
| case kCpu:
|
| - stats_proxy_->OnCpuRestrictedResolutionChanged(scale_counters[reason] >
|
| - 0);
|
| + if (!IsFramerateScalingEnabled(degradation_preference_))
|
| + counts.fps = -1;
|
| + if (!IsResolutionScalingEnabled(degradation_preference_))
|
| + counts.resolution = -1;
|
| + break;
|
| + case kQuality:
|
| + if (!IsFramerateScalingEnabled(degradation_preference_) ||
|
| + !quality_scaler_) {
|
| + counts.fps = -1;
|
| + }
|
| + if (!IsResolutionScalingEnabled(degradation_preference_) ||
|
| + !quality_scaler_) {
|
| + counts.resolution = -1;
|
| + }
|
| break;
|
| }
|
| + return counts;
|
| +}
|
|
|
| - for (size_t i = 0; i < kScaleReasonSize; ++i) {
|
| - LOG(LS_INFO) << "Scaled " << scale_counters[i]
|
| - << " times for reason: " << (i ? "cpu" : "quality");
|
| - }
|
| +ViEEncoder::AdaptCounter& ViEEncoder::GetAdaptCounter() {
|
| + return adapt_counters_[degradation_preference_];
|
| }
|
|
|
| -const std::vector<int>& ViEEncoder::GetScaleCounters() {
|
| - auto it = scale_counters_.find(degradation_preference_);
|
| - if (it == scale_counters_.end()) {
|
| - scale_counters_[degradation_preference_].resize(kScaleReasonSize);
|
| - return scale_counters_[degradation_preference_];
|
| - }
|
| - return it->second;
|
| +const ViEEncoder::AdaptCounter& ViEEncoder::GetConstAdaptCounter() {
|
| + return adapt_counters_[degradation_preference_];
|
| +}
|
| +
|
| +// Class holding adaptation information.
|
| +ViEEncoder::AdaptCounter::AdaptCounter() {
|
| + fps_counters_.resize(kScaleReasonSize);
|
| + resolution_counters_.resize(kScaleReasonSize);
|
| +}
|
| +
|
| +ViEEncoder::AdaptCounter::~AdaptCounter() {}
|
| +
|
| +std::string ViEEncoder::AdaptCounter::ToString() const {
|
| + std::stringstream ss;
|
| + ss << "Downgrade counts: fps: {" << ToString(fps_counters_);
|
| + ss << "}, resolution: {" << ToString(resolution_counters_) << "}";
|
| + return ss.str();
|
| +}
|
| +
|
| +ViEEncoder::AdaptCounts ViEEncoder::AdaptCounter::Counts(int reason) const {
|
| + AdaptCounts counts;
|
| + counts.fps = fps_counters_[reason];
|
| + counts.resolution = resolution_counters_[reason];
|
| + return counts;
|
| +}
|
| +
|
| +void ViEEncoder::AdaptCounter::IncrementFramerate(int reason, int delta) {
|
| + fps_counters_[reason] += delta;
|
| +}
|
| +
|
| +void ViEEncoder::AdaptCounter::IncrementResolution(int reason, int delta) {
|
| + resolution_counters_[reason] += delta;
|
| +}
|
| +
|
| +int ViEEncoder::AdaptCounter::FramerateCount() const {
|
| + return Count(fps_counters_);
|
| +}
|
| +
|
| +int ViEEncoder::AdaptCounter::ResolutionCount() const {
|
| + return Count(resolution_counters_);
|
| +}
|
| +
|
| +int ViEEncoder::AdaptCounter::TotalCount() const {
|
| + return FramerateCount() + ResolutionCount();
|
| +}
|
| +
|
| +int ViEEncoder::AdaptCounter::FramerateCount(int reason) const {
|
| + return fps_counters_[reason];
|
| +}
|
| +
|
| +int ViEEncoder::AdaptCounter::ResolutionCount(int reason) const {
|
| + return resolution_counters_[reason];
|
| +}
|
| +
|
| +int ViEEncoder::AdaptCounter::TotalCount(int reason) const {
|
| + return FramerateCount(reason) + ResolutionCount(reason);
|
| +}
|
| +
|
| +int ViEEncoder::AdaptCounter::Count(const std::vector<int>& counters) const {
|
| + return std::accumulate(counters.begin(), counters.end(), 0);
|
| }
|
|
|
| -void ViEEncoder::IncrementScaleCounter(int reason, int delta) {
|
| - // Get the counters and validate. This may also lazily initialize the state.
|
| - const std::vector<int>& counter = GetScaleCounters();
|
| - if (delta < 0) {
|
| - RTC_DCHECK_GE(counter[reason], delta);
|
| +std::string ViEEncoder::AdaptCounter::ToString(
|
| + const std::vector<int>& counters) const {
|
| + std::stringstream ss;
|
| + for (size_t reason = 0; reason < kScaleReasonSize; ++reason) {
|
| + ss << (reason ? " cpu" : "quality") << ":" << counters[reason];
|
| }
|
| - scale_counters_[degradation_preference_][reason] += delta;
|
| + return ss.str();
|
| }
|
|
|
| } // namespace webrtc
|
|
|