1 /* 2 * Copyright 2020 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "video/adaptation/quality_scaler_resource.h" 12 13 #include <utility> 14 15 #include "rtc_base/checks.h" 16 #include "rtc_base/experiments/balanced_degradation_settings.h" 17 #include "rtc_base/ref_counted_object.h" 18 #include "rtc_base/task_utils/to_queued_task.h" 19 #include "rtc_base/time_utils.h" 20 21 namespace webrtc { 22 23 // static Create()24rtc::scoped_refptr<QualityScalerResource> QualityScalerResource::Create() { 25 return new rtc::RefCountedObject<QualityScalerResource>(); 26 } 27 QualityScalerResource()28QualityScalerResource::QualityScalerResource() 29 : VideoStreamEncoderResource("QualityScalerResource"), 30 quality_scaler_(nullptr) {} 31 ~QualityScalerResource()32QualityScalerResource::~QualityScalerResource() { 33 RTC_DCHECK(!quality_scaler_); 34 } 35 is_started() const36bool QualityScalerResource::is_started() const { 37 RTC_DCHECK_RUN_ON(encoder_queue()); 38 return quality_scaler_.get(); 39 } 40 StartCheckForOveruse(VideoEncoder::QpThresholds qp_thresholds)41void QualityScalerResource::StartCheckForOveruse( 42 VideoEncoder::QpThresholds qp_thresholds) { 43 RTC_DCHECK_RUN_ON(encoder_queue()); 44 RTC_DCHECK(!is_started()); 45 quality_scaler_ = 46 std::make_unique<QualityScaler>(this, std::move(qp_thresholds)); 47 } 48 StopCheckForOveruse()49void QualityScalerResource::StopCheckForOveruse() { 50 RTC_DCHECK_RUN_ON(encoder_queue()); 51 RTC_DCHECK(is_started()); 52 // Ensure we have no pending callbacks. This makes it safe to destroy the 53 // QualityScaler and even task queues with tasks in-flight. 54 quality_scaler_.reset(); 55 } 56 SetQpThresholds(VideoEncoder::QpThresholds qp_thresholds)57void QualityScalerResource::SetQpThresholds( 58 VideoEncoder::QpThresholds qp_thresholds) { 59 RTC_DCHECK_RUN_ON(encoder_queue()); 60 RTC_DCHECK(is_started()); 61 quality_scaler_->SetQpThresholds(std::move(qp_thresholds)); 62 } 63 QpFastFilterLow()64bool QualityScalerResource::QpFastFilterLow() { 65 RTC_DCHECK_RUN_ON(encoder_queue()); 66 RTC_DCHECK(is_started()); 67 return quality_scaler_->QpFastFilterLow(); 68 } 69 OnEncodeCompleted(const EncodedImage & encoded_image,int64_t time_sent_in_us)70void QualityScalerResource::OnEncodeCompleted(const EncodedImage& encoded_image, 71 int64_t time_sent_in_us) { 72 RTC_DCHECK_RUN_ON(encoder_queue()); 73 if (quality_scaler_ && encoded_image.qp_ >= 0) { 74 quality_scaler_->ReportQp(encoded_image.qp_, time_sent_in_us); 75 } 76 } 77 OnFrameDropped(EncodedImageCallback::DropReason reason)78void QualityScalerResource::OnFrameDropped( 79 EncodedImageCallback::DropReason reason) { 80 RTC_DCHECK_RUN_ON(encoder_queue()); 81 if (!quality_scaler_) 82 return; 83 switch (reason) { 84 case EncodedImageCallback::DropReason::kDroppedByMediaOptimizations: 85 quality_scaler_->ReportDroppedFrameByMediaOpt(); 86 break; 87 case EncodedImageCallback::DropReason::kDroppedByEncoder: 88 quality_scaler_->ReportDroppedFrameByEncoder(); 89 break; 90 } 91 } 92 OnReportQpUsageHigh()93void QualityScalerResource::OnReportQpUsageHigh() { 94 OnResourceUsageStateMeasured(ResourceUsageState::kOveruse); 95 } 96 OnReportQpUsageLow()97void QualityScalerResource::OnReportQpUsageLow() { 98 OnResourceUsageStateMeasured(ResourceUsageState::kUnderuse); 99 } 100 101 } // namespace webrtc 102