| /* | 
 |  *  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. | 
 |     // | 
 |     // |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; | 
 |  | 
 |     // 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; | 
 |  | 
 |   // Conditionally requests a refresh frame via | 
 |   // Callback::RequestRefreshFrame. | 
 |   virtual void ProcessKeyFrameRequest() = 0; | 
 | }; | 
 |  | 
 | }  // namespace webrtc | 
 |  | 
 | #endif  // VIDEO_FRAME_CADENCE_ADAPTER_H_ |