[Adaptation] Move min pixel limit logic out of adaptation processor
This is in preperation for eventual multi-stream and multi-mitigation adaptation. This logic only applied to a single stream and thus is better fit in the VideoStreamAdapter. Bug: webrtc:11754 Change-Id: Icc5c7920038c82b574f4b5f7efbc92698691076f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/181585 Commit-Queue: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31944}
This commit is contained in:
parent
fcf5e7b131
commit
d73d421565
@ -69,12 +69,10 @@ ResourceAdaptationProcessor::MitigationResultAndLogMessage::
|
||||
: result(result), message(std::move(message)) {}
|
||||
|
||||
ResourceAdaptationProcessor::ResourceAdaptationProcessor(
|
||||
VideoStreamEncoderObserver* encoder_stats_observer,
|
||||
VideoStreamAdapter* stream_adapter)
|
||||
: resource_adaptation_queue_(nullptr),
|
||||
resource_listener_delegate_(
|
||||
new rtc::RefCountedObject<ResourceListenerDelegate>(this)),
|
||||
encoder_stats_observer_(encoder_stats_observer),
|
||||
resources_(),
|
||||
stream_adapter_(stream_adapter),
|
||||
last_reported_source_restrictions_(),
|
||||
@ -302,9 +300,6 @@ ResourceAdaptationProcessor::OnResourceOveruse(
|
||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||
// How can this stream be adapted up?
|
||||
Adaptation adaptation = stream_adapter_->GetAdaptationDown();
|
||||
if (adaptation.min_pixel_limit_reached()) {
|
||||
encoder_stats_observer_->OnMinPixelLimitReached();
|
||||
}
|
||||
if (adaptation.status() == Adaptation::Status::kLimitReached) {
|
||||
// Add resource as most limited.
|
||||
VideoStreamAdapter::RestrictionsWithCounters restrictions;
|
||||
|
||||
@ -54,8 +54,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
||||
public VideoSourceRestrictionsListener,
|
||||
public ResourceListener {
|
||||
public:
|
||||
ResourceAdaptationProcessor(
|
||||
VideoStreamEncoderObserver* encoder_stats_observer,
|
||||
explicit ResourceAdaptationProcessor(
|
||||
VideoStreamAdapter* video_stream_adapter);
|
||||
~ResourceAdaptationProcessor() override;
|
||||
|
||||
@ -147,8 +146,6 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
||||
TaskQueueBase* resource_adaptation_queue_;
|
||||
rtc::scoped_refptr<ResourceListenerDelegate> resource_listener_delegate_;
|
||||
// Input and output.
|
||||
VideoStreamEncoderObserver* const encoder_stats_observer_
|
||||
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||
mutable Mutex resources_lock_;
|
||||
std::vector<rtc::scoped_refptr<Resource>> resources_
|
||||
RTC_GUARDED_BY(resources_lock_);
|
||||
|
||||
@ -89,9 +89,9 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
|
||||
resource_(FakeResource::Create("FakeResource")),
|
||||
other_resource_(FakeResource::Create("OtherFakeResource")),
|
||||
video_stream_adapter_(
|
||||
std::make_unique<VideoStreamAdapter>(&input_state_provider_)),
|
||||
std::make_unique<VideoStreamAdapter>(&input_state_provider_,
|
||||
&frame_rate_provider_)),
|
||||
processor_(std::make_unique<ResourceAdaptationProcessor>(
|
||||
/*encoder_stats_observer=*/&frame_rate_provider_,
|
||||
video_stream_adapter_.get())) {
|
||||
processor_->SetResourceAdaptationQueue(TaskQueueBase::Current());
|
||||
video_stream_adapter_->AddRestrictionsListener(&restrictions_listener_);
|
||||
|
||||
@ -108,6 +108,12 @@ bool CanIncreaseFrameRateTo(int max_frame_rate,
|
||||
std::numeric_limits<int>::max()));
|
||||
}
|
||||
|
||||
bool MinPixelLimitReached(const VideoStreamInputState& input_state) {
|
||||
return input_state.frame_size_pixels().has_value() &&
|
||||
GetLowerResolutionThan(input_state.frame_size_pixels().value()) <
|
||||
input_state.min_pixels_per_frame();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
VideoSourceRestrictionsListener::~VideoSourceRestrictionsListener() = default;
|
||||
@ -161,23 +167,15 @@ const char* Adaptation::StatusToString(Adaptation::Status status) {
|
||||
Adaptation::Adaptation(int validation_id,
|
||||
VideoSourceRestrictions restrictions,
|
||||
VideoAdaptationCounters counters,
|
||||
VideoStreamInputState input_state,
|
||||
bool min_pixel_limit_reached)
|
||||
VideoStreamInputState input_state)
|
||||
: validation_id_(validation_id),
|
||||
status_(Status::kValid),
|
||||
min_pixel_limit_reached_(min_pixel_limit_reached),
|
||||
input_state_(std::move(input_state)),
|
||||
restrictions_(std::move(restrictions)),
|
||||
counters_(std::move(counters)) {}
|
||||
|
||||
Adaptation::Adaptation(int validation_id,
|
||||
Status invalid_status,
|
||||
VideoStreamInputState input_state,
|
||||
bool min_pixel_limit_reached)
|
||||
: validation_id_(validation_id),
|
||||
status_(invalid_status),
|
||||
min_pixel_limit_reached_(min_pixel_limit_reached),
|
||||
input_state_(std::move(input_state)) {
|
||||
Adaptation::Adaptation(int validation_id, Status invalid_status)
|
||||
: validation_id_(validation_id), status_(invalid_status) {
|
||||
RTC_DCHECK_NE(status_, Status::kValid);
|
||||
}
|
||||
|
||||
@ -185,10 +183,6 @@ Adaptation::Status Adaptation::status() const {
|
||||
return status_;
|
||||
}
|
||||
|
||||
bool Adaptation::min_pixel_limit_reached() const {
|
||||
return min_pixel_limit_reached_;
|
||||
}
|
||||
|
||||
const VideoStreamInputState& Adaptation::input_state() const {
|
||||
return input_state_;
|
||||
}
|
||||
@ -202,14 +196,16 @@ const VideoAdaptationCounters& Adaptation::counters() const {
|
||||
}
|
||||
|
||||
VideoStreamAdapter::VideoStreamAdapter(
|
||||
VideoStreamInputStateProvider* input_state_provider)
|
||||
VideoStreamInputStateProvider* input_state_provider,
|
||||
VideoStreamEncoderObserver* encoder_stats_observer)
|
||||
: input_state_provider_(input_state_provider),
|
||||
balanced_settings_(),
|
||||
encoder_stats_observer_(encoder_stats_observer),
|
||||
adaptation_validation_id_(0),
|
||||
degradation_preference_(DegradationPreference::DISABLED),
|
||||
awaiting_frame_size_change_(absl::nullopt),
|
||||
last_video_source_restrictions_() {
|
||||
awaiting_frame_size_change_(absl::nullopt) {
|
||||
sequence_checker_.Detach();
|
||||
RTC_DCHECK(input_state_provider_);
|
||||
RTC_DCHECK(encoder_stats_observer_);
|
||||
}
|
||||
|
||||
VideoStreamAdapter::~VideoStreamAdapter() {
|
||||
@ -299,17 +295,11 @@ void VideoStreamAdapter::SetDegradationPreference(
|
||||
struct VideoStreamAdapter::RestrictionsOrStateVisitor {
|
||||
Adaptation operator()(const RestrictionsWithCounters& r) const {
|
||||
return Adaptation(adaptation_validation_id, r.restrictions, r.counters,
|
||||
input_state, min_pixel_limit_reached());
|
||||
input_state);
|
||||
}
|
||||
Adaptation operator()(const Adaptation::Status& status) const {
|
||||
RTC_DCHECK_NE(status, Adaptation::Status::kValid);
|
||||
return Adaptation(adaptation_validation_id, status, input_state,
|
||||
min_pixel_limit_reached());
|
||||
}
|
||||
bool min_pixel_limit_reached() const {
|
||||
return input_state.frame_size_pixels().has_value() &&
|
||||
GetLowerResolutionThan(input_state.frame_size_pixels().value()) <
|
||||
input_state.min_pixels_per_frame();
|
||||
return Adaptation(adaptation_validation_id, status);
|
||||
}
|
||||
|
||||
const int adaptation_validation_id;
|
||||
@ -399,7 +389,9 @@ Adaptation VideoStreamAdapter::GetAdaptationDown() {
|
||||
++adaptation_validation_id_;
|
||||
RestrictionsOrState restrictions_or_state =
|
||||
GetAdaptationDownStep(input_state, current_restrictions_);
|
||||
|
||||
if (MinPixelLimitReached(input_state)) {
|
||||
encoder_stats_observer_->OnMinPixelLimitReached();
|
||||
}
|
||||
// Check for min_fps
|
||||
if (degradation_preference_ == DegradationPreference::BALANCED &&
|
||||
absl::holds_alternative<RestrictionsWithCounters>(
|
||||
@ -664,7 +656,7 @@ Adaptation VideoStreamAdapter::GetAdaptationTo(
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
VideoStreamInputState input_state = input_state_provider_->InputState();
|
||||
return Adaptation(adaptation_validation_id_, restrictions, counters,
|
||||
input_state, false);
|
||||
input_state);
|
||||
}
|
||||
|
||||
void VideoStreamAdapter::BroadcastVideoRestrictionsUpdate(
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "api/adaptation/resource.h"
|
||||
#include "api/rtp_parameters.h"
|
||||
#include "api/video/video_adaptation_counters.h"
|
||||
#include "api/video/video_stream_encoder_observer.h"
|
||||
#include "call/adaptation/adaptation_constraint.h"
|
||||
#include "call/adaptation/degradation_preference_provider.h"
|
||||
#include "call/adaptation/video_source_restrictions.h"
|
||||
@ -87,8 +88,6 @@ class Adaptation final {
|
||||
const VideoStreamInputState& input_state() const;
|
||||
const VideoSourceRestrictions& restrictions() const;
|
||||
const VideoAdaptationCounters& counters() const;
|
||||
// Used for stats reporting.
|
||||
bool min_pixel_limit_reached() const;
|
||||
|
||||
private:
|
||||
friend class VideoStreamAdapter;
|
||||
@ -97,13 +96,9 @@ class Adaptation final {
|
||||
Adaptation(int validation_id,
|
||||
VideoSourceRestrictions restrictions,
|
||||
VideoAdaptationCounters counters,
|
||||
VideoStreamInputState input_state,
|
||||
bool min_pixel_limit_reached);
|
||||
VideoStreamInputState input_state);
|
||||
// Constructor when adaptation is not valid. Status MUST NOT be kValid.
|
||||
Adaptation(int validation_id,
|
||||
Status invalid_status,
|
||||
VideoStreamInputState input_state,
|
||||
bool min_pixel_limit_reached);
|
||||
Adaptation(int validation_id, Status invalid_status);
|
||||
|
||||
// An Adaptation can become invalidated if the state of VideoStreamAdapter is
|
||||
// modified before the Adaptation is applied. To guard against this, this ID
|
||||
@ -111,7 +106,6 @@ class Adaptation final {
|
||||
// TODO(https://crbug.com/webrtc/11700): Remove the validation_id_.
|
||||
const int validation_id_;
|
||||
const Status status_;
|
||||
const bool min_pixel_limit_reached_;
|
||||
// Input state when adaptation was made.
|
||||
const VideoStreamInputState input_state_;
|
||||
const VideoSourceRestrictions restrictions_;
|
||||
@ -126,8 +120,8 @@ class Adaptation final {
|
||||
// 3. Modify the stream's restrictions in one of the valid ways.
|
||||
class VideoStreamAdapter {
|
||||
public:
|
||||
explicit VideoStreamAdapter(
|
||||
VideoStreamInputStateProvider* input_state_provider);
|
||||
VideoStreamAdapter(VideoStreamInputStateProvider* input_state_provider,
|
||||
VideoStreamEncoderObserver* encoder_stats_observer);
|
||||
~VideoStreamAdapter();
|
||||
|
||||
VideoSourceRestrictions source_restrictions() const;
|
||||
@ -224,6 +218,8 @@ class VideoStreamAdapter {
|
||||
// Gets the input state which is the basis of all adaptations.
|
||||
// Thread safe.
|
||||
VideoStreamInputStateProvider* input_state_provider_;
|
||||
// Used to signal when min pixel limit has been reached.
|
||||
VideoStreamEncoderObserver* const encoder_stats_observer_;
|
||||
// Decides the next adaptation target in DegradationPreference::BALANCED.
|
||||
const BalancedDegradationSettings balanced_settings_;
|
||||
// To guard against applying adaptations that have become invalidated, an
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "api/video_codecs/video_encoder_config.h"
|
||||
#include "call/adaptation/adaptation_constraint.h"
|
||||
#include "call/adaptation/encoder_settings.h"
|
||||
#include "call/adaptation/test/fake_frame_rate_provider.h"
|
||||
#include "call/adaptation/test/fake_resource.h"
|
||||
#include "call/adaptation/video_source_restrictions.h"
|
||||
#include "call/adaptation/video_stream_input_state.h"
|
||||
@ -137,7 +138,7 @@ class FakeVideoStreamAdapterListner : public VideoSourceRestrictionsListener {
|
||||
VideoSourceRestrictions restrictions,
|
||||
const VideoAdaptationCounters& adaptation_counters,
|
||||
rtc::scoped_refptr<Resource> reason,
|
||||
const VideoSourceRestrictions& unfiltered_restrictions) {
|
||||
const VideoSourceRestrictions& unfiltered_restrictions) override {
|
||||
calls_++;
|
||||
last_restrictions_ = unfiltered_restrictions;
|
||||
}
|
||||
@ -172,14 +173,14 @@ class VideoStreamAdapterTest : public ::testing::Test {
|
||||
public:
|
||||
VideoStreamAdapterTest()
|
||||
: field_trials_(BalancedFieldTrialConfig()),
|
||||
input_state_provider_(),
|
||||
resource_(FakeResource::Create("FakeResource")),
|
||||
adapter_(&input_state_provider_) {}
|
||||
adapter_(&input_state_provider_, &encoder_stats_observer_) {}
|
||||
|
||||
protected:
|
||||
webrtc::test::ScopedFieldTrials field_trials_;
|
||||
FakeVideoStreamInputStateProvider input_state_provider_;
|
||||
rtc::scoped_refptr<Resource> resource_;
|
||||
testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
|
||||
VideoStreamAdapter adapter_;
|
||||
};
|
||||
|
||||
@ -195,7 +196,6 @@ TEST_F(VideoStreamAdapterTest, MaintainFramerate_DecreasesPixelsToThreeFifths) {
|
||||
kDefaultMinPixelsPerFrame);
|
||||
Adaptation adaptation = adapter_.GetAdaptationDown();
|
||||
EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
|
||||
EXPECT_FALSE(adaptation.min_pixel_limit_reached());
|
||||
adapter_.ApplyAdaptation(adaptation, nullptr);
|
||||
EXPECT_EQ(static_cast<size_t>((kInputPixels * 3) / 5),
|
||||
adapter_.source_restrictions().max_pixels_per_frame());
|
||||
@ -212,6 +212,7 @@ TEST_F(VideoStreamAdapterTest,
|
||||
adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
|
||||
input_state_provider_.SetInputState(kMinPixelsPerFrame + 1, 30,
|
||||
kMinPixelsPerFrame);
|
||||
EXPECT_CALL(encoder_stats_observer_, OnMinPixelLimitReached());
|
||||
// Even though we are above kMinPixelsPerFrame, because adapting down would
|
||||
// have exceeded the limit, we are said to have reached the limit already.
|
||||
// This differs from the frame rate adaptation logic, which would have clamped
|
||||
@ -219,7 +220,6 @@ TEST_F(VideoStreamAdapterTest,
|
||||
// step.
|
||||
Adaptation adaptation = adapter_.GetAdaptationDown();
|
||||
EXPECT_EQ(Adaptation::Status::kLimitReached, adaptation.status());
|
||||
EXPECT_TRUE(adaptation.min_pixel_limit_reached());
|
||||
}
|
||||
|
||||
TEST_F(VideoStreamAdapterTest, MaintainFramerate_IncreasePixelsToFiveThirds) {
|
||||
@ -537,6 +537,7 @@ TEST_F(VideoStreamAdapterTest, Balanced_LimitReached) {
|
||||
adapter_.GetAdaptationUp().status());
|
||||
// Adapting down once result in restricted frame rate, in this case we reach
|
||||
// the lowest possible frame rate immediately: kBalancedLowFrameRateFps.
|
||||
EXPECT_CALL(encoder_stats_observer_, OnMinPixelLimitReached()).Times(2);
|
||||
fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
|
||||
EXPECT_EQ(static_cast<double>(kBalancedLowFrameRateFps),
|
||||
adapter_.source_restrictions().max_frame_rate());
|
||||
@ -940,7 +941,8 @@ TEST_F(VideoStreamAdapterTest, AdaptationConstraintDisallowsAdaptationsUp) {
|
||||
TEST(VideoStreamAdapterDeathTest,
|
||||
SetDegradationPreferenceInvalidatesAdaptations) {
|
||||
FakeVideoStreamInputStateProvider input_state_provider;
|
||||
VideoStreamAdapter adapter(&input_state_provider);
|
||||
testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
|
||||
VideoStreamAdapter adapter(&input_state_provider, &encoder_stats_observer_);
|
||||
adapter.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
|
||||
input_state_provider.SetInputState(1280 * 720, 30, kDefaultMinPixelsPerFrame);
|
||||
Adaptation adaptation = adapter.GetAdaptationDown();
|
||||
@ -950,7 +952,8 @@ TEST(VideoStreamAdapterDeathTest,
|
||||
|
||||
TEST(VideoStreamAdapterDeathTest, AdaptDownInvalidatesAdaptations) {
|
||||
FakeVideoStreamInputStateProvider input_state_provider;
|
||||
VideoStreamAdapter adapter(&input_state_provider);
|
||||
testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
|
||||
VideoStreamAdapter adapter(&input_state_provider, &encoder_stats_observer_);
|
||||
adapter.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
|
||||
input_state_provider.SetInputState(1280 * 720, 30, kDefaultMinPixelsPerFrame);
|
||||
Adaptation adaptation = adapter.GetAdaptationDown();
|
||||
|
||||
@ -341,10 +341,10 @@ VideoStreamEncoder::VideoStreamEncoder(
|
||||
encoder_switch_requested_(false),
|
||||
input_state_provider_(encoder_stats_observer),
|
||||
video_stream_adapter_(
|
||||
std::make_unique<VideoStreamAdapter>(&input_state_provider_)),
|
||||
std::make_unique<VideoStreamAdapter>(&input_state_provider_,
|
||||
encoder_stats_observer)),
|
||||
resource_adaptation_processor_(
|
||||
std::make_unique<ResourceAdaptationProcessor>(
|
||||
encoder_stats_observer,
|
||||
video_stream_adapter_.get())),
|
||||
degradation_preference_manager_(
|
||||
std::make_unique<DegradationPreferenceManager>()),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user