Files
platform-external-webrtc/video/adaptation/encode_usage_resource.cc
Henrik Boström 5cc28b0c6a [Adaptation] Prep Resource for api/ move. Introduce VSE-Resource.
This CL is in preparation for moving Resource to the api/ folder. It
does not move it, but makes it such that the moving CL can be a pure
move.

In order to do this, we must stop depending on rtc_base/rtc::TaskQueue
in favor of api/webrtc::TaskQueueBase.

There are also other rtc_base/ dependencies that we do not want to
expose to the api/ folder, like critical sections and thread
annotations which are not publically exposed. To get around this, we
make Resource an abstract interface and move all of the base class
functionality into a new non-api/ class: VideoStreamEncoderResource.

The Resource now has Register/UnregisterAdaptationTaskQueue() methods.
By explicitly unregistering, we can ensure validity of the pointer even
if the Resource outlives the PeerConnection. While public interface
methods are only to be called on the adaptation task queue, posting to
the task queue happens off-queue, so a |lock_| is introduced to guard
it.

Bug: webrtc:11525
Change-Id: I50b3a30960cdec9032016c779b47001c01dad32f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176320
Reviewed-by: Evan Shrubsole <eshr@google.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31402}
2020-06-02 07:56:38 +00:00

120 lines
4.1 KiB
C++

/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "video/adaptation/encode_usage_resource.h"
#include <limits>
#include <utility>
#include "api/video/video_adaptation_reason.h"
#include "rtc_base/checks.h"
#include "rtc_base/ref_counted_object.h"
namespace webrtc {
// static
rtc::scoped_refptr<EncodeUsageResource> EncodeUsageResource::Create(
std::unique_ptr<OveruseFrameDetector> overuse_detector) {
return new rtc::RefCountedObject<EncodeUsageResource>(
std::move(overuse_detector));
}
EncodeUsageResource::EncodeUsageResource(
std::unique_ptr<OveruseFrameDetector> overuse_detector)
: VideoStreamEncoderResource("EncoderUsageResource"),
overuse_detector_(std::move(overuse_detector)),
is_started_(false),
target_frame_rate_(absl::nullopt) {
RTC_DCHECK(overuse_detector_);
}
EncodeUsageResource::~EncodeUsageResource() {}
bool EncodeUsageResource::is_started() const {
RTC_DCHECK_RUN_ON(encoder_queue());
return is_started_;
}
void EncodeUsageResource::StartCheckForOveruse(CpuOveruseOptions options) {
RTC_DCHECK_RUN_ON(encoder_queue());
RTC_DCHECK(!is_started_);
overuse_detector_->StartCheckForOveruse(TaskQueueBase::Current(),
std::move(options), this);
is_started_ = true;
overuse_detector_->OnTargetFramerateUpdated(TargetFrameRateAsInt());
}
void EncodeUsageResource::StopCheckForOveruse() {
RTC_DCHECK_RUN_ON(encoder_queue());
overuse_detector_->StopCheckForOveruse();
is_started_ = false;
}
void EncodeUsageResource::SetTargetFrameRate(
absl::optional<double> target_frame_rate) {
RTC_DCHECK_RUN_ON(encoder_queue());
if (target_frame_rate == target_frame_rate_)
return;
target_frame_rate_ = target_frame_rate;
if (is_started_)
overuse_detector_->OnTargetFramerateUpdated(TargetFrameRateAsInt());
}
void EncodeUsageResource::OnEncodeStarted(const VideoFrame& cropped_frame,
int64_t time_when_first_seen_us) {
RTC_DCHECK_RUN_ON(encoder_queue());
// TODO(hbos): Rename FrameCaptured() to something more appropriate (e.g.
// "OnEncodeStarted"?) or revise usage.
overuse_detector_->FrameCaptured(cropped_frame, time_when_first_seen_us);
}
void EncodeUsageResource::OnEncodeCompleted(
uint32_t timestamp,
int64_t time_sent_in_us,
int64_t capture_time_us,
absl::optional<int> encode_duration_us) {
RTC_DCHECK_RUN_ON(encoder_queue());
// TODO(hbos): Rename FrameSent() to something more appropriate (e.g.
// "OnEncodeCompleted"?).
overuse_detector_->FrameSent(timestamp, time_sent_in_us, capture_time_us,
encode_duration_us);
}
void EncodeUsageResource::AdaptUp() {
RTC_DCHECK_RUN_ON(encoder_queue());
// Reference counting guarantees that this object is still alive by the time
// the task is executed.
MaybePostTaskToResourceAdaptationQueue(
[this_ref = rtc::scoped_refptr<EncodeUsageResource>(this)] {
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
this_ref->OnResourceUsageStateMeasured(ResourceUsageState::kUnderuse);
});
}
void EncodeUsageResource::AdaptDown() {
RTC_DCHECK_RUN_ON(encoder_queue());
// Reference counting guarantees that this object is still alive by the time
// the task is executed.
MaybePostTaskToResourceAdaptationQueue(
[this_ref = rtc::scoped_refptr<EncodeUsageResource>(this)] {
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
this_ref->OnResourceUsageStateMeasured(ResourceUsageState::kOveruse);
});
}
int EncodeUsageResource::TargetFrameRateAsInt() {
RTC_DCHECK_RUN_ON(encoder_queue());
return target_frame_rate_.has_value()
? static_cast<int>(target_frame_rate_.value())
: std::numeric_limits<int>::max();
}
} // namespace webrtc