blob: 8633c0de39a0963997bb8c7bd80498ac393ea870 [file] [log] [blame]
stefan@webrtc.org9f557c12013-05-17 12:55:07 +00001/*
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
Rasmus Brandtc4d253c2022-05-25 12:03:35 +020011#include "modules/video_coding/timing/timing.h"
Jonas Olssona4d87372019-07-05 19:08:33 +020012
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010013#include "api/units/frequency.h"
14#include "api/units/time_delta.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "system_wrappers/include/clock.h"
16#include "test/gtest.h"
Jonas Orelande02f9ee2022-03-25 12:43:14 +010017#include "test/scoped_key_value_config.h"
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000018
19namespace webrtc {
Åsa Persson8368d1a2018-01-05 12:44:45 +010020namespace {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010021
22constexpr Frequency k25Fps = Frequency::Hertz(25);
23constexpr Frequency k90kHz = Frequency::KiloHertz(90);
24
Åsa Persson8368d1a2018-01-05 12:44:45 +010025} // namespace
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000026
Johannes Kron985905d2021-06-29 11:37:06 +020027TEST(ReceiverTimingTest, JitterDelay) {
Jonas Orelande02f9ee2022-03-25 12:43:14 +010028 test::ScopedKeyValueConfig field_trials;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000029 SimulatedClock clock(0);
Jonas Orelande02f9ee2022-03-25 12:43:14 +010030 VCMTiming timing(&clock, field_trials);
Åsa Persson8368d1a2018-01-05 12:44:45 +010031 timing.Reset();
32
33 uint32_t timestamp = 0;
34 timing.UpdateCurrentDelay(timestamp);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000035
36 timing.Reset();
37
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010038 timing.IncomingTimestamp(timestamp, clock.CurrentTime());
39 TimeDelta jitter_delay = TimeDelta::Millis(20);
40 timing.SetJitterDelay(jitter_delay);
Åsa Persson8368d1a2018-01-05 12:44:45 +010041 timing.UpdateCurrentDelay(timestamp);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010042 timing.set_render_delay(TimeDelta::Zero());
43 auto wait_time = timing.MaxWaitingTime(
44 timing.RenderTime(timestamp, clock.CurrentTime()), clock.CurrentTime(),
45 /*too_many_frames_queued=*/false);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000046 // First update initializes the render time. Since we have no decode delay
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010047 // we get wait_time = renderTime - now - renderDelay = jitter.
48 EXPECT_EQ(jitter_delay, wait_time);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000049
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010050 jitter_delay += TimeDelta::Millis(VCMTiming::kDelayMaxChangeMsPerS + 10);
Åsa Persson8368d1a2018-01-05 12:44:45 +010051 timestamp += 90000;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000052 clock.AdvanceTimeMilliseconds(1000);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010053 timing.SetJitterDelay(jitter_delay);
Åsa Persson8368d1a2018-01-05 12:44:45 +010054 timing.UpdateCurrentDelay(timestamp);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010055 wait_time = timing.MaxWaitingTime(
56 timing.RenderTime(timestamp, clock.CurrentTime()), clock.CurrentTime(),
57 /*too_many_frames_queued=*/false);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000058 // Since we gradually increase the delay we only get 100 ms every second.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010059 EXPECT_EQ(jitter_delay - TimeDelta::Millis(10), wait_time);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000060
Åsa Persson8368d1a2018-01-05 12:44:45 +010061 timestamp += 90000;
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000062 clock.AdvanceTimeMilliseconds(1000);
Åsa Persson8368d1a2018-01-05 12:44:45 +010063 timing.UpdateCurrentDelay(timestamp);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010064 wait_time = timing.MaxWaitingTime(
65 timing.RenderTime(timestamp, clock.CurrentTime()), clock.CurrentTime(),
66 /*too_many_frames_queued=*/false);
67 EXPECT_EQ(jitter_delay, wait_time);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000068
Åsa Persson8368d1a2018-01-05 12:44:45 +010069 // Insert frames without jitter, verify that this gives the exact wait time.
70 const int kNumFrames = 300;
71 for (int i = 0; i < kNumFrames; i++) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010072 clock.AdvanceTime(1 / k25Fps);
73 timestamp += k90kHz / k25Fps;
74 timing.IncomingTimestamp(timestamp, clock.CurrentTime());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000075 }
Åsa Persson8368d1a2018-01-05 12:44:45 +010076 timing.UpdateCurrentDelay(timestamp);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010077 wait_time = timing.MaxWaitingTime(
78 timing.RenderTime(timestamp, clock.CurrentTime()), clock.CurrentTime(),
79 /*too_many_frames_queued=*/false);
80 EXPECT_EQ(jitter_delay, wait_time);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000081
Åsa Persson8368d1a2018-01-05 12:44:45 +010082 // Add decode time estimates for 1 second.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010083 const TimeDelta kDecodeTime = TimeDelta::Millis(10);
84 for (int i = 0; i < k25Fps.hertz(); i++) {
85 clock.AdvanceTime(kDecodeTime);
86 timing.StopDecodeTimer(kDecodeTime, clock.CurrentTime());
87 timestamp += k90kHz / k25Fps;
88 clock.AdvanceTime(1 / k25Fps - kDecodeTime);
89 timing.IncomingTimestamp(timestamp, clock.CurrentTime());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000090 }
Åsa Persson8368d1a2018-01-05 12:44:45 +010091 timing.UpdateCurrentDelay(timestamp);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010092 wait_time = timing.MaxWaitingTime(
93 timing.RenderTime(timestamp, clock.CurrentTime()), clock.CurrentTime(),
94 /*too_many_frames_queued=*/false);
95 EXPECT_EQ(jitter_delay, wait_time);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000096
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010097 const TimeDelta kMinTotalDelay = TimeDelta::Millis(200);
98 timing.set_min_playout_delay(kMinTotalDelay);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +000099 clock.AdvanceTimeMilliseconds(5000);
Åsa Persson8368d1a2018-01-05 12:44:45 +0100100 timestamp += 5 * 90000;
101 timing.UpdateCurrentDelay(timestamp);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100102 const TimeDelta kRenderDelay = TimeDelta::Millis(10);
103 timing.set_render_delay(kRenderDelay);
104 wait_time = timing.MaxWaitingTime(
105 timing.RenderTime(timestamp, clock.CurrentTime()), clock.CurrentTime(),
106 /*too_many_frames_queued=*/false);
Åsa Persson8368d1a2018-01-05 12:44:45 +0100107 // We should at least have kMinTotalDelayMs - decodeTime (10) - renderTime
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000108 // (10) to wait.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100109 EXPECT_EQ(kMinTotalDelay - kDecodeTime - kRenderDelay, wait_time);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000110 // The total video delay should be equal to the min total delay.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100111 EXPECT_EQ(kMinTotalDelay, timing.TargetVideoDelay());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000112
mikhal@webrtc.orgadc64a72013-05-30 16:20:18 +0000113 // Reset playout delay.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100114 timing.set_min_playout_delay(TimeDelta::Zero());
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000115 clock.AdvanceTimeMilliseconds(5000);
Åsa Persson8368d1a2018-01-05 12:44:45 +0100116 timestamp += 5 * 90000;
117 timing.UpdateCurrentDelay(timestamp);
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000118}
119
Johannes Kron985905d2021-06-29 11:37:06 +0200120TEST(ReceiverTimingTest, TimestampWrapAround) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100121 constexpr auto kStartTime = Timestamp::Millis(1337);
Jonas Orelande02f9ee2022-03-25 12:43:14 +0100122 test::ScopedKeyValueConfig field_trials;
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100123 SimulatedClock clock(kStartTime);
Jonas Orelande02f9ee2022-03-25 12:43:14 +0100124 VCMTiming timing(&clock, field_trials);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100125
Åsa Persson8368d1a2018-01-05 12:44:45 +0100126 // Provoke a wrap-around. The fifth frame will have wrapped at 25 fps.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100127 constexpr uint32_t kRtpTicksPerFrame = k90kHz / k25Fps;
128 uint32_t timestamp = 0xFFFFFFFFu - 3 * kRtpTicksPerFrame;
Åsa Persson8368d1a2018-01-05 12:44:45 +0100129 for (int i = 0; i < 5; ++i) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100130 timing.IncomingTimestamp(timestamp, clock.CurrentTime());
131 clock.AdvanceTime(1 / k25Fps);
132 timestamp += kRtpTicksPerFrame;
133 EXPECT_EQ(kStartTime + 3 / k25Fps,
134 timing.RenderTime(0xFFFFFFFFu, clock.CurrentTime()));
135 // One ms later in 90 kHz.
136 EXPECT_EQ(kStartTime + 3 / k25Fps + TimeDelta::Millis(1),
137 timing.RenderTime(89u, clock.CurrentTime()));
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000138 }
139}
140
Johannes Kronbbf639e2022-06-15 12:27:23 +0200141TEST(ReceiverTimingTest, UseLowLatencyRenderer) {
142 test::ScopedKeyValueConfig field_trials;
143 SimulatedClock clock(0);
144 VCMTiming timing(&clock, field_trials);
145 timing.Reset();
146 // Default is false.
147 EXPECT_FALSE(timing.RenderParameters().use_low_latency_rendering);
148 // False if min playout delay > 0.
149 timing.set_min_playout_delay(TimeDelta::Millis(10));
150 timing.set_max_playout_delay(TimeDelta::Millis(20));
151 EXPECT_FALSE(timing.RenderParameters().use_low_latency_rendering);
152 // True if min==0, max > 0.
Philipp Hanckea204ad22022-07-08 18:43:25 +0200153 timing.set_min_playout_delay(TimeDelta::Zero());
Johannes Kronbbf639e2022-06-15 12:27:23 +0200154 EXPECT_TRUE(timing.RenderParameters().use_low_latency_rendering);
155 // True if min==max==0.
Philipp Hanckea204ad22022-07-08 18:43:25 +0200156 timing.set_max_playout_delay(TimeDelta::Zero());
Johannes Kronbbf639e2022-06-15 12:27:23 +0200157 EXPECT_TRUE(timing.RenderParameters().use_low_latency_rendering);
158 // True also for max playout delay==500 ms.
159 timing.set_max_playout_delay(TimeDelta::Millis(500));
160 EXPECT_TRUE(timing.RenderParameters().use_low_latency_rendering);
161 // False if max playout delay > 500 ms.
162 timing.set_max_playout_delay(TimeDelta::Millis(501));
163 EXPECT_FALSE(timing.RenderParameters().use_low_latency_rendering);
164}
165
Johannes Kron985905d2021-06-29 11:37:06 +0200166TEST(ReceiverTimingTest, MaxWaitingTimeIsZeroForZeroRenderTime) {
167 // This is the default path when the RTP playout delay header extension is set
Johannes Kron23bfff32021-09-28 21:31:46 +0200168 // to min==0 and max==0.
Johannes Kron985905d2021-06-29 11:37:06 +0200169 constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100170 constexpr TimeDelta kTimeDelta = 1 / Frequency::Hertz(60);
171 constexpr Timestamp kZeroRenderTime = Timestamp::Zero();
Johannes Kron985905d2021-06-29 11:37:06 +0200172 SimulatedClock clock(kStartTimeUs);
Jonas Orelande02f9ee2022-03-25 12:43:14 +0100173 test::ScopedKeyValueConfig field_trials;
174 VCMTiming timing(&clock, field_trials);
Johannes Kron985905d2021-06-29 11:37:06 +0200175 timing.Reset();
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100176 timing.set_max_playout_delay(TimeDelta::Zero());
Johannes Kron985905d2021-06-29 11:37:06 +0200177 for (int i = 0; i < 10; ++i) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100178 clock.AdvanceTime(kTimeDelta);
179 Timestamp now = clock.CurrentTime();
180 EXPECT_LT(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200181 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100182 TimeDelta::Zero());
Johannes Kron985905d2021-06-29 11:37:06 +0200183 }
184 // Another frame submitted at the same time also returns a negative max
185 // waiting time.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100186 Timestamp now = clock.CurrentTime();
187 EXPECT_LT(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200188 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100189 TimeDelta::Zero());
Johannes Kron985905d2021-06-29 11:37:06 +0200190 // MaxWaitingTime should be less than zero even if there's a burst of frames.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100191 EXPECT_LT(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200192 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100193 TimeDelta::Zero());
194 EXPECT_LT(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200195 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100196 TimeDelta::Zero());
197 EXPECT_LT(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200198 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100199 TimeDelta::Zero());
Johannes Kron985905d2021-06-29 11:37:06 +0200200}
201
202TEST(ReceiverTimingTest, MaxWaitingTimeZeroDelayPacingExperiment) {
203 // The minimum pacing is enabled by a field trial and active if the RTP
204 // playout delay header extension is set to min==0.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100205 constexpr TimeDelta kMinPacing = TimeDelta::Millis(3);
Jonas Orelande02f9ee2022-03-25 12:43:14 +0100206 test::ScopedKeyValueConfig field_trials(
Johannes Kron985905d2021-06-29 11:37:06 +0200207 "WebRTC-ZeroPlayoutDelay/min_pacing:3ms/");
208 constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100209 constexpr TimeDelta kTimeDelta = 1 / Frequency::Hertz(60);
210 constexpr auto kZeroRenderTime = Timestamp::Zero();
Johannes Kron985905d2021-06-29 11:37:06 +0200211 SimulatedClock clock(kStartTimeUs);
Jonas Orelande02f9ee2022-03-25 12:43:14 +0100212 VCMTiming timing(&clock, field_trials);
Johannes Kron985905d2021-06-29 11:37:06 +0200213 timing.Reset();
214 // MaxWaitingTime() returns zero for evenly spaced video frames.
215 for (int i = 0; i < 10; ++i) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100216 clock.AdvanceTime(kTimeDelta);
217 Timestamp now = clock.CurrentTime();
218 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200219 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100220 TimeDelta::Zero());
221 timing.SetLastDecodeScheduledTimestamp(now);
Johannes Kron985905d2021-06-29 11:37:06 +0200222 }
223 // Another frame submitted at the same time is paced according to the field
224 // trial setting.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100225 auto now = clock.CurrentTime();
226 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200227 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100228 kMinPacing);
Rezaul Barbhuiya82c22482021-08-05 17:54:11 -0700229 // If there's a burst of frames, the wait time is calculated based on next
230 // decode time.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100231 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200232 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100233 kMinPacing);
234 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200235 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100236 kMinPacing);
Johannes Kron985905d2021-06-29 11:37:06 +0200237 // Allow a few ms to pass, this should be subtracted from the MaxWaitingTime.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100238 constexpr TimeDelta kTwoMs = TimeDelta::Millis(2);
239 clock.AdvanceTime(kTwoMs);
240 now = clock.CurrentTime();
241 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200242 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100243 kMinPacing - kTwoMs);
Rezaul Barbhuiya82c22482021-08-05 17:54:11 -0700244 // A frame is decoded at the current time, the wait time should be restored to
245 // pacing delay.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100246 timing.SetLastDecodeScheduledTimestamp(now);
247 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200248 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100249 kMinPacing);
Johannes Kron985905d2021-06-29 11:37:06 +0200250}
251
252TEST(ReceiverTimingTest, DefaultMaxWaitingTimeUnaffectedByPacingExperiment) {
253 // The minimum pacing is enabled by a field trial but should not have any
254 // effect if render_time_ms is greater than 0;
Jonas Orelande02f9ee2022-03-25 12:43:14 +0100255 test::ScopedKeyValueConfig field_trials(
Johannes Kron985905d2021-06-29 11:37:06 +0200256 "WebRTC-ZeroPlayoutDelay/min_pacing:3ms/");
257 constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100258 const TimeDelta kTimeDelta = TimeDelta::Millis(1000.0 / 60.0);
Johannes Kron985905d2021-06-29 11:37:06 +0200259 SimulatedClock clock(kStartTimeUs);
Jonas Orelande02f9ee2022-03-25 12:43:14 +0100260 VCMTiming timing(&clock, field_trials);
Johannes Kron985905d2021-06-29 11:37:06 +0200261 timing.Reset();
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100262 clock.AdvanceTime(kTimeDelta);
263 auto now = clock.CurrentTime();
264 Timestamp render_time = now + TimeDelta::Millis(30);
Johannes Kron985905d2021-06-29 11:37:06 +0200265 // Estimate the internal processing delay from the first frame.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100266 TimeDelta estimated_processing_delay =
267 (render_time - now) -
268 timing.MaxWaitingTime(render_time, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200269 /*too_many_frames_queued=*/false);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100270 EXPECT_GT(estimated_processing_delay, TimeDelta::Zero());
Johannes Kron985905d2021-06-29 11:37:06 +0200271
272 // Any other frame submitted at the same time should be scheduled according to
273 // its render time.
274 for (int i = 0; i < 5; ++i) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100275 render_time += kTimeDelta;
276 EXPECT_EQ(timing.MaxWaitingTime(render_time, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200277 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100278 render_time - now - estimated_processing_delay);
Johannes Kron985905d2021-06-29 11:37:06 +0200279 }
280}
281
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100282TEST(ReceiverTimingTest, MaxWaitingTimeReturnsZeroIfTooManyFramesQueuedIsTrue) {
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200283 // The minimum pacing is enabled by a field trial and active if the RTP
284 // playout delay header extension is set to min==0.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100285 constexpr TimeDelta kMinPacing = TimeDelta::Millis(3);
Jonas Orelande02f9ee2022-03-25 12:43:14 +0100286 test::ScopedKeyValueConfig field_trials(
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200287 "WebRTC-ZeroPlayoutDelay/min_pacing:3ms/");
288 constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100289 const TimeDelta kTimeDelta = TimeDelta::Millis(1000.0 / 60.0);
290 constexpr auto kZeroRenderTime = Timestamp::Zero();
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200291 SimulatedClock clock(kStartTimeUs);
Jonas Orelande02f9ee2022-03-25 12:43:14 +0100292 VCMTiming timing(&clock, field_trials);
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200293 timing.Reset();
294 // MaxWaitingTime() returns zero for evenly spaced video frames.
295 for (int i = 0; i < 10; ++i) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100296 clock.AdvanceTime(kTimeDelta);
297 auto now = clock.CurrentTime();
298 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200299 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100300 TimeDelta::Zero());
301 timing.SetLastDecodeScheduledTimestamp(now);
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200302 }
303 // Another frame submitted at the same time is paced according to the field
304 // trial setting.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100305 auto now_ms = clock.CurrentTime();
306 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now_ms,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200307 /*too_many_frames_queued=*/false),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100308 kMinPacing);
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200309 // MaxWaitingTime returns 0 even if there's a burst of frames if
310 // too_many_frames_queued is set to true.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100311 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now_ms,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200312 /*too_many_frames_queued=*/true),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100313 TimeDelta::Zero());
314 EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTime, now_ms,
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200315 /*too_many_frames_queued=*/true),
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100316 TimeDelta::Zero());
Johannes Kron2ddc39e2021-08-10 16:56:12 +0200317}
318
Evan Shrubsole496ad522022-08-01 15:03:23 +0000319TEST(ReceiverTimingTest, UpdateCurrentDelayCapsWhenOffByMicroseconds) {
320 test::ScopedKeyValueConfig field_trials;
321 SimulatedClock clock(0);
322 VCMTiming timing(&clock, field_trials);
323 timing.Reset();
324
325 // Set larger initial current delay.
326 timing.set_min_playout_delay(TimeDelta::Millis(200));
327 timing.UpdateCurrentDelay(Timestamp::Millis(900), Timestamp::Millis(1000));
328
329 // Add a few microseconds to ensure that the delta of decode time is 0 after
330 // rounding, and should reset to the target delay.
331 timing.set_min_playout_delay(TimeDelta::Millis(50));
332 Timestamp decode_time = Timestamp::Millis(1337);
333 Timestamp render_time =
334 decode_time + TimeDelta::Millis(10) + TimeDelta::Micros(37);
335 timing.UpdateCurrentDelay(render_time, decode_time);
336 EXPECT_EQ(timing.GetTimings().current_delay, timing.TargetVideoDelay());
337}
338
stefan@webrtc.org9f557c12013-05-17 12:55:07 +0000339} // namespace webrtc