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