xref: /aosp_15_r20/external/webrtc/modules/video_coding/timing/inter_frame_delay.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 #include "modules/video_coding/timing/inter_frame_delay.h"
12 
13 #include "absl/types/optional.h"
14 #include "api/units/frequency.h"
15 #include "api/units/time_delta.h"
16 #include "modules/include/module_common_types_public.h"
17 
18 namespace webrtc {
19 
20 namespace {
21 constexpr Frequency k90kHz = Frequency::KiloHertz(90);
22 }
23 
InterFrameDelay()24 InterFrameDelay::InterFrameDelay() {
25   Reset();
26 }
27 
28 // Resets the delay estimate.
Reset()29 void InterFrameDelay::Reset() {
30   prev_wall_clock_ = absl::nullopt;
31   prev_rtp_timestamp_unwrapped_ = 0;
32 }
33 
34 // Calculates the delay of a frame with the given timestamp.
35 // This method is called when the frame is complete.
CalculateDelay(uint32_t rtp_timestamp,Timestamp now)36 absl::optional<TimeDelta> InterFrameDelay::CalculateDelay(
37     uint32_t rtp_timestamp,
38     Timestamp now) {
39   int64_t rtp_timestamp_unwrapped = unwrapper_.Unwrap(rtp_timestamp);
40   if (!prev_wall_clock_) {
41     // First set of data, initialization, wait for next frame.
42     prev_wall_clock_ = now;
43     prev_rtp_timestamp_unwrapped_ = rtp_timestamp_unwrapped;
44     return TimeDelta::Zero();
45   }
46 
47   // Account for reordering in jitter variance estimate in the future?
48   // Note that this also captures incomplete frames which are grabbed for
49   // decoding after a later frame has been complete, i.e. real packet losses.
50   uint32_t cropped_last = static_cast<uint32_t>(prev_rtp_timestamp_unwrapped_);
51   if (rtp_timestamp_unwrapped < prev_rtp_timestamp_unwrapped_ ||
52       !IsNewerTimestamp(rtp_timestamp, cropped_last)) {
53     return absl::nullopt;
54   }
55 
56   // Compute the compensated timestamp difference.
57   int64_t d_rtp_ticks = rtp_timestamp_unwrapped - prev_rtp_timestamp_unwrapped_;
58   TimeDelta dts = d_rtp_ticks / k90kHz;
59   TimeDelta dt = now - *prev_wall_clock_;
60 
61   // frameDelay is the difference of dT and dTS -- i.e. the difference of the
62   // wall clock time difference and the timestamp difference between two
63   // following frames.
64   TimeDelta delay = dt - dts;
65 
66   prev_rtp_timestamp_unwrapped_ = rtp_timestamp_unwrapped;
67   prev_wall_clock_ = now;
68   return delay;
69 }
70 
71 }  // namespace webrtc
72