mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00
[Adaptation] Remove resource adaptation queue
Resource adaptation needs refactoring for async adaptations. For now the resource adaptation processor can work on the encoder thread, until it is refactored to support async adaptation. Bug: webrtc:11867 Change-Id: I9c46da356db19c0fd52748c999ccb216f2ca923b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/182040 Commit-Queue: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31991}
This commit is contained in:
parent
90caa4356b
commit
8572841131
15 changed files with 169 additions and 298 deletions
|
@ -14,7 +14,6 @@
|
|||
#include <string>
|
||||
|
||||
#include "api/adaptation/resource.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "call/adaptation/video_source_restrictions.h"
|
||||
#include "call/adaptation/video_stream_input_state.h"
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
namespace webrtc {
|
||||
|
||||
// Thread-safe retrieval of degradation preferences.
|
||||
class DegradationPreferenceProvider {
|
||||
public:
|
||||
virtual ~DegradationPreferenceProvider();
|
||||
|
|
|
@ -27,34 +27,34 @@ namespace webrtc {
|
|||
|
||||
ResourceAdaptationProcessor::ResourceListenerDelegate::ResourceListenerDelegate(
|
||||
ResourceAdaptationProcessor* processor)
|
||||
: resource_adaptation_queue_(nullptr), processor_(processor) {}
|
||||
: task_queue_(nullptr), processor_(processor) {}
|
||||
|
||||
void ResourceAdaptationProcessor::ResourceListenerDelegate::
|
||||
SetResourceAdaptationQueue(TaskQueueBase* resource_adaptation_queue) {
|
||||
RTC_DCHECK(!resource_adaptation_queue_);
|
||||
RTC_DCHECK(resource_adaptation_queue);
|
||||
resource_adaptation_queue_ = resource_adaptation_queue;
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
void ResourceAdaptationProcessor::ResourceListenerDelegate::SetTaskQueue(
|
||||
TaskQueueBase* task_queue) {
|
||||
RTC_DCHECK(!task_queue_);
|
||||
RTC_DCHECK(task_queue);
|
||||
task_queue_ = task_queue;
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
}
|
||||
|
||||
void ResourceAdaptationProcessor::ResourceListenerDelegate::
|
||||
OnProcessorDestroyed() {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
processor_ = nullptr;
|
||||
}
|
||||
|
||||
void ResourceAdaptationProcessor::ResourceListenerDelegate::
|
||||
OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource,
|
||||
ResourceUsageState usage_state) {
|
||||
if (!resource_adaptation_queue_->IsCurrent()) {
|
||||
resource_adaptation_queue_->PostTask(ToQueuedTask(
|
||||
if (!task_queue_->IsCurrent()) {
|
||||
task_queue_->PostTask(ToQueuedTask(
|
||||
[this_ref = rtc::scoped_refptr<ResourceListenerDelegate>(this),
|
||||
resource, usage_state] {
|
||||
this_ref->OnResourceUsageStateMeasured(resource, usage_state);
|
||||
}));
|
||||
return;
|
||||
}
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
if (processor_) {
|
||||
processor_->OnResourceUsageStateMeasured(resource, usage_state);
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ ResourceAdaptationProcessor::MitigationResultAndLogMessage::
|
|||
|
||||
ResourceAdaptationProcessor::ResourceAdaptationProcessor(
|
||||
VideoStreamAdapter* stream_adapter)
|
||||
: resource_adaptation_queue_(nullptr),
|
||||
: task_queue_(nullptr),
|
||||
resource_listener_delegate_(
|
||||
new rtc::RefCountedObject<ResourceListenerDelegate>(this)),
|
||||
resources_(),
|
||||
|
@ -81,7 +81,7 @@ ResourceAdaptationProcessor::ResourceAdaptationProcessor(
|
|||
}
|
||||
|
||||
ResourceAdaptationProcessor::~ResourceAdaptationProcessor() {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
RTC_DCHECK(resources_.empty())
|
||||
<< "There are resource(s) attached to a ResourceAdaptationProcessor "
|
||||
<< "being destroyed.";
|
||||
|
@ -89,30 +89,29 @@ ResourceAdaptationProcessor::~ResourceAdaptationProcessor() {
|
|||
resource_listener_delegate_->OnProcessorDestroyed();
|
||||
}
|
||||
|
||||
void ResourceAdaptationProcessor::SetResourceAdaptationQueue(
|
||||
TaskQueueBase* resource_adaptation_queue) {
|
||||
RTC_DCHECK(!resource_adaptation_queue_);
|
||||
RTC_DCHECK(resource_adaptation_queue);
|
||||
resource_adaptation_queue_ = resource_adaptation_queue;
|
||||
resource_listener_delegate_->SetResourceAdaptationQueue(
|
||||
resource_adaptation_queue);
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
// Now that we have the adaptation queue we can attach as adaptation listener.
|
||||
void ResourceAdaptationProcessor::SetTaskQueue(TaskQueueBase* task_queue) {
|
||||
RTC_DCHECK(!task_queue_);
|
||||
RTC_DCHECK(task_queue);
|
||||
task_queue_ = task_queue;
|
||||
resource_listener_delegate_->SetTaskQueue(task_queue);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
// Now that we have the queue we can attach as adaptation listener.
|
||||
stream_adapter_->AddRestrictionsListener(this);
|
||||
}
|
||||
|
||||
void ResourceAdaptationProcessor::AddResourceLimitationsListener(
|
||||
ResourceLimitationsListener* limitations_listener) {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
RTC_DCHECK(std::find(resource_limitations_listeners_.begin(),
|
||||
resource_limitations_listeners_.end(),
|
||||
limitations_listener) ==
|
||||
resource_limitations_listeners_.end());
|
||||
resource_limitations_listeners_.push_back(limitations_listener);
|
||||
}
|
||||
|
||||
void ResourceAdaptationProcessor::RemoveResourceLimitationsListener(
|
||||
ResourceLimitationsListener* limitations_listener) {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
auto it =
|
||||
std::find(resource_limitations_listeners_.begin(),
|
||||
resource_limitations_listeners_.end(), limitations_listener);
|
||||
|
@ -155,12 +154,12 @@ void ResourceAdaptationProcessor::RemoveResource(
|
|||
|
||||
void ResourceAdaptationProcessor::RemoveLimitationsImposedByResource(
|
||||
rtc::scoped_refptr<Resource> resource) {
|
||||
if (!resource_adaptation_queue_->IsCurrent()) {
|
||||
resource_adaptation_queue_->PostTask(ToQueuedTask(
|
||||
if (!task_queue_->IsCurrent()) {
|
||||
task_queue_->PostTask(ToQueuedTask(
|
||||
[this, resource]() { RemoveLimitationsImposedByResource(resource); }));
|
||||
return;
|
||||
}
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
auto resource_adaptation_limits =
|
||||
adaptation_limits_by_resources_.find(resource);
|
||||
if (resource_adaptation_limits != adaptation_limits_by_resources_.end()) {
|
||||
|
@ -198,7 +197,7 @@ void ResourceAdaptationProcessor::RemoveLimitationsImposedByResource(
|
|||
void ResourceAdaptationProcessor::OnResourceUsageStateMeasured(
|
||||
rtc::scoped_refptr<Resource> resource,
|
||||
ResourceUsageState usage_state) {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
RTC_DCHECK(resource);
|
||||
// |resource| could have been removed after signalling.
|
||||
{
|
||||
|
@ -240,7 +239,7 @@ void ResourceAdaptationProcessor::OnResourceUsageStateMeasured(
|
|||
ResourceAdaptationProcessor::MitigationResultAndLogMessage
|
||||
ResourceAdaptationProcessor::OnResourceUnderuse(
|
||||
rtc::scoped_refptr<Resource> reason_resource) {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
// How can this stream be adapted up?
|
||||
Adaptation adaptation = stream_adapter_->GetAdaptationUp();
|
||||
if (adaptation.status() != Adaptation::Status::kValid) {
|
||||
|
@ -296,7 +295,7 @@ ResourceAdaptationProcessor::OnResourceUnderuse(
|
|||
ResourceAdaptationProcessor::MitigationResultAndLogMessage
|
||||
ResourceAdaptationProcessor::OnResourceOveruse(
|
||||
rtc::scoped_refptr<Resource> reason_resource) {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
// How can this stream be adapted up?
|
||||
Adaptation adaptation = stream_adapter_->GetAdaptationDown();
|
||||
if (adaptation.status() == Adaptation::Status::kLimitReached) {
|
||||
|
@ -375,7 +374,7 @@ void ResourceAdaptationProcessor::OnVideoSourceRestrictionsUpdated(
|
|||
const VideoAdaptationCounters& adaptation_counters,
|
||||
rtc::scoped_refptr<Resource> reason,
|
||||
const VideoSourceRestrictions& unfiltered_restrictions) {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
if (reason) {
|
||||
UpdateResourceLimitations(reason, unfiltered_restrictions,
|
||||
adaptation_counters);
|
||||
|
|
|
@ -58,8 +58,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
|||
VideoStreamAdapter* video_stream_adapter);
|
||||
~ResourceAdaptationProcessor() override;
|
||||
|
||||
void SetResourceAdaptationQueue(
|
||||
TaskQueueBase* resource_adaptation_queue) override;
|
||||
void SetTaskQueue(TaskQueueBase* task_queue) override;
|
||||
|
||||
// ResourceAdaptationProcessorInterface implementation.
|
||||
void AddResourceLimitationsListener(
|
||||
|
@ -91,7 +90,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
|||
public:
|
||||
explicit ResourceListenerDelegate(ResourceAdaptationProcessor* processor);
|
||||
|
||||
void SetResourceAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
|
||||
void SetTaskQueue(TaskQueueBase* task_queue);
|
||||
void OnProcessorDestroyed();
|
||||
|
||||
// ResourceListener implementation.
|
||||
|
@ -99,9 +98,8 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
|||
ResourceUsageState usage_state) override;
|
||||
|
||||
private:
|
||||
TaskQueueBase* resource_adaptation_queue_;
|
||||
ResourceAdaptationProcessor* processor_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
TaskQueueBase* task_queue_;
|
||||
ResourceAdaptationProcessor* processor_ RTC_GUARDED_BY(task_queue_);
|
||||
};
|
||||
|
||||
enum class MitigationResult {
|
||||
|
@ -129,7 +127,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
|||
void UpdateResourceLimitations(rtc::scoped_refptr<Resource> reason_resource,
|
||||
const VideoSourceRestrictions& restrictions,
|
||||
const VideoAdaptationCounters& counters)
|
||||
RTC_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_RUN_ON(task_queue_);
|
||||
|
||||
// Searches |adaptation_limits_by_resources_| for each resource with the
|
||||
// highest total adaptation counts. Adaptation up may only occur if the
|
||||
|
@ -138,33 +136,31 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
|||
// corresponding adaptation of that resource.
|
||||
std::pair<std::vector<rtc::scoped_refptr<Resource>>,
|
||||
VideoStreamAdapter::RestrictionsWithCounters>
|
||||
FindMostLimitedResources() const RTC_RUN_ON(resource_adaptation_queue_);
|
||||
FindMostLimitedResources() const RTC_RUN_ON(task_queue_);
|
||||
|
||||
void RemoveLimitationsImposedByResource(
|
||||
rtc::scoped_refptr<Resource> resource);
|
||||
|
||||
TaskQueueBase* resource_adaptation_queue_;
|
||||
TaskQueueBase* task_queue_;
|
||||
rtc::scoped_refptr<ResourceListenerDelegate> resource_listener_delegate_;
|
||||
// Input and output.
|
||||
mutable Mutex resources_lock_;
|
||||
std::vector<rtc::scoped_refptr<Resource>> resources_
|
||||
RTC_GUARDED_BY(resources_lock_);
|
||||
std::vector<ResourceLimitationsListener*> resource_limitations_listeners_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
RTC_GUARDED_BY(task_queue_);
|
||||
// Purely used for statistics, does not ensure mapped resources stay alive.
|
||||
std::map<rtc::scoped_refptr<Resource>,
|
||||
VideoStreamAdapter::RestrictionsWithCounters>
|
||||
adaptation_limits_by_resources_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
adaptation_limits_by_resources_ RTC_GUARDED_BY(task_queue_);
|
||||
// Responsible for generating and applying possible adaptations.
|
||||
VideoStreamAdapter* const stream_adapter_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
VideoStreamAdapter* const stream_adapter_ RTC_GUARDED_BY(task_queue_);
|
||||
VideoSourceRestrictions last_reported_source_restrictions_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
RTC_GUARDED_BY(task_queue_);
|
||||
// Keeps track of previous mitigation results per resource since the last
|
||||
// successful adaptation. Used to avoid RTC_LOG spam.
|
||||
std::map<Resource*, MitigationResult> previous_mitigation_results_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
RTC_GUARDED_BY(task_queue_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -47,8 +47,7 @@ class ResourceAdaptationProcessorInterface {
|
|||
public:
|
||||
virtual ~ResourceAdaptationProcessorInterface();
|
||||
|
||||
virtual void SetResourceAdaptationQueue(
|
||||
TaskQueueBase* resource_adaptation_queue) = 0;
|
||||
virtual void SetTaskQueue(TaskQueueBase* task_queue) = 0;
|
||||
|
||||
virtual void AddResourceLimitationsListener(
|
||||
ResourceLimitationsListener* limitations_listener) = 0;
|
||||
|
|
|
@ -93,7 +93,7 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
|
|||
&frame_rate_provider_)),
|
||||
processor_(std::make_unique<ResourceAdaptationProcessor>(
|
||||
video_stream_adapter_.get())) {
|
||||
processor_->SetResourceAdaptationQueue(TaskQueueBase::Current());
|
||||
processor_->SetTaskQueue(TaskQueueBase::Current());
|
||||
video_stream_adapter_->AddRestrictionsListener(&restrictions_listener_);
|
||||
processor_->AddResource(resource_);
|
||||
processor_->AddResource(other_resource_);
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
*/
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "rtc_base/synchronization/sequence_checker.h"
|
||||
#include "rtc_base/task_utils/to_queued_task.h"
|
||||
#include "video/adaptation/balanced_constraint.h"
|
||||
|
||||
|
@ -17,32 +19,23 @@ namespace webrtc {
|
|||
|
||||
BalancedConstraint::BalancedConstraint(
|
||||
DegradationPreferenceProvider* degradation_preference_provider)
|
||||
: resource_adaptation_queue_(nullptr),
|
||||
encoder_target_bitrate_bps_(absl::nullopt),
|
||||
: encoder_target_bitrate_bps_(absl::nullopt),
|
||||
degradation_preference_provider_(degradation_preference_provider) {
|
||||
RTC_DCHECK(degradation_preference_provider_);
|
||||
}
|
||||
|
||||
void BalancedConstraint::SetAdaptationQueue(
|
||||
TaskQueueBase* resource_adaptation_queue) {
|
||||
resource_adaptation_queue_ = resource_adaptation_queue;
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void BalancedConstraint::OnEncoderTargetBitrateUpdated(
|
||||
absl::optional<uint32_t> encoder_target_bitrate_bps) {
|
||||
resource_adaptation_queue_->PostTask(
|
||||
ToQueuedTask([this_ref = rtc::scoped_refptr<BalancedConstraint>(this),
|
||||
encoder_target_bitrate_bps] {
|
||||
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
|
||||
this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
|
||||
}));
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps);
|
||||
}
|
||||
|
||||
bool BalancedConstraint::IsAdaptationUpAllowed(
|
||||
const VideoStreamInputState& input_state,
|
||||
const VideoSourceRestrictions& restrictions_before,
|
||||
const VideoSourceRestrictions& restrictions_after) const {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
// Don't adapt if BalancedDegradationSettings applies and determines this will
|
||||
// exceed bitrate constraints.
|
||||
if (degradation_preference_provider_->degradation_preference() ==
|
||||
|
|
|
@ -14,21 +14,19 @@
|
|||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/task_queue/task_queue_base.h"
|
||||
#include "call/adaptation/adaptation_constraint.h"
|
||||
#include "call/adaptation/degradation_preference_provider.h"
|
||||
#include "rtc_base/experiments/balanced_degradation_settings.h"
|
||||
#include "rtc_base/synchronization/sequence_checker.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class BalancedConstraint : public rtc::RefCountInterface,
|
||||
public AdaptationConstraint {
|
||||
class BalancedConstraint : public AdaptationConstraint {
|
||||
public:
|
||||
explicit BalancedConstraint(
|
||||
DegradationPreferenceProvider* degradation_preference_provider);
|
||||
~BalancedConstraint() override = default;
|
||||
|
||||
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
|
||||
void OnEncoderTargetBitrateUpdated(
|
||||
absl::optional<uint32_t> encoder_target_bitrate_bps);
|
||||
|
||||
|
@ -40,11 +38,11 @@ class BalancedConstraint : public rtc::RefCountInterface,
|
|||
const VideoSourceRestrictions& restrictions_after) const override;
|
||||
|
||||
private:
|
||||
TaskQueueBase* resource_adaptation_queue_;
|
||||
SequenceChecker sequence_checker_;
|
||||
absl::optional<uint32_t> encoder_target_bitrate_bps_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
BalancedDegradationSettings balanced_settings_;
|
||||
DegradationPreferenceProvider* degradation_preference_provider_;
|
||||
RTC_GUARDED_BY(&sequence_checker_);
|
||||
const BalancedDegradationSettings balanced_settings_;
|
||||
const DegradationPreferenceProvider* degradation_preference_provider_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -12,46 +12,34 @@
|
|||
#include <utility>
|
||||
|
||||
#include "call/adaptation/video_stream_adapter.h"
|
||||
#include "rtc_base/task_utils/to_queued_task.h"
|
||||
#include "rtc_base/synchronization/sequence_checker.h"
|
||||
#include "video/adaptation/bitrate_constraint.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
BitrateConstraint::BitrateConstraint()
|
||||
: resource_adaptation_queue_(nullptr),
|
||||
encoder_settings_(absl::nullopt),
|
||||
encoder_target_bitrate_bps_(absl::nullopt) {}
|
||||
|
||||
void BitrateConstraint::SetAdaptationQueue(
|
||||
TaskQueueBase* resource_adaptation_queue) {
|
||||
resource_adaptation_queue_ = resource_adaptation_queue;
|
||||
: encoder_settings_(absl::nullopt),
|
||||
encoder_target_bitrate_bps_(absl::nullopt) {
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void BitrateConstraint::OnEncoderSettingsUpdated(
|
||||
absl::optional<EncoderSettings> encoder_settings) {
|
||||
resource_adaptation_queue_->PostTask(
|
||||
ToQueuedTask([this_ref = rtc::scoped_refptr<BitrateConstraint>(this),
|
||||
encoder_settings] {
|
||||
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
|
||||
this_ref->encoder_settings_ = std::move(encoder_settings);
|
||||
}));
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
encoder_settings_ = std::move(encoder_settings);
|
||||
}
|
||||
|
||||
void BitrateConstraint::OnEncoderTargetBitrateUpdated(
|
||||
absl::optional<uint32_t> encoder_target_bitrate_bps) {
|
||||
resource_adaptation_queue_->PostTask(
|
||||
ToQueuedTask([this_ref = rtc::scoped_refptr<BitrateConstraint>(this),
|
||||
encoder_target_bitrate_bps] {
|
||||
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
|
||||
this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
|
||||
}));
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps);
|
||||
}
|
||||
|
||||
bool BitrateConstraint::IsAdaptationUpAllowed(
|
||||
const VideoStreamInputState& input_state,
|
||||
const VideoSourceRestrictions& restrictions_before,
|
||||
const VideoSourceRestrictions& restrictions_after) const {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
// Make sure bitrate limits are not violated.
|
||||
if (DidIncreaseResolution(restrictions_before, restrictions_after)) {
|
||||
uint32_t bitrate_bps = encoder_target_bitrate_bps_.value_or(0);
|
||||
|
|
|
@ -14,21 +14,19 @@
|
|||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/task_queue/task_queue_base.h"
|
||||
#include "call/adaptation/adaptation_constraint.h"
|
||||
#include "call/adaptation/encoder_settings.h"
|
||||
#include "call/adaptation/video_source_restrictions.h"
|
||||
#include "call/adaptation/video_stream_input_state.h"
|
||||
#include "rtc_base/synchronization/sequence_checker.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class BitrateConstraint : public rtc::RefCountInterface,
|
||||
public AdaptationConstraint {
|
||||
class BitrateConstraint : public AdaptationConstraint {
|
||||
public:
|
||||
BitrateConstraint();
|
||||
~BitrateConstraint() override = default;
|
||||
|
||||
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
|
||||
void OnEncoderSettingsUpdated(
|
||||
absl::optional<EncoderSettings> encoder_settings);
|
||||
void OnEncoderTargetBitrateUpdated(
|
||||
|
@ -42,13 +40,11 @@ class BitrateConstraint : public rtc::RefCountInterface,
|
|||
const VideoSourceRestrictions& restrictions_after) const override;
|
||||
|
||||
private:
|
||||
// The |manager_| must be alive as long as this resource is added to the
|
||||
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
|
||||
TaskQueueBase* resource_adaptation_queue_;
|
||||
SequenceChecker sequence_checker_;
|
||||
absl::optional<EncoderSettings> encoder_settings_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
RTC_GUARDED_BY(&sequence_checker_);
|
||||
absl::optional<uint32_t> encoder_target_bitrate_bps_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
RTC_GUARDED_BY(&sequence_checker_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
#include "rtc_base/ref_counted_object.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
#include "rtc_base/synchronization/sequence_checker.h"
|
||||
#include "rtc_base/time_utils.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
@ -136,15 +137,14 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager(
|
|||
std::unique_ptr<OveruseFrameDetector> overuse_detector,
|
||||
DegradationPreferenceProvider* degradation_preference_provider)
|
||||
: degradation_preference_provider_(degradation_preference_provider),
|
||||
bitrate_constraint_(new rtc::RefCountedObject<BitrateConstraint>()),
|
||||
balanced_constraint_(new rtc::RefCountedObject<BalancedConstraint>(
|
||||
bitrate_constraint_(std::make_unique<BitrateConstraint>()),
|
||||
balanced_constraint_(std::make_unique<BalancedConstraint>(
|
||||
degradation_preference_provider_)),
|
||||
encode_usage_resource_(
|
||||
EncodeUsageResource::Create(std::move(overuse_detector))),
|
||||
quality_scaler_resource_(
|
||||
QualityScalerResource::Create(degradation_preference_provider_)),
|
||||
encoder_queue_(nullptr),
|
||||
resource_adaptation_queue_(nullptr),
|
||||
input_state_provider_(input_state_provider),
|
||||
adaptation_processor_(nullptr),
|
||||
encoder_stats_observer_(encoder_stats_observer),
|
||||
|
@ -158,27 +158,20 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager(
|
|||
encoder_target_bitrate_bps_(absl::nullopt),
|
||||
quality_rampup_experiment_(
|
||||
QualityRampUpExperimentHelper::CreateIfEnabled(this, clock_)),
|
||||
encoder_settings_(absl::nullopt) {
|
||||
encoder_settings_(absl::nullopt),
|
||||
resources_{{encode_usage_resource_, VideoAdaptationReason::kCpu},
|
||||
{quality_scaler_resource_, VideoAdaptationReason::kQuality}} {
|
||||
RTC_CHECK(degradation_preference_provider_);
|
||||
RTC_CHECK(encoder_stats_observer_);
|
||||
MapResourceToReason(encode_usage_resource_, VideoAdaptationReason::kCpu);
|
||||
MapResourceToReason(quality_scaler_resource_,
|
||||
VideoAdaptationReason::kQuality);
|
||||
}
|
||||
|
||||
VideoStreamEncoderResourceManager::~VideoStreamEncoderResourceManager() {}
|
||||
|
||||
void VideoStreamEncoderResourceManager::Initialize(
|
||||
rtc::TaskQueue* encoder_queue,
|
||||
rtc::TaskQueue* resource_adaptation_queue) {
|
||||
rtc::TaskQueue* encoder_queue) {
|
||||
RTC_DCHECK(!encoder_queue_);
|
||||
RTC_DCHECK(encoder_queue);
|
||||
RTC_DCHECK(!resource_adaptation_queue_);
|
||||
RTC_DCHECK(resource_adaptation_queue);
|
||||
encoder_queue_ = encoder_queue;
|
||||
resource_adaptation_queue_ = resource_adaptation_queue;
|
||||
bitrate_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
|
||||
balanced_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
|
||||
encode_usage_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
|
||||
quality_scaler_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
|
||||
}
|
||||
|
@ -186,7 +179,7 @@ void VideoStreamEncoderResourceManager::Initialize(
|
|||
void VideoStreamEncoderResourceManager::SetAdaptationProcessor(
|
||||
ResourceAdaptationProcessorInterface* adaptation_processor,
|
||||
VideoStreamAdapter* stream_adapter) {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
adaptation_processor_ = adaptation_processor;
|
||||
stream_adapter_ = stream_adapter;
|
||||
}
|
||||
|
@ -222,7 +215,7 @@ void VideoStreamEncoderResourceManager::StopManagedResources() {
|
|||
void VideoStreamEncoderResourceManager::MapResourceToReason(
|
||||
rtc::scoped_refptr<Resource> resource,
|
||||
VideoAdaptationReason reason) {
|
||||
MutexLock lock(&resource_lock_);
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
RTC_DCHECK(resource);
|
||||
RTC_DCHECK(absl::c_find_if(resources_,
|
||||
[resource](const ResourceAndReason& r) {
|
||||
|
@ -234,7 +227,7 @@ void VideoStreamEncoderResourceManager::MapResourceToReason(
|
|||
|
||||
std::vector<rtc::scoped_refptr<Resource>>
|
||||
VideoStreamEncoderResourceManager::MappedResources() const {
|
||||
MutexLock lock(&resource_lock_);
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
std::vector<rtc::scoped_refptr<Resource>> resources;
|
||||
for (auto const& resource_and_reason : resources_) {
|
||||
resources.push_back(resource_and_reason.resource);
|
||||
|
@ -244,12 +237,13 @@ VideoStreamEncoderResourceManager::MappedResources() const {
|
|||
|
||||
std::vector<AdaptationConstraint*>
|
||||
VideoStreamEncoderResourceManager::AdaptationConstraints() const {
|
||||
return {bitrate_constraint_, balanced_constraint_};
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
return {bitrate_constraint_.get(), balanced_constraint_.get()};
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<QualityScalerResource>
|
||||
VideoStreamEncoderResourceManager::quality_scaler_resource_for_testing() {
|
||||
MutexLock lock(&resource_lock_);
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
return quality_scaler_resource_;
|
||||
}
|
||||
|
||||
|
@ -297,24 +291,12 @@ void VideoStreamEncoderResourceManager::SetEncoderRates(
|
|||
|
||||
void VideoStreamEncoderResourceManager::OnFrameDroppedDueToSize() {
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
// The VideoStreamEncoder makes the manager outlive the adaptation queue. This
|
||||
// means that if the task gets executed, |this| has not been freed yet.
|
||||
// TODO(https://crbug.com/webrtc/11565): When the manager no longer outlives
|
||||
// the adaptation queue, add logic to prevent use-after-free on |this|.
|
||||
resource_adaptation_queue_->PostTask([this] {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
if (!adaptation_processor_) {
|
||||
// The processor nulled before this task had a chance to execute. This
|
||||
// happens if the processor is destroyed. No action needed.
|
||||
return;
|
||||
}
|
||||
Adaptation reduce_resolution = stream_adapter_->GetAdaptDownResolution();
|
||||
if (reduce_resolution.status() == Adaptation::Status::kValid) {
|
||||
stream_adapter_->ApplyAdaptation(reduce_resolution,
|
||||
quality_scaler_resource_);
|
||||
}
|
||||
});
|
||||
initial_frame_dropper_->OnFrameDroppedDueToSize();
|
||||
Adaptation reduce_resolution = stream_adapter_->GetAdaptDownResolution();
|
||||
if (reduce_resolution.status() == Adaptation::Status::kValid) {
|
||||
stream_adapter_->ApplyAdaptation(reduce_resolution,
|
||||
quality_scaler_resource_);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoStreamEncoderResourceManager::OnEncodeStarted(
|
||||
|
@ -422,7 +404,7 @@ void VideoStreamEncoderResourceManager::ConfigureQualityScaler(
|
|||
|
||||
VideoAdaptationReason VideoStreamEncoderResourceManager::GetReasonFromResource(
|
||||
rtc::scoped_refptr<Resource> resource) const {
|
||||
MutexLock lock(&resource_lock_);
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
const auto& registered_resource =
|
||||
absl::c_find_if(resources_, [&resource](const ResourceAndReason& r) {
|
||||
return r.resource == resource;
|
||||
|
@ -466,28 +448,23 @@ void VideoStreamEncoderResourceManager::OnVideoSourceRestrictionsUpdated(
|
|||
const VideoAdaptationCounters& adaptation_counters,
|
||||
rtc::scoped_refptr<Resource> reason,
|
||||
const VideoSourceRestrictions& unfiltered_restrictions) {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
// TODO(bugs.webrtc.org/11553) Remove reason parameter and add reset callback.
|
||||
if (!reason && adaptation_counters.Total() == 0) {
|
||||
// Adaptation was manually reset - clear the per-reason counters too.
|
||||
encoder_stats_observer_->ClearAdaptationStats();
|
||||
}
|
||||
|
||||
// The VideoStreamEncoder makes the manager outlive the encoder queue. This
|
||||
// means that if the task gets executed, |this| has not been freed yet.
|
||||
encoder_queue_->PostTask([this, restrictions] {
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
video_source_restrictions_ = FilterRestrictionsByDegradationPreference(
|
||||
restrictions, degradation_preference_);
|
||||
MaybeUpdateTargetFrameRate();
|
||||
});
|
||||
video_source_restrictions_ = FilterRestrictionsByDegradationPreference(
|
||||
restrictions, degradation_preference_);
|
||||
MaybeUpdateTargetFrameRate();
|
||||
}
|
||||
|
||||
void VideoStreamEncoderResourceManager::OnResourceLimitationChanged(
|
||||
rtc::scoped_refptr<Resource> resource,
|
||||
const std::map<rtc::scoped_refptr<Resource>, VideoAdaptationCounters>&
|
||||
resource_limitations) {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
if (!resource) {
|
||||
encoder_stats_observer_->ClearAdaptationStats();
|
||||
return;
|
||||
|
@ -509,19 +486,14 @@ void VideoStreamEncoderResourceManager::OnResourceLimitationChanged(
|
|||
adaptation_reason, limitations[VideoAdaptationReason::kCpu],
|
||||
limitations[VideoAdaptationReason::kQuality]);
|
||||
|
||||
encoder_queue_->PostTask(ToQueuedTask(
|
||||
[cpu_limited = limitations.at(VideoAdaptationReason::kCpu).Total() > 0,
|
||||
qp_resolution_adaptations =
|
||||
limitations.at(VideoAdaptationReason::kQuality)
|
||||
.resolution_adaptations,
|
||||
this]() {
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
if (quality_rampup_experiment_) {
|
||||
quality_rampup_experiment_->cpu_adapted(cpu_limited);
|
||||
quality_rampup_experiment_->qp_resolution_adaptations(
|
||||
qp_resolution_adaptations);
|
||||
}
|
||||
}));
|
||||
if (quality_rampup_experiment_) {
|
||||
bool cpu_limited = limitations.at(VideoAdaptationReason::kCpu).Total() > 0;
|
||||
auto qp_resolution_adaptations =
|
||||
limitations.at(VideoAdaptationReason::kQuality).resolution_adaptations;
|
||||
quality_rampup_experiment_->cpu_adapted(cpu_limited);
|
||||
quality_rampup_experiment_->qp_resolution_adaptations(
|
||||
qp_resolution_adaptations);
|
||||
}
|
||||
|
||||
RTC_LOG(LS_INFO) << ActiveCountsToString(limitations);
|
||||
}
|
||||
|
@ -584,19 +556,7 @@ std::string VideoStreamEncoderResourceManager::ActiveCountsToString(
|
|||
|
||||
void VideoStreamEncoderResourceManager::OnQualityRampUp() {
|
||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||
// The VideoStreamEncoder makes the manager outlive the adaptation queue.
|
||||
// This means that if the task gets executed, |this| has not been freed yet.
|
||||
// TODO(https://crbug.com/webrtc/11565): When the manager no longer outlives
|
||||
// the adaptation queue, add logic to prevent use-after-free on |this|.
|
||||
resource_adaptation_queue_->PostTask([this] {
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
if (!stream_adapter_) {
|
||||
// The processor nulled before this task had a chance to execute. This
|
||||
// happens if the processor is destroyed. No action needed.
|
||||
return;
|
||||
}
|
||||
stream_adapter_->ClearRestrictions();
|
||||
});
|
||||
stream_adapter_->ClearRestrictions();
|
||||
quality_rampup_experiment_.reset();
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "rtc_base/strings/string_builder.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
#include "rtc_base/task_queue.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
#include "video/adaptation/balanced_constraint.h"
|
||||
#include "video/adaptation/bitrate_constraint.h"
|
||||
|
@ -79,8 +80,7 @@ class VideoStreamEncoderResourceManager
|
|||
DegradationPreferenceProvider* degradation_preference_provider);
|
||||
~VideoStreamEncoderResourceManager() override;
|
||||
|
||||
void Initialize(rtc::TaskQueue* encoder_queue,
|
||||
rtc::TaskQueue* resource_adaptation_queue);
|
||||
void Initialize(rtc::TaskQueue* encoder_queue);
|
||||
void SetAdaptationProcessor(
|
||||
ResourceAdaptationProcessorInterface* adaptation_processor,
|
||||
VideoStreamAdapter* stream_adapter);
|
||||
|
@ -166,19 +166,19 @@ class VideoStreamEncoderResourceManager
|
|||
active_counts);
|
||||
|
||||
DegradationPreferenceProvider* const degradation_preference_provider_;
|
||||
const rtc::scoped_refptr<BitrateConstraint> bitrate_constraint_;
|
||||
const rtc::scoped_refptr<BalancedConstraint> balanced_constraint_;
|
||||
std::unique_ptr<BitrateConstraint> bitrate_constraint_
|
||||
RTC_GUARDED_BY(encoder_queue_);
|
||||
const std::unique_ptr<BalancedConstraint> balanced_constraint_
|
||||
RTC_GUARDED_BY(encoder_queue_);
|
||||
const rtc::scoped_refptr<EncodeUsageResource> encode_usage_resource_;
|
||||
const rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource_;
|
||||
|
||||
rtc::TaskQueue* encoder_queue_;
|
||||
rtc::TaskQueue* resource_adaptation_queue_;
|
||||
VideoStreamInputStateProvider* const input_state_provider_
|
||||
RTC_GUARDED_BY(encoder_queue_);
|
||||
ResourceAdaptationProcessorInterface* adaptation_processor_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
VideoStreamAdapter* stream_adapter_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
RTC_GUARDED_BY(encoder_queue_);
|
||||
VideoStreamAdapter* stream_adapter_ RTC_GUARDED_BY(encoder_queue_);
|
||||
// Thread-safe.
|
||||
VideoStreamEncoderObserver* const encoder_stats_observer_;
|
||||
|
||||
|
@ -212,8 +212,7 @@ class VideoStreamEncoderResourceManager
|
|||
const rtc::scoped_refptr<Resource> resource;
|
||||
const VideoAdaptationReason reason;
|
||||
};
|
||||
mutable Mutex resource_lock_;
|
||||
std::vector<ResourceAndReason> resources_ RTC_GUARDED_BY(&resource_lock_);
|
||||
std::vector<ResourceAndReason> resources_ RTC_GUARDED_BY(encoder_queue_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -211,48 +211,38 @@ bool VideoStreamEncoder::EncoderRateSettings::operator!=(
|
|||
class VideoStreamEncoder::DegradationPreferenceManager
|
||||
: public DegradationPreferenceProvider {
|
||||
public:
|
||||
DegradationPreferenceManager()
|
||||
explicit DegradationPreferenceManager(
|
||||
VideoStreamAdapter* video_stream_adapter)
|
||||
: degradation_preference_(DegradationPreference::DISABLED),
|
||||
is_screenshare_(false),
|
||||
effective_degradation_preference_(DegradationPreference::DISABLED) {}
|
||||
|
||||
~DegradationPreferenceManager() override {
|
||||
RTC_DCHECK(!video_stream_adapter_);
|
||||
effective_degradation_preference_(DegradationPreference::DISABLED),
|
||||
video_stream_adapter_(video_stream_adapter) {
|
||||
RTC_DCHECK(video_stream_adapter_);
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
~DegradationPreferenceManager() override = default;
|
||||
|
||||
DegradationPreference degradation_preference() const override {
|
||||
MutexLock lock(&lock_);
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
return effective_degradation_preference_;
|
||||
}
|
||||
|
||||
void SetDegradationPreference(DegradationPreference degradation_preference) {
|
||||
MutexLock lock(&lock_);
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
degradation_preference_ = degradation_preference;
|
||||
MaybeUpdateEffectiveDegradationPreference();
|
||||
}
|
||||
|
||||
void SetIsScreenshare(bool is_screenshare) {
|
||||
MutexLock lock(&lock_);
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
is_screenshare_ = is_screenshare;
|
||||
MaybeUpdateEffectiveDegradationPreference();
|
||||
}
|
||||
|
||||
void SetVideoStreamAdapterQueue(
|
||||
TaskQueueBase* video_stream_adapter_task_queue) {
|
||||
RTC_DCHECK(!video_stream_adapter_task_queue_);
|
||||
RTC_DCHECK(video_stream_adapter_task_queue);
|
||||
RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue);
|
||||
video_stream_adapter_task_queue_ = video_stream_adapter_task_queue;
|
||||
}
|
||||
|
||||
void SetVideoStreamAdapter(VideoStreamAdapter* video_stream_adapter) {
|
||||
RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue_);
|
||||
video_stream_adapter_ = video_stream_adapter;
|
||||
}
|
||||
|
||||
private:
|
||||
void MaybeUpdateEffectiveDegradationPreference()
|
||||
RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_) {
|
||||
RTC_RUN_ON(&sequence_checker_) {
|
||||
DegradationPreference effective_degradation_preference =
|
||||
(is_screenshare_ &&
|
||||
degradation_preference_ == DegradationPreference::BALANCED)
|
||||
|
@ -261,27 +251,18 @@ class VideoStreamEncoder::DegradationPreferenceManager
|
|||
|
||||
if (effective_degradation_preference != effective_degradation_preference_) {
|
||||
effective_degradation_preference_ = effective_degradation_preference;
|
||||
if (video_stream_adapter_task_queue_) {
|
||||
video_stream_adapter_task_queue_->PostTask(
|
||||
ToQueuedTask([this, effective_degradation_preference]() {
|
||||
RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue_);
|
||||
if (video_stream_adapter_) {
|
||||
video_stream_adapter_->SetDegradationPreference(
|
||||
effective_degradation_preference);
|
||||
}
|
||||
}));
|
||||
}
|
||||
video_stream_adapter_->SetDegradationPreference(
|
||||
effective_degradation_preference);
|
||||
}
|
||||
}
|
||||
|
||||
mutable Mutex lock_;
|
||||
DegradationPreference degradation_preference_ RTC_GUARDED_BY(&lock_);
|
||||
bool is_screenshare_ RTC_GUARDED_BY(&lock_);
|
||||
SequenceChecker sequence_checker_;
|
||||
DegradationPreference degradation_preference_
|
||||
RTC_GUARDED_BY(&sequence_checker_);
|
||||
bool is_screenshare_ RTC_GUARDED_BY(&sequence_checker_);
|
||||
DegradationPreference effective_degradation_preference_
|
||||
RTC_GUARDED_BY(&lock_);
|
||||
TaskQueueBase* video_stream_adapter_task_queue_ = nullptr;
|
||||
VideoStreamAdapter* video_stream_adapter_
|
||||
RTC_GUARDED_BY(&video_stream_adapter_task_queue_);
|
||||
RTC_GUARDED_BY(&sequence_checker_);
|
||||
VideoStreamAdapter* video_stream_adapter_ RTC_GUARDED_BY(&sequence_checker_);
|
||||
};
|
||||
|
||||
VideoStreamEncoder::VideoStreamEncoder(
|
||||
|
@ -346,7 +327,8 @@ VideoStreamEncoder::VideoStreamEncoder(
|
|||
std::make_unique<ResourceAdaptationProcessor>(
|
||||
video_stream_adapter_.get())),
|
||||
degradation_preference_manager_(
|
||||
std::make_unique<DegradationPreferenceManager>()),
|
||||
std::make_unique<DegradationPreferenceManager>(
|
||||
video_stream_adapter_.get())),
|
||||
adaptation_constraints_(),
|
||||
stream_resource_manager_(&input_state_provider_,
|
||||
encoder_stats_observer,
|
||||
|
@ -356,33 +338,24 @@ VideoStreamEncoder::VideoStreamEncoder(
|
|||
degradation_preference_manager_.get()),
|
||||
video_source_sink_controller_(/*sink=*/this,
|
||||
/*source=*/nullptr),
|
||||
resource_adaptation_queue_(task_queue_factory->CreateTaskQueue(
|
||||
"ResourceAdaptationQueue",
|
||||
TaskQueueFactory::Priority::NORMAL)),
|
||||
encoder_queue_(task_queue_factory->CreateTaskQueue(
|
||||
"EncoderQueue",
|
||||
TaskQueueFactory::Priority::NORMAL)) {
|
||||
RTC_DCHECK(encoder_stats_observer);
|
||||
RTC_DCHECK_GE(number_of_cores, 1);
|
||||
|
||||
stream_resource_manager_.Initialize(&encoder_queue_,
|
||||
&resource_adaptation_queue_);
|
||||
stream_resource_manager_.Initialize(&encoder_queue_);
|
||||
|
||||
rtc::Event initialize_processor_event;
|
||||
resource_adaptation_queue_.PostTask([this, &initialize_processor_event] {
|
||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||
resource_adaptation_processor_->SetResourceAdaptationQueue(
|
||||
resource_adaptation_queue_.Get());
|
||||
encoder_queue_.PostTask([this, &initialize_processor_event] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
resource_adaptation_processor_->SetTaskQueue(encoder_queue_.Get());
|
||||
stream_resource_manager_.SetAdaptationProcessor(
|
||||
resource_adaptation_processor_.get(), video_stream_adapter_.get());
|
||||
resource_adaptation_processor_->AddResourceLimitationsListener(
|
||||
&stream_resource_manager_);
|
||||
video_stream_adapter_->AddRestrictionsListener(&stream_resource_manager_);
|
||||
video_stream_adapter_->AddRestrictionsListener(this);
|
||||
degradation_preference_manager_->SetVideoStreamAdapterQueue(
|
||||
resource_adaptation_queue_.Get());
|
||||
degradation_preference_manager_->SetVideoStreamAdapter(
|
||||
video_stream_adapter_.get());
|
||||
|
||||
// Add the stream resource manager's resources to the processor.
|
||||
adaptation_constraints_ = stream_resource_manager_.AdaptationConstraints();
|
||||
|
@ -407,19 +380,12 @@ void VideoStreamEncoder::Stop() {
|
|||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
||||
video_source_sink_controller_.SetSource(nullptr);
|
||||
|
||||
if (resource_adaptation_processor_) {
|
||||
for (auto& resource : stream_resource_manager_.MappedResources()) {
|
||||
resource_adaptation_processor_->RemoveResource(resource);
|
||||
}
|
||||
}
|
||||
rtc::Event shutdown_adaptation_processor_event;
|
||||
resource_adaptation_queue_.PostTask([this,
|
||||
&shutdown_adaptation_processor_event] {
|
||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||
encoder_queue_.PostTask([this] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
if (resource_adaptation_processor_) {
|
||||
// Removed on the resource_adaptaiton_processor_ queue because the
|
||||
// adaptation_constraints_ and adaptation_listeners_ fields are guarded by
|
||||
// this queue.
|
||||
for (auto& resource : stream_resource_manager_.MappedResources()) {
|
||||
resource_adaptation_processor_->RemoveResource(resource);
|
||||
}
|
||||
for (auto* constraint : adaptation_constraints_) {
|
||||
video_stream_adapter_->RemoveAdaptationConstraint(constraint);
|
||||
}
|
||||
|
@ -429,14 +395,8 @@ void VideoStreamEncoder::Stop() {
|
|||
resource_adaptation_processor_->RemoveResourceLimitationsListener(
|
||||
&stream_resource_manager_);
|
||||
stream_resource_manager_.SetAdaptationProcessor(nullptr, nullptr);
|
||||
degradation_preference_manager_->SetVideoStreamAdapter(nullptr);
|
||||
resource_adaptation_processor_.reset();
|
||||
}
|
||||
shutdown_adaptation_processor_event.Set();
|
||||
});
|
||||
shutdown_adaptation_processor_event.Wait(rtc::Event::kForever);
|
||||
encoder_queue_.PostTask([this] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
stream_resource_manager_.StopManagedResources();
|
||||
rate_allocator_ = nullptr;
|
||||
bitrate_observer_ = nullptr;
|
||||
|
@ -496,11 +456,11 @@ void VideoStreamEncoder::SetSource(
|
|||
video_source_sink_controller_.SetSource(source);
|
||||
input_state_provider_.OnHasInputChanged(source);
|
||||
|
||||
degradation_preference_manager_->SetDegradationPreference(
|
||||
degradation_preference);
|
||||
// This may trigger reconfiguring the QualityScaler on the encoder queue.
|
||||
encoder_queue_.PostTask([this, degradation_preference] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
degradation_preference_manager_->SetDegradationPreference(
|
||||
degradation_preference);
|
||||
stream_resource_manager_.SetDegradationPreferences(degradation_preference);
|
||||
if (encoder_) {
|
||||
stream_resource_manager_.ConfigureQualityScaler(
|
||||
|
@ -1809,7 +1769,7 @@ void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated(
|
|||
const VideoAdaptationCounters& adaptation_counters,
|
||||
rtc::scoped_refptr<Resource> reason,
|
||||
const VideoSourceRestrictions& unfiltered_restrictions) {
|
||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
std::string resource_name = reason ? reason->Name() : "<null>";
|
||||
RTC_LOG(INFO) << "Updating sink restrictions from " << resource_name << " to "
|
||||
<< restrictions.ToString();
|
||||
|
@ -2095,8 +2055,8 @@ void VideoStreamEncoder::InjectAdaptationResource(
|
|||
void VideoStreamEncoder::InjectAdaptationConstraint(
|
||||
AdaptationConstraint* adaptation_constraint) {
|
||||
rtc::Event event;
|
||||
resource_adaptation_queue_.PostTask([this, adaptation_constraint, &event] {
|
||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||
encoder_queue_.PostTask([this, adaptation_constraint, &event] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
if (!resource_adaptation_processor_) {
|
||||
// The VideoStreamEncoder was stopped and the processor destroyed before
|
||||
// this task had a chance to execute. No action needed.
|
||||
|
@ -2118,8 +2078,8 @@ VideoStreamEncoder::quality_scaler_resource_for_testing() {
|
|||
void VideoStreamEncoder::AddRestrictionsListenerForTesting(
|
||||
VideoSourceRestrictionsListener* restrictions_listener) {
|
||||
rtc::Event event;
|
||||
resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
|
||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||
encoder_queue_.PostTask([this, restrictions_listener, &event] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
RTC_DCHECK(resource_adaptation_processor_);
|
||||
video_stream_adapter_->AddRestrictionsListener(restrictions_listener);
|
||||
event.Set();
|
||||
|
@ -2130,8 +2090,8 @@ void VideoStreamEncoder::AddRestrictionsListenerForTesting(
|
|||
void VideoStreamEncoder::RemoveRestrictionsListenerForTesting(
|
||||
VideoSourceRestrictionsListener* restrictions_listener) {
|
||||
rtc::Event event;
|
||||
resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
|
||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||
encoder_queue_.PostTask([this, restrictions_listener, &event] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
RTC_DCHECK(resource_adaptation_processor_);
|
||||
video_stream_adapter_->RemoveRestrictionsListener(restrictions_listener);
|
||||
event.Set();
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "rtc_base/rate_statistics.h"
|
||||
#include "rtc_base/synchronization/sequence_checker.h"
|
||||
#include "rtc_base/task_queue.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
#include "rtc_base/thread_checker.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
#include "video/adaptation/video_stream_encoder_resource_manager.h"
|
||||
|
@ -112,9 +113,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
|||
// Used for testing. For example the |ScalingObserverInterface| methods must
|
||||
// be called on |encoder_queue_|.
|
||||
rtc::TaskQueue* encoder_queue() { return &encoder_queue_; }
|
||||
rtc::TaskQueue* resource_adaptation_queue() {
|
||||
return &resource_adaptation_queue_;
|
||||
}
|
||||
|
||||
void OnVideoSourceRestrictionsUpdated(
|
||||
VideoSourceRestrictions restrictions,
|
||||
|
@ -410,24 +408,24 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
|||
VideoStreamInputStateProvider input_state_provider_;
|
||||
|
||||
std::unique_ptr<VideoStreamAdapter> video_stream_adapter_
|
||||
RTC_GUARDED_BY(&resource_adaptation_queue_);
|
||||
RTC_GUARDED_BY(&encoder_queue_);
|
||||
// Responsible for adapting input resolution or frame rate to ensure resources
|
||||
// (e.g. CPU or bandwidth) are not overused.
|
||||
// Adding resources can occur on any thread, but all other methods need to be
|
||||
// called on the adaptation thread.
|
||||
// (e.g. CPU or bandwidth) are not overused. Adding resources can occur on any
|
||||
// thread.
|
||||
std::unique_ptr<ResourceAdaptationProcessorInterface>
|
||||
resource_adaptation_processor_;
|
||||
std::unique_ptr<DegradationPreferenceManager> degradation_preference_manager_;
|
||||
std::unique_ptr<DegradationPreferenceManager> degradation_preference_manager_
|
||||
RTC_GUARDED_BY(&encoder_queue_);
|
||||
std::vector<AdaptationConstraint*> adaptation_constraints_
|
||||
RTC_GUARDED_BY(&resource_adaptation_queue_);
|
||||
RTC_GUARDED_BY(&encoder_queue_);
|
||||
// Handles input, output and stats reporting related to VideoStreamEncoder
|
||||
// specific resources, such as "encode usage percent" measurements and "QP
|
||||
// scaling". Also involved with various mitigations such as inital frame
|
||||
// dropping.
|
||||
// The manager primarily operates on the |encoder_queue_| but its lifetime is
|
||||
// tied to the VideoStreamEncoder (which is destroyed off the encoder queue)
|
||||
// and its resource list is accessible from any thread.
|
||||
VideoStreamEncoderResourceManager stream_resource_manager_;
|
||||
// tied to the VideoStreamEncoder (which is destroyed off the encoder queue).
|
||||
VideoStreamEncoderResourceManager stream_resource_manager_
|
||||
RTC_GUARDED_BY(&encoder_queue_);
|
||||
// Carries out the VideoSourceRestrictions provided by the
|
||||
// ResourceAdaptationProcessor, i.e. reconfigures the source of video frames
|
||||
// to provide us with different resolution or frame rate.
|
||||
|
@ -436,10 +434,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
|||
|
||||
// Public methods are proxied to the task queues. The queues must be destroyed
|
||||
// first to make sure no tasks run that use other members.
|
||||
// TODO(https://crbug.com/webrtc/11172): Move ownership of the
|
||||
// ResourceAdaptationProcessor and its task queue to Call when processors are
|
||||
// multi-stream aware.
|
||||
rtc::TaskQueue resource_adaptation_queue_;
|
||||
rtc::TaskQueue encoder_queue_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(VideoStreamEncoder);
|
||||
|
|
|
@ -329,15 +329,6 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||
fraction_lost, round_trip_time_ms, cwnd_reduce_ratio);
|
||||
// Bitrate is updated on the encoder queue.
|
||||
WaitUntilTaskQueueIsIdle();
|
||||
// Give the managed resources time to react to the new bitrate.
|
||||
// TODO(hbos): Can we await an appropriate event instead?
|
||||
WaitUntilAdaptationTaskQueueIsIdle();
|
||||
}
|
||||
|
||||
void WaitUntilAdaptationTaskQueueIsIdle() {
|
||||
rtc::Event event;
|
||||
resource_adaptation_queue()->PostTask([&event] { event.Set(); });
|
||||
ASSERT_TRUE(event.Wait(5000));
|
||||
}
|
||||
|
||||
// This is used as a synchronisation mechanism, to make sure that the
|
||||
|
@ -351,7 +342,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||
// Triggers resource usage measurements on the fake CPU resource.
|
||||
void TriggerCpuOveruse() {
|
||||
rtc::Event event;
|
||||
resource_adaptation_queue()->PostTask([this, &event] {
|
||||
encoder_queue()->PostTask([this, &event] {
|
||||
fake_cpu_resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||
event.Set();
|
||||
});
|
||||
|
@ -359,7 +350,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||
}
|
||||
void TriggerCpuUnderuse() {
|
||||
rtc::Event event;
|
||||
resource_adaptation_queue()->PostTask([this, &event] {
|
||||
encoder_queue()->PostTask([this, &event] {
|
||||
fake_cpu_resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||
event.Set();
|
||||
});
|
||||
|
@ -369,7 +360,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||
// Triggers resource usage measurements on the fake quality resource.
|
||||
void TriggerQualityLow() {
|
||||
rtc::Event event;
|
||||
resource_adaptation_queue()->PostTask([this, &event] {
|
||||
encoder_queue()->PostTask([this, &event] {
|
||||
fake_quality_resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||
event.Set();
|
||||
});
|
||||
|
@ -377,7 +368,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||
}
|
||||
void TriggerQualityHigh() {
|
||||
rtc::Event event;
|
||||
resource_adaptation_queue()->PostTask([this, &event] {
|
||||
encoder_queue()->PostTask([this, &event] {
|
||||
fake_quality_resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||
event.Set();
|
||||
});
|
||||
|
@ -4172,7 +4163,7 @@ TEST_F(VideoStreamEncoderTest,
|
|||
WaitForEncodedFrame(3);
|
||||
|
||||
// Expect the sink_wants to specify a scaled frame.
|
||||
video_stream_encoder_->WaitUntilAdaptationTaskQueueIsIdle();
|
||||
video_stream_encoder_->WaitUntilTaskQueueIsIdle();
|
||||
EXPECT_THAT(video_source_.sink_wants(), ResolutionMax());
|
||||
|
||||
video_stream_encoder_->Stop();
|
||||
|
@ -4233,7 +4224,7 @@ TEST_F(VideoStreamEncoderTest, RampsUpInQualityWhenBwIsHigh) {
|
|||
WaitForEncodedFrame(timestamp_ms);
|
||||
// The ramp-up code involves the adaptation queue, give it time to execute.
|
||||
// TODO(hbos): Can we await an appropriate event instead?
|
||||
video_stream_encoder_->WaitUntilAdaptationTaskQueueIsIdle();
|
||||
video_stream_encoder_->WaitUntilTaskQueueIsIdle();
|
||||
EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
|
||||
|
||||
// Frame should not be adapted.
|
||||
|
|
Loading…
Reference in a new issue