| /* |
| * 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/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); |
| |
| struct ZeroHertzModeParams { |
| // The number of simulcast layers used in this configuration. |
| int 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. |
| // |
| // |frames_scheduled_for_processing| indicates how many frames that have |
| // been scheduled for processing. During sequential conditions where |
| // FrameCadenceAdapterInterface::OnFrame is invoked and subsequently ending |
| // up in this callback, this value will read 1. Otherwise if the |
| // |queue| gets stalled for some reason, the value will increase |
| // beyond 1. |
| virtual void OnFrame(Timestamp post_time, |
| int frames_scheduled_for_processing, |
| const VideoFrame& frame) = 0; |
| |
| // Called when the source has discarded a frame. |
| virtual void OnDiscardedFrame() = 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); |
| |
| // 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(int spatial_index, |
| bool converged) = 0; |
| |
| // Updates spatial layer enabled status. |
| virtual void UpdateLayerStatus(int spatial_index, bool enabled) = 0; |
| |
| // Returns true if a key frame request should cause generation of a new frame |
| // from the source. |
| virtual ABSL_MUST_USE_RESULT bool ProcessKeyFrameRequest() = 0; |
| }; |
| |
| } // namespace webrtc |
| |
| #endif // VIDEO_FRAME_CADENCE_ADAPTER_H_ |