1 /* 2 * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef VIDEO_FRAME_CADENCE_ADAPTER_H_ 12 #define VIDEO_FRAME_CADENCE_ADAPTER_H_ 13 14 #include <memory> 15 16 #include "absl/base/attributes.h" 17 #include "api/field_trials_view.h" 18 #include "api/task_queue/task_queue_base.h" 19 #include "api/units/time_delta.h" 20 #include "api/video/video_frame.h" 21 #include "api/video/video_sink_interface.h" 22 #include "rtc_base/synchronization/mutex.h" 23 #include "rtc_base/thread_annotations.h" 24 #include "system_wrappers/include/clock.h" 25 26 namespace webrtc { 27 28 // A sink adapter implementing mutations to the received frame cadence. 29 // With the exception of the constructor and the methods overridden in 30 // VideoSinkInterface, the rest of the interface to this class (including dtor) 31 // needs to happen on the queue passed in Create. 32 class FrameCadenceAdapterInterface 33 : public rtc::VideoSinkInterface<VideoFrame> { 34 public: 35 // Averaging window spanning 90 frames at default 30fps, matching old media 36 // optimization module defaults. 37 // TODO(crbug.com/1255737): Use TimeDelta. 38 static constexpr int64_t kFrameRateAveragingWindowSizeMs = (1000 / 30) * 90; 39 // In zero-hertz mode, the idle repeat rate is a compromise between 40 // RTP receiver keyframe-requesting timeout (3s), other backend limitations 41 // and some worst case RTT. 42 static constexpr TimeDelta kZeroHertzIdleRepeatRatePeriod = 43 TimeDelta::Millis(1000); 44 // The number of frame periods to wait for new frames until starting to 45 // request refresh frames. 46 static constexpr int kOnDiscardedFrameRefreshFramePeriod = 3; 47 48 struct ZeroHertzModeParams { 49 // The number of simulcast layers used in this configuration. 50 size_t num_simulcast_layers = 0; 51 }; 52 53 // Callback interface used to inform instance owners. 54 class Callback { 55 public: 56 virtual ~Callback() = default; 57 58 // Called when a frame arrives on the |queue| specified in Create. 59 // 60 // The |post_time| parameter indicates the current time sampled when 61 // FrameCadenceAdapterInterface::OnFrame was called. 62 // 63 // |frames_scheduled_for_processing| indicates how many frames that have 64 // been scheduled for processing. During sequential conditions where 65 // FrameCadenceAdapterInterface::OnFrame is invoked and subsequently ending 66 // up in this callback, this value will read 1. Otherwise if the 67 // |queue| gets stalled for some reason, the value will increase 68 // beyond 1. 69 virtual void OnFrame(Timestamp post_time, 70 int frames_scheduled_for_processing, 71 const VideoFrame& frame) = 0; 72 73 // Called when the source has discarded a frame. 74 virtual void OnDiscardedFrame() = 0; 75 76 // Called when the adapter needs the source to send a refresh frame. 77 virtual void RequestRefreshFrame() = 0; 78 }; 79 80 // Factory function creating a production instance. Deletion of the returned 81 // instance needs to happen on the same sequence that Create() was called on. 82 // Frames arriving in FrameCadenceAdapterInterface::OnFrame are posted to 83 // Callback::OnFrame on the |queue|. 84 static std::unique_ptr<FrameCadenceAdapterInterface> Create( 85 Clock* clock, 86 TaskQueueBase* queue, 87 const FieldTrialsView& field_trials); 88 89 // Call before using the rest of the API. 90 virtual void Initialize(Callback* callback) = 0; 91 92 // Pass zero hertz parameters in |params| as a prerequisite to enable 93 // zero-hertz operation. If absl:::nullopt is passed, the cadence adapter will 94 // switch to passthrough mode. 95 virtual void SetZeroHertzModeEnabled( 96 absl::optional<ZeroHertzModeParams> params) = 0; 97 98 // Returns the input framerate. This is measured by RateStatistics when 99 // zero-hertz mode is off, and returns the max framerate in zero-hertz mode. 100 virtual absl::optional<uint32_t> GetInputFrameRateFps() = 0; 101 102 // Updates frame rate. This is done unconditionally irrespective of adapter 103 // mode. 104 virtual void UpdateFrameRate() = 0; 105 106 // Updates quality convergence status for an enabled spatial layer. 107 // Convergence means QP has dropped to a low-enough level to warrant ceasing 108 // to send identical frames at high frequency. 109 virtual void UpdateLayerQualityConvergence(size_t spatial_index, 110 bool converged) = 0; 111 112 // Updates spatial layer enabled status. 113 virtual void UpdateLayerStatus(size_t spatial_index, bool enabled) = 0; 114 115 // Conditionally requests a refresh frame via 116 // Callback::RequestRefreshFrame. 117 virtual void ProcessKeyFrameRequest() = 0; 118 }; 119 120 } // namespace webrtc 121 122 #endif // VIDEO_FRAME_CADENCE_ADAPTER_H_ 123