Henrik Boström b613e3ab6b [Adaptation] Resource::IsAdaptationUpAllowed() for IsBitrateConstrained.
This CL is part of the Call-Level Adaptation Processing design doc:
https://docs.google.com/document/d/1ZyC26yOCknrrcYa839ZWLxD6o6Gig5A3lVTh4E41074/edit?usp=sharing

The VideoStreamAdapter is currently responsible for aborting and not
providing adaptations if we are bitrate constrained
(kIsBitrateConstrained). Whether or not we are bitrate constrained is
clearly a resource question and should be phrased as such. By moving
this logic to Resource::IsAdaptationUpAllowed(), the VideoStreamAdapter
can continue to be thread-agnostic when a future CL introduces a
"processing queue", and the VideoStreamAdapter can be simplified: it
returns Adaptations even if we are constrained (but we refuse to Apply
them any resource rejects it).

This CL adds new Resource classes as inner classes of
ResourceAdaptationProcessor that take on the responsibility of
kIsBitrateConstrained logic:
PreventIncreaseResolutionDueToBitrateResource and
PreventAdaptUpInBalancedResource.

A third class, PreventAdaptUpDueToActiveCounts, also allows us to move
adaptation-aborting logic. This piece of code appears to be about not
adapting up if we’re already at the highest setting, which would be
VideoStreamAdapter responsibility (covered by
Adaptation::Status::kLimitReached), but it is actually more complicated
than that: the active_counts_ care about "reason", so it is really about
"is this resource type OK with you adapting up?". We should probably
rewrite this code in the future, but for now it is moved to an inner
class of ResourceAdaptationProcessor.

Other misc changes:
- ApplyDegradationPreference is moved to video_stream_adapter.[h/cc]
  and renamed "Filter".
- OnResourceOveruse/Underuse now use Resource* as the reason instead of
  AdaptReason. In a future CL, the processor will be split into a
  "processor" part and a "video stream encoder resource manager" part.
  Only the manager needs to know about AdaptReason since this is only
  used for |active_counts_| and we want to get rid of it as much as
  possible as it is not future-proof.

Bug: webrtc:11172
Change-Id: I2eba9ec3d717f7024c451aeb14635fe759551318
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/172930
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Evan Shrubsole <eshr@google.com>
Cr-Commit-Position: refs/heads/master@{#31099}
2020-04-17 12:35:18 +00:00

114 lines
4.2 KiB
C++

/*
* Copyright 2019 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.
*/
#ifndef CALL_ADAPTATION_RESOURCE_H_
#define CALL_ADAPTATION_RESOURCE_H_
#include <string>
#include <vector>
#include "absl/types/optional.h"
#include "call/adaptation/video_source_restrictions.h"
#include "call/adaptation/video_stream_input_state.h"
namespace webrtc {
class Resource;
enum class ResourceUsageState {
// Action is needed to minimze the load on this resource.
kOveruse,
// No action needed for this resource, increasing the load on this resource
// is not allowed.
kStable,
// Increasing the load on this resource is allowed.
kUnderuse,
};
enum class ResourceListenerResponse {
kNothing,
// This response is only applicable to QualityScaler-based resources.
// It tells the QualityScaler to increase its QP measurement frequency.
//
// This is modelled after AdaptationObserverInterface::AdaptDown()'s return
// value. The method comment says "Returns false if a downgrade was requested
// but the request did not result in a new limiting resolution or fps."
// However the actual implementation seems to be: Return false if
// !has_input_video_ or if we use balanced degradation preference and we DID
// adapt frame rate but the difference between input frame rate and balanced
// settings' min fps is less than the balanced settings' min fps diff - in all
// other cases, return true whether or not adaptation happened.
//
// For QualityScaler-based resources, kQualityScalerShouldIncreaseFrequency
// maps to "return false" and kNothing maps to "return true".
//
// TODO(https://crbug.com/webrtc/11222): Remove this enum. Resource
// measurements and adaptation decisions need to be separated in order to
// support injectable adaptation modules, multi-stream aware adaptation and
// decision-making logic based on multiple resources.
kQualityScalerShouldIncreaseFrequency,
};
class ResourceListener {
public:
virtual ~ResourceListener();
// Informs the listener of a new measurement of resource usage. This means
// that |resource.usage_state()| is now up-to-date.
//
// The listener may influence the resource that signaled the measurement
// according to the returned ResourceListenerResponse enum.
virtual ResourceListenerResponse OnResourceUsageStateMeasured(
const Resource& resource) = 0;
};
// A Resource is something which can be measured as "overused", "stable" or
// "underused". When the resource usage changes, listeners of the resource are
// informed.
//
// Implementations of this interface are responsible for performing resource
// usage measurements and invoking OnResourceUsageStateMeasured().
class Resource {
public:
// By default, usage_state() is kStable until a measurement is made.
Resource();
virtual ~Resource();
void RegisterListener(ResourceListener* listener);
void UnregisterListener(ResourceListener* listener);
ResourceUsageState usage_state() const;
// This method allows the Resource to reject a proposed adaptation in the "up"
// direction if it predicts this would cause overuse of this resource. The
// default implementation unconditionally returns true (= allowed).
virtual bool IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
const Resource& reason_resource) const;
virtual std::string name() const = 0;
protected:
// Updates the usage state and informs all registered listeners.
// Returns the result of the last listener's OnResourceUsageStateMeasured()
// call that was not kNothing, else kNothing.
ResourceListenerResponse OnResourceUsageStateMeasured(
ResourceUsageState usage_state);
private:
ResourceUsageState usage_state_;
std::vector<ResourceListener*> listeners_;
};
} // namespace webrtc
#endif // CALL_ADAPTATION_RESOURCE_H_