xref: /aosp_15_r20/external/webrtc/modules/video_coding/timing/timing.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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