This change ensures that the FCA now is informed about a new max fps when VideoStreamEncoder::OnVideoSourceRestrictionsUpdated is called. The latest restricted frame rate which is provided to the FCA will only affect the cadence of repeated non-idle (quality has not converged) frames and the main goal is to ensure that the FCA reduces its repeat rate in situations where the video source is constrained. UpdateVideoSourceRestrictions is added to the FrameCadenceAdapter API and it is called from the VideoStreamEncoder when its source parameters (resolution and/or frame rate) are restricted. This modification has no effect on the flow driven by ProcessOnDelayedCadence (non repeated frames). Bug: webrtc:15539 Change-Id: I26dee6480e5137f82c5ccf57091b737cad82dbf6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/328300 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Markus Handell <handellm@webrtc.org> Commit-Queue: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/main@{#41308}
126 lines
4.9 KiB
C++
126 lines
4.9 KiB
C++
/*
|
|
* Copyright (c) 2021 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 VIDEO_FRAME_CADENCE_ADAPTER_H_
|
|
#define VIDEO_FRAME_CADENCE_ADAPTER_H_
|
|
|
|
#include <memory>
|
|
|
|
#include "absl/base/attributes.h"
|
|
#include "api/field_trials_view.h"
|
|
#include "api/task_queue/task_queue_base.h"
|
|
#include "api/units/time_delta.h"
|
|
#include "api/video/video_frame.h"
|
|
#include "api/video/video_sink_interface.h"
|
|
#include "rtc_base/synchronization/mutex.h"
|
|
#include "rtc_base/thread_annotations.h"
|
|
#include "system_wrappers/include/clock.h"
|
|
|
|
namespace webrtc {
|
|
|
|
// A sink adapter implementing mutations to the received frame cadence.
|
|
// With the exception of the constructor and the methods overridden in
|
|
// VideoSinkInterface, the rest of the interface to this class (including dtor)
|
|
// needs to happen on the queue passed in Create.
|
|
class FrameCadenceAdapterInterface
|
|
: public rtc::VideoSinkInterface<VideoFrame> {
|
|
public:
|
|
// Averaging window spanning 90 frames at default 30fps, matching old media
|
|
// optimization module defaults.
|
|
// TODO(crbug.com/1255737): Use TimeDelta.
|
|
static constexpr int64_t kFrameRateAveragingWindowSizeMs = (1000 / 30) * 90;
|
|
// In zero-hertz mode, the idle repeat rate is a compromise between
|
|
// RTP receiver keyframe-requesting timeout (3s), other backend limitations
|
|
// and some worst case RTT.
|
|
static constexpr TimeDelta kZeroHertzIdleRepeatRatePeriod =
|
|
TimeDelta::Millis(1000);
|
|
// The number of frame periods to wait for new frames until starting to
|
|
// request refresh frames.
|
|
static constexpr int kOnDiscardedFrameRefreshFramePeriod = 3;
|
|
|
|
struct ZeroHertzModeParams {
|
|
// The number of simulcast layers used in this configuration.
|
|
size_t num_simulcast_layers = 0;
|
|
};
|
|
|
|
// Callback interface used to inform instance owners.
|
|
class Callback {
|
|
public:
|
|
virtual ~Callback() = default;
|
|
|
|
// Called when a frame arrives on the |queue| specified in Create.
|
|
//
|
|
// The |post_time| parameter indicates the current time sampled when
|
|
// FrameCadenceAdapterInterface::OnFrame was called.
|
|
//
|
|
// |queue_overload| is true if the frame cadence adapter notices it's
|
|
// not able to deliver the incoming |frame| to the |queue| in the expected
|
|
// time.
|
|
virtual void OnFrame(Timestamp post_time,
|
|
bool queue_overload,
|
|
const VideoFrame& frame) = 0;
|
|
|
|
// Called when the source has discarded a frame.
|
|
virtual void OnDiscardedFrame() = 0;
|
|
|
|
// Called when the adapter needs the source to send a refresh frame.
|
|
virtual void RequestRefreshFrame() = 0;
|
|
};
|
|
|
|
// Factory function creating a production instance. Deletion of the returned
|
|
// instance needs to happen on the same sequence that Create() was called on.
|
|
// Frames arriving in FrameCadenceAdapterInterface::OnFrame are posted to
|
|
// Callback::OnFrame on the |queue|.
|
|
static std::unique_ptr<FrameCadenceAdapterInterface> Create(
|
|
Clock* clock,
|
|
TaskQueueBase* queue,
|
|
const FieldTrialsView& field_trials);
|
|
|
|
// Call before using the rest of the API.
|
|
virtual void Initialize(Callback* callback) = 0;
|
|
|
|
// Pass zero hertz parameters in |params| as a prerequisite to enable
|
|
// zero-hertz operation. If absl:::nullopt is passed, the cadence adapter will
|
|
// switch to passthrough mode.
|
|
virtual void SetZeroHertzModeEnabled(
|
|
absl::optional<ZeroHertzModeParams> params) = 0;
|
|
|
|
// Returns the input framerate. This is measured by RateStatistics when
|
|
// zero-hertz mode is off, and returns the max framerate in zero-hertz mode.
|
|
virtual absl::optional<uint32_t> GetInputFrameRateFps() = 0;
|
|
|
|
// Updates frame rate. This is done unconditionally irrespective of adapter
|
|
// mode.
|
|
virtual void UpdateFrameRate() = 0;
|
|
|
|
// Updates quality convergence status for an enabled spatial layer.
|
|
// Convergence means QP has dropped to a low-enough level to warrant ceasing
|
|
// to send identical frames at high frequency.
|
|
virtual void UpdateLayerQualityConvergence(size_t spatial_index,
|
|
bool converged) = 0;
|
|
|
|
// Updates spatial layer enabled status.
|
|
virtual void UpdateLayerStatus(size_t spatial_index, bool enabled) = 0;
|
|
|
|
// Updates the restrictions of max frame rate for the video source.
|
|
// The new `max_frame_rate` will only affect the cadence of Callback::OnFrame
|
|
// for non-idle (non converged) repeated frames.
|
|
virtual void UpdateVideoSourceRestrictions(
|
|
absl::optional<double> max_frame_rate) = 0;
|
|
|
|
// Conditionally requests a refresh frame via
|
|
// Callback::RequestRefreshFrame.
|
|
virtual void ProcessKeyFrameRequest() = 0;
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // VIDEO_FRAME_CADENCE_ADAPTER_H_
|