| /* |
| * 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_ |