1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2011 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 MODULES_VIDEO_CODING_TIMING_TIMING_H_ 12*d9f75844SAndroid Build Coastguard Worker #define MODULES_VIDEO_CODING_TIMING_TIMING_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/types/optional.h" 17*d9f75844SAndroid Build Coastguard Worker #include "api/field_trials_view.h" 18*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h" 19*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_frame.h" 20*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_timing.h" 21*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/timing/codec_timer.h" 22*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/timing/timestamp_extrapolator.h" 23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/experiments/field_trial_parser.h" 24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h" 25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h" 26*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h" 27*d9f75844SAndroid Build Coastguard Worker 28*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 29*d9f75844SAndroid Build Coastguard Worker 30*d9f75844SAndroid Build Coastguard Worker class VCMTiming { 31*d9f75844SAndroid Build Coastguard Worker public: 32*d9f75844SAndroid Build Coastguard Worker static constexpr auto kDefaultRenderDelay = TimeDelta::Millis(10); 33*d9f75844SAndroid Build Coastguard Worker static constexpr auto kDelayMaxChangeMsPerS = 100; 34*d9f75844SAndroid Build Coastguard Worker 35*d9f75844SAndroid Build Coastguard Worker VCMTiming(Clock* clock, const FieldTrialsView& field_trials); 36*d9f75844SAndroid Build Coastguard Worker virtual ~VCMTiming() = default; 37*d9f75844SAndroid Build Coastguard Worker 38*d9f75844SAndroid Build Coastguard Worker // Resets the timing to the initial state. 39*d9f75844SAndroid Build Coastguard Worker void Reset(); 40*d9f75844SAndroid Build Coastguard Worker 41*d9f75844SAndroid Build Coastguard Worker // Set the amount of time needed to render an image. Defaults to 10 ms. 42*d9f75844SAndroid Build Coastguard Worker void set_render_delay(TimeDelta render_delay); 43*d9f75844SAndroid Build Coastguard Worker 44*d9f75844SAndroid Build Coastguard Worker // Set the minimum time the video must be delayed on the receiver to 45*d9f75844SAndroid Build Coastguard Worker // get the desired jitter buffer level. 46*d9f75844SAndroid Build Coastguard Worker void SetJitterDelay(TimeDelta required_delay); 47*d9f75844SAndroid Build Coastguard Worker 48*d9f75844SAndroid Build Coastguard Worker // Set/get the minimum playout delay from capture to render. 49*d9f75844SAndroid Build Coastguard Worker TimeDelta min_playout_delay() const; 50*d9f75844SAndroid Build Coastguard Worker void set_min_playout_delay(TimeDelta min_playout_delay); 51*d9f75844SAndroid Build Coastguard Worker 52*d9f75844SAndroid Build Coastguard Worker // Set/get the maximum playout delay from capture to render in ms. 53*d9f75844SAndroid Build Coastguard Worker void set_max_playout_delay(TimeDelta max_playout_delay); 54*d9f75844SAndroid Build Coastguard Worker 55*d9f75844SAndroid Build Coastguard Worker // Increases or decreases the current delay to get closer to the target delay. 56*d9f75844SAndroid Build Coastguard Worker // Calculates how long it has been since the previous call to this function, 57*d9f75844SAndroid Build Coastguard Worker // and increases/decreases the delay in proportion to the time difference. 58*d9f75844SAndroid Build Coastguard Worker void UpdateCurrentDelay(uint32_t frame_timestamp); 59*d9f75844SAndroid Build Coastguard Worker 60*d9f75844SAndroid Build Coastguard Worker // Increases or decreases the current delay to get closer to the target delay. 61*d9f75844SAndroid Build Coastguard Worker // Given the actual decode time in ms and the render time in ms for a frame, 62*d9f75844SAndroid Build Coastguard Worker // this function calculates how late the frame is and increases the delay 63*d9f75844SAndroid Build Coastguard Worker // accordingly. 64*d9f75844SAndroid Build Coastguard Worker void UpdateCurrentDelay(Timestamp render_time, Timestamp actual_decode_time); 65*d9f75844SAndroid Build Coastguard Worker 66*d9f75844SAndroid Build Coastguard Worker // Stops the decoder timer, should be called when the decoder returns a frame 67*d9f75844SAndroid Build Coastguard Worker // or when the decoded frame callback is called. 68*d9f75844SAndroid Build Coastguard Worker void StopDecodeTimer(TimeDelta decode_time, Timestamp now); 69*d9f75844SAndroid Build Coastguard Worker 70*d9f75844SAndroid Build Coastguard Worker // Used to report that a frame is passed to decoding. Updates the timestamp 71*d9f75844SAndroid Build Coastguard Worker // filter which is used to map between timestamps and receiver system time. 72*d9f75844SAndroid Build Coastguard Worker virtual void IncomingTimestamp(uint32_t rtp_timestamp, 73*d9f75844SAndroid Build Coastguard Worker Timestamp last_packet_time); 74*d9f75844SAndroid Build Coastguard Worker 75*d9f75844SAndroid Build Coastguard Worker // Returns the receiver system time when the frame with timestamp 76*d9f75844SAndroid Build Coastguard Worker // `frame_timestamp` should be rendered, assuming that the system time 77*d9f75844SAndroid Build Coastguard Worker // currently is `now`. 78*d9f75844SAndroid Build Coastguard Worker virtual Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const; 79*d9f75844SAndroid Build Coastguard Worker 80*d9f75844SAndroid Build Coastguard Worker // Returns the maximum time in ms that we can wait for a frame to become 81*d9f75844SAndroid Build Coastguard Worker // complete before we must pass it to the decoder. render_time==0 indicates 82*d9f75844SAndroid Build Coastguard Worker // that the frames should be processed as quickly as possible, with possibly 83*d9f75844SAndroid Build Coastguard Worker // only a small delay added to make sure that the decoder is not overloaded. 84*d9f75844SAndroid Build Coastguard Worker // In this case, the parameter too_many_frames_queued is used to signal that 85*d9f75844SAndroid Build Coastguard Worker // the decode queue is full and that the frame should be decoded as soon as 86*d9f75844SAndroid Build Coastguard Worker // possible. 87*d9f75844SAndroid Build Coastguard Worker virtual TimeDelta MaxWaitingTime(Timestamp render_time, 88*d9f75844SAndroid Build Coastguard Worker Timestamp now, 89*d9f75844SAndroid Build Coastguard Worker bool too_many_frames_queued) const; 90*d9f75844SAndroid Build Coastguard Worker 91*d9f75844SAndroid Build Coastguard Worker // Returns the current target delay which is required delay + decode time + 92*d9f75844SAndroid Build Coastguard Worker // render delay. 93*d9f75844SAndroid Build Coastguard Worker TimeDelta TargetVideoDelay() const; 94*d9f75844SAndroid Build Coastguard Worker 95*d9f75844SAndroid Build Coastguard Worker // Return current timing information. Returns true if the first frame has been 96*d9f75844SAndroid Build Coastguard Worker // decoded, false otherwise. 97*d9f75844SAndroid Build Coastguard Worker struct VideoDelayTimings { 98*d9f75844SAndroid Build Coastguard Worker TimeDelta max_decode_duration; 99*d9f75844SAndroid Build Coastguard Worker TimeDelta current_delay; 100*d9f75844SAndroid Build Coastguard Worker TimeDelta target_delay; 101*d9f75844SAndroid Build Coastguard Worker TimeDelta jitter_buffer_delay; 102*d9f75844SAndroid Build Coastguard Worker TimeDelta min_playout_delay; 103*d9f75844SAndroid Build Coastguard Worker TimeDelta max_playout_delay; 104*d9f75844SAndroid Build Coastguard Worker TimeDelta render_delay; 105*d9f75844SAndroid Build Coastguard Worker size_t num_decoded_frames; 106*d9f75844SAndroid Build Coastguard Worker }; 107*d9f75844SAndroid Build Coastguard Worker VideoDelayTimings GetTimings() const; 108*d9f75844SAndroid Build Coastguard Worker 109*d9f75844SAndroid Build Coastguard Worker void SetTimingFrameInfo(const TimingFrameInfo& info); 110*d9f75844SAndroid Build Coastguard Worker absl::optional<TimingFrameInfo> GetTimingFrameInfo(); 111*d9f75844SAndroid Build Coastguard Worker 112*d9f75844SAndroid Build Coastguard Worker void SetMaxCompositionDelayInFrames( 113*d9f75844SAndroid Build Coastguard Worker absl::optional<int> max_composition_delay_in_frames); 114*d9f75844SAndroid Build Coastguard Worker 115*d9f75844SAndroid Build Coastguard Worker VideoFrame::RenderParameters RenderParameters() const; 116*d9f75844SAndroid Build Coastguard Worker 117*d9f75844SAndroid Build Coastguard Worker // Updates the last time a frame was scheduled for decoding. 118*d9f75844SAndroid Build Coastguard Worker void SetLastDecodeScheduledTimestamp(Timestamp last_decode_scheduled); 119*d9f75844SAndroid Build Coastguard Worker 120*d9f75844SAndroid Build Coastguard Worker protected: 121*d9f75844SAndroid Build Coastguard Worker TimeDelta RequiredDecodeTime() const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 122*d9f75844SAndroid Build Coastguard Worker Timestamp RenderTimeInternal(uint32_t frame_timestamp, Timestamp now) const 123*d9f75844SAndroid Build Coastguard Worker RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 124*d9f75844SAndroid Build Coastguard Worker TimeDelta TargetDelayInternal() const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 125*d9f75844SAndroid Build Coastguard Worker bool UseLowLatencyRendering() const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 126*d9f75844SAndroid Build Coastguard Worker 127*d9f75844SAndroid Build Coastguard Worker private: 128*d9f75844SAndroid Build Coastguard Worker mutable Mutex mutex_; 129*d9f75844SAndroid Build Coastguard Worker Clock* const clock_; 130*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<TimestampExtrapolator> ts_extrapolator_ 131*d9f75844SAndroid Build Coastguard Worker RTC_PT_GUARDED_BY(mutex_); 132*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<CodecTimer> codec_timer_ RTC_GUARDED_BY(mutex_) 133*d9f75844SAndroid Build Coastguard Worker RTC_PT_GUARDED_BY(mutex_); 134*d9f75844SAndroid Build Coastguard Worker TimeDelta render_delay_ RTC_GUARDED_BY(mutex_); 135*d9f75844SAndroid Build Coastguard Worker // Best-effort playout delay range for frames from capture to render. 136*d9f75844SAndroid Build Coastguard Worker // The receiver tries to keep the delay between `min_playout_delay_ms_` 137*d9f75844SAndroid Build Coastguard Worker // and `max_playout_delay_ms_` taking the network jitter into account. 138*d9f75844SAndroid Build Coastguard Worker // A special case is where min_playout_delay_ms_ = max_playout_delay_ms_ = 0, 139*d9f75844SAndroid Build Coastguard Worker // in which case the receiver tries to play the frames as they arrive. 140*d9f75844SAndroid Build Coastguard Worker TimeDelta min_playout_delay_ RTC_GUARDED_BY(mutex_); 141*d9f75844SAndroid Build Coastguard Worker TimeDelta max_playout_delay_ RTC_GUARDED_BY(mutex_); 142*d9f75844SAndroid Build Coastguard Worker TimeDelta jitter_delay_ RTC_GUARDED_BY(mutex_); 143*d9f75844SAndroid Build Coastguard Worker TimeDelta current_delay_ RTC_GUARDED_BY(mutex_); 144*d9f75844SAndroid Build Coastguard Worker uint32_t prev_frame_timestamp_ RTC_GUARDED_BY(mutex_); 145*d9f75844SAndroid Build Coastguard Worker absl::optional<TimingFrameInfo> timing_frame_info_ RTC_GUARDED_BY(mutex_); 146*d9f75844SAndroid Build Coastguard Worker size_t num_decoded_frames_ RTC_GUARDED_BY(mutex_); 147*d9f75844SAndroid Build Coastguard Worker absl::optional<int> max_composition_delay_in_frames_ RTC_GUARDED_BY(mutex_); 148*d9f75844SAndroid Build Coastguard Worker // Set by the field trial WebRTC-ZeroPlayoutDelay. The parameter min_pacing 149*d9f75844SAndroid Build Coastguard Worker // determines the minimum delay between frames scheduled for decoding that is 150*d9f75844SAndroid Build Coastguard Worker // used when min playout delay=0 and max playout delay>=0. 151*d9f75844SAndroid Build Coastguard Worker FieldTrialParameter<TimeDelta> zero_playout_delay_min_pacing_ 152*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(mutex_); 153*d9f75844SAndroid Build Coastguard Worker // Timestamp at which the last frame was scheduled to be sent to the decoder. 154*d9f75844SAndroid Build Coastguard Worker // Used only when the RTP header extension playout delay is set to min=0 ms 155*d9f75844SAndroid Build Coastguard Worker // which is indicated by a render time set to 0. 156*d9f75844SAndroid Build Coastguard Worker Timestamp last_decode_scheduled_ RTC_GUARDED_BY(mutex_); 157*d9f75844SAndroid Build Coastguard Worker }; 158*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 159*d9f75844SAndroid Build Coastguard Worker 160*d9f75844SAndroid Build Coastguard Worker #endif // MODULES_VIDEO_CODING_TIMING_TIMING_H_ 161