1 /*
2  *  Copyright (c) 2011 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 MODULES_VIDEO_CODING_TIMING_H_
12 #define MODULES_VIDEO_CODING_TIMING_H_
13 
14 #include <memory>
15 
16 #include "absl/types/optional.h"
17 #include "api/video/video_timing.h"
18 #include "modules/video_coding/codec_timer.h"
19 #include "rtc_base/synchronization/mutex.h"
20 #include "rtc_base/thread_annotations.h"
21 
22 namespace webrtc {
23 
24 class Clock;
25 class TimestampExtrapolator;
26 
27 class VCMTiming {
28  public:
29   // The primary timing component should be passed
30   // if this is the dual timing component.
31   explicit VCMTiming(Clock* clock, VCMTiming* master_timing = NULL);
32   virtual ~VCMTiming();
33 
34   // Resets the timing to the initial state.
35   void Reset();
36 
37   // Set the amount of time needed to render an image. Defaults to 10 ms.
38   void set_render_delay(int render_delay_ms);
39 
40   // Set the minimum time the video must be delayed on the receiver to
41   // get the desired jitter buffer level.
42   void SetJitterDelay(int required_delay_ms);
43 
44   // Set/get the minimum playout delay from capture to render in ms.
45   void set_min_playout_delay(int min_playout_delay_ms);
46   int min_playout_delay();
47 
48   // Set/get the maximum playout delay from capture to render in ms.
49   void set_max_playout_delay(int max_playout_delay_ms);
50   int max_playout_delay();
51 
52   // Increases or decreases the current delay to get closer to the target delay.
53   // Calculates how long it has been since the previous call to this function,
54   // and increases/decreases the delay in proportion to the time difference.
55   void UpdateCurrentDelay(uint32_t frame_timestamp);
56 
57   // Increases or decreases the current delay to get closer to the target delay.
58   // Given the actual decode time in ms and the render time in ms for a frame,
59   // this function calculates how late the frame is and increases the delay
60   // accordingly.
61   void UpdateCurrentDelay(int64_t render_time_ms,
62                           int64_t actual_decode_time_ms);
63 
64   // Stops the decoder timer, should be called when the decoder returns a frame
65   // or when the decoded frame callback is called.
66   void StopDecodeTimer(int32_t decode_time_ms, int64_t now_ms);
67   // TODO(kron): Remove once downstream projects has been changed to use the
68   // above function.
69   void StopDecodeTimer(uint32_t time_stamp,
70                        int32_t decode_time_ms,
71                        int64_t now_ms,
72                        int64_t render_time_ms);
73 
74   // Used to report that a frame is passed to decoding. Updates the timestamp
75   // filter which is used to map between timestamps and receiver system time.
76   void IncomingTimestamp(uint32_t time_stamp, int64_t last_packet_time_ms);
77 
78   // Returns the receiver system time when the frame with timestamp
79   // |frame_timestamp| should be rendered, assuming that the system time
80   // currently is |now_ms|.
81   virtual int64_t RenderTimeMs(uint32_t frame_timestamp, int64_t now_ms) const;
82 
83   // Returns the maximum time in ms that we can wait for a frame to become
84   // complete before we must pass it to the decoder.
85   virtual int64_t MaxWaitingTime(int64_t render_time_ms, int64_t now_ms) const;
86 
87   // Returns the current target delay which is required delay + decode time +
88   // render delay.
89   int TargetVideoDelay() const;
90 
91   // Return current timing information. Returns true if the first frame has been
92   // decoded, false otherwise.
93   virtual bool GetTimings(int* max_decode_ms,
94                           int* current_delay_ms,
95                           int* target_delay_ms,
96                           int* jitter_buffer_ms,
97                           int* min_playout_delay_ms,
98                           int* render_delay_ms) const;
99 
100   void SetTimingFrameInfo(const TimingFrameInfo& info);
101   absl::optional<TimingFrameInfo> GetTimingFrameInfo();
102 
103   enum { kDefaultRenderDelayMs = 10 };
104   enum { kDelayMaxChangeMsPerS = 100 };
105 
106  protected:
107   int RequiredDecodeTimeMs() const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
108   int64_t RenderTimeMsInternal(uint32_t frame_timestamp, int64_t now_ms) const
109       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
110   int TargetDelayInternal() const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
111 
112  private:
113   mutable Mutex mutex_;
114   Clock* const clock_;
115   bool master_ RTC_GUARDED_BY(mutex_);
116   TimestampExtrapolator* ts_extrapolator_ RTC_GUARDED_BY(mutex_);
117   std::unique_ptr<VCMCodecTimer> codec_timer_ RTC_GUARDED_BY(mutex_);
118   int render_delay_ms_ RTC_GUARDED_BY(mutex_);
119   // Best-effort playout delay range for frames from capture to render.
120   // The receiver tries to keep the delay between |min_playout_delay_ms_|
121   // and |max_playout_delay_ms_| taking the network jitter into account.
122   // A special case is where min_playout_delay_ms_ = max_playout_delay_ms_ = 0,
123   // in which case the receiver tries to play the frames as they arrive.
124   int min_playout_delay_ms_ RTC_GUARDED_BY(mutex_);
125   int max_playout_delay_ms_ RTC_GUARDED_BY(mutex_);
126   int jitter_delay_ms_ RTC_GUARDED_BY(mutex_);
127   int current_delay_ms_ RTC_GUARDED_BY(mutex_);
128   uint32_t prev_frame_timestamp_ RTC_GUARDED_BY(mutex_);
129   absl::optional<TimingFrameInfo> timing_frame_info_ RTC_GUARDED_BY(mutex_);
130   size_t num_decoded_frames_ RTC_GUARDED_BY(mutex_);
131 };
132 }  // namespace webrtc
133 
134 #endif  // MODULES_VIDEO_CODING_TIMING_H_
135