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/encode_usage_resource.h"
12
13 #include <limits>
14 #include <utility>
15
16 #include "api/video/video_adaptation_reason.h"
17 #include "rtc_base/checks.h"
18 #include "rtc_base/ref_counted_object.h"
19
20 namespace webrtc {
21
22 // static
Create(std::unique_ptr<OveruseFrameDetector> overuse_detector)23 rtc::scoped_refptr<EncodeUsageResource> EncodeUsageResource::Create(
24 std::unique_ptr<OveruseFrameDetector> overuse_detector) {
25 return new rtc::RefCountedObject<EncodeUsageResource>(
26 std::move(overuse_detector));
27 }
28
EncodeUsageResource(std::unique_ptr<OveruseFrameDetector> overuse_detector)29 EncodeUsageResource::EncodeUsageResource(
30 std::unique_ptr<OveruseFrameDetector> overuse_detector)
31 : VideoStreamEncoderResource("EncoderUsageResource"),
32 overuse_detector_(std::move(overuse_detector)),
33 is_started_(false),
34 target_frame_rate_(absl::nullopt) {
35 RTC_DCHECK(overuse_detector_);
36 }
37
~EncodeUsageResource()38 EncodeUsageResource::~EncodeUsageResource() {}
39
is_started() const40 bool EncodeUsageResource::is_started() const {
41 RTC_DCHECK_RUN_ON(encoder_queue());
42 return is_started_;
43 }
44
StartCheckForOveruse(CpuOveruseOptions options)45 void EncodeUsageResource::StartCheckForOveruse(CpuOveruseOptions options) {
46 RTC_DCHECK_RUN_ON(encoder_queue());
47 RTC_DCHECK(!is_started_);
48 overuse_detector_->StartCheckForOveruse(TaskQueueBase::Current(),
49 std::move(options), this);
50 is_started_ = true;
51 overuse_detector_->OnTargetFramerateUpdated(TargetFrameRateAsInt());
52 }
53
StopCheckForOveruse()54 void EncodeUsageResource::StopCheckForOveruse() {
55 RTC_DCHECK_RUN_ON(encoder_queue());
56 overuse_detector_->StopCheckForOveruse();
57 is_started_ = false;
58 }
59
SetTargetFrameRate(absl::optional<double> target_frame_rate)60 void EncodeUsageResource::SetTargetFrameRate(
61 absl::optional<double> target_frame_rate) {
62 RTC_DCHECK_RUN_ON(encoder_queue());
63 if (target_frame_rate == target_frame_rate_)
64 return;
65 target_frame_rate_ = target_frame_rate;
66 if (is_started_)
67 overuse_detector_->OnTargetFramerateUpdated(TargetFrameRateAsInt());
68 }
69
OnEncodeStarted(const VideoFrame & cropped_frame,int64_t time_when_first_seen_us)70 void EncodeUsageResource::OnEncodeStarted(const VideoFrame& cropped_frame,
71 int64_t time_when_first_seen_us) {
72 RTC_DCHECK_RUN_ON(encoder_queue());
73 // TODO(hbos): Rename FrameCaptured() to something more appropriate (e.g.
74 // "OnEncodeStarted"?) or revise usage.
75 overuse_detector_->FrameCaptured(cropped_frame, time_when_first_seen_us);
76 }
77
OnEncodeCompleted(uint32_t timestamp,int64_t time_sent_in_us,int64_t capture_time_us,absl::optional<int> encode_duration_us)78 void EncodeUsageResource::OnEncodeCompleted(
79 uint32_t timestamp,
80 int64_t time_sent_in_us,
81 int64_t capture_time_us,
82 absl::optional<int> encode_duration_us) {
83 RTC_DCHECK_RUN_ON(encoder_queue());
84 // TODO(hbos): Rename FrameSent() to something more appropriate (e.g.
85 // "OnEncodeCompleted"?).
86 overuse_detector_->FrameSent(timestamp, time_sent_in_us, capture_time_us,
87 encode_duration_us);
88 }
89
AdaptUp()90 void EncodeUsageResource::AdaptUp() {
91 RTC_DCHECK_RUN_ON(encoder_queue());
92 // Reference counting guarantees that this object is still alive by the time
93 // the task is executed.
94 MaybePostTaskToResourceAdaptationQueue(
95 [this_ref = rtc::scoped_refptr<EncodeUsageResource>(this)] {
96 RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
97 this_ref->OnResourceUsageStateMeasured(ResourceUsageState::kUnderuse);
98 });
99 }
100
AdaptDown()101 void EncodeUsageResource::AdaptDown() {
102 RTC_DCHECK_RUN_ON(encoder_queue());
103 // Reference counting guarantees that this object is still alive by the time
104 // the task is executed.
105 MaybePostTaskToResourceAdaptationQueue(
106 [this_ref = rtc::scoped_refptr<EncodeUsageResource>(this)] {
107 RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
108 this_ref->OnResourceUsageStateMeasured(ResourceUsageState::kOveruse);
109 });
110 }
111
TargetFrameRateAsInt()112 int EncodeUsageResource::TargetFrameRateAsInt() {
113 RTC_DCHECK_RUN_ON(encoder_queue());
114 return target_frame_rate_.has_value()
115 ? static_cast<int>(target_frame_rate_.value())
116 : std::numeric_limits<int>::max();
117 }
118
119 } // namespace webrtc
120