blob: f9ae37d0bb69fe148c14421164f1a176e2497ac3 [file] [log] [blame]
stefan@webrtc.org5f284982012-06-28 07:51:16 +00001/*
2 * Copyright (c) 2012 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
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000011#include <math.h>
stefan@webrtc.org5f284982012-06-28 07:51:16 +000012
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010013#include <algorithm>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "test/gtest.h"
16#include "video/stream_synchronization.h"
stefan@webrtc.org5f284982012-06-28 07:51:16 +000017
18namespace webrtc {
19
20// These correspond to the same constants defined in vie_sync_module.cc.
21enum { kMaxVideoDiffMs = 80 };
22enum { kMaxAudioDiffMs = 80 };
23enum { kMaxDelay = 1500 };
24
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000025// Test constants.
26enum { kDefaultAudioFrequency = 8000 };
27enum { kDefaultVideoFrequency = 90000 };
28const double kNtpFracPerMs = 4.294967296E6;
pwestin@webrtc.org63117332013-04-22 18:57:14 +000029static const int kSmoothingFilter = 4 * 2;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000030
stefan@webrtc.org5f284982012-06-28 07:51:16 +000031class Time {
32 public:
33 explicit Time(int64_t offset)
34 : kNtpJan1970(2208988800UL),
35 time_now_ms_(offset) {}
36
asaperssonb7e7b492016-11-17 02:27:14 -080037 NtpTime GetNowNtp() const {
38 uint32_t ntp_secs = time_now_ms_ / 1000 + kNtpJan1970;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000039 int64_t remainder_ms = time_now_ms_ % 1000;
asaperssonb7e7b492016-11-17 02:27:14 -080040 uint32_t ntp_frac = static_cast<uint32_t>(
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000041 static_cast<double>(remainder_ms) * kNtpFracPerMs + 0.5);
asaperssonb7e7b492016-11-17 02:27:14 -080042 return NtpTime(ntp_secs, ntp_frac);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000043 }
44
asaperssonb7e7b492016-11-17 02:27:14 -080045 uint32_t GetNowRtp(int frequency, uint32_t offset) const {
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000046 return frequency * time_now_ms_ / 1000 + offset;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000047 }
48
49 void IncreaseTimeMs(int64_t inc) {
50 time_now_ms_ += inc;
51 }
52
53 int64_t time_now_ms() const {
54 return time_now_ms_;
55 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000056
stefan@webrtc.org5f284982012-06-28 07:51:16 +000057 private:
58 // January 1970, in NTP seconds.
59 const uint32_t kNtpJan1970;
60 int64_t time_now_ms_;
61};
62
63class StreamSynchronizationTest : public ::testing::Test {
64 protected:
65 virtual void SetUp() {
66 sync_ = new StreamSynchronization(0, 0);
67 send_time_ = new Time(kSendTimeOffsetMs);
68 receive_time_ = new Time(kReceiveTimeOffsetMs);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000069 audio_clock_drift_ = 1.0;
70 video_clock_drift_ = 1.0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000071 }
72
73 virtual void TearDown() {
74 delete sync_;
75 delete send_time_;
76 delete receive_time_;
77 }
78
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000079 // Generates the necessary RTCP measurements and RTP timestamps and computes
80 // the audio and video delays needed to get the two streams in sync.
81 // |audio_delay_ms| and |video_delay_ms| are the number of milliseconds after
82 // capture which the frames are rendered.
83 // |current_audio_delay_ms| is the number of milliseconds which audio is
84 // currently being delayed by the receiver.
85 bool DelayedStreams(int audio_delay_ms,
86 int video_delay_ms,
87 int current_audio_delay_ms,
88 int* extra_audio_delay_ms,
89 int* total_video_delay_ms) {
90 int audio_frequency = static_cast<int>(kDefaultAudioFrequency *
91 audio_clock_drift_ + 0.5);
92 int audio_offset = 0;
93 int video_frequency = static_cast<int>(kDefaultVideoFrequency *
94 video_clock_drift_ + 0.5);
asaperssonde9e5ff2016-11-02 07:14:03 -070095 bool new_sr;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000096 int video_offset = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000097 StreamSynchronization::Measurements audio;
98 StreamSynchronization::Measurements video;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000099 // Generate NTP/RTP timestamp pair for both streams corresponding to RTCP.
asaperssonfe50b4d2016-12-22 07:53:51 -0800100 NtpTime ntp_time = send_time_->GetNowNtp();
101 uint32_t rtp_timestamp =
102 send_time_->GetNowRtp(audio_frequency, audio_offset);
103 EXPECT_TRUE(audio.rtp_to_ntp.UpdateMeasurements(
104 ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000105 send_time_->IncreaseTimeMs(100);
106 receive_time_->IncreaseTimeMs(100);
asaperssonfe50b4d2016-12-22 07:53:51 -0800107 ntp_time = send_time_->GetNowNtp();
108 rtp_timestamp = send_time_->GetNowRtp(video_frequency, video_offset);
109 EXPECT_TRUE(video.rtp_to_ntp.UpdateMeasurements(
110 ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000111 send_time_->IncreaseTimeMs(900);
112 receive_time_->IncreaseTimeMs(900);
asaperssonfe50b4d2016-12-22 07:53:51 -0800113 ntp_time = send_time_->GetNowNtp();
114 rtp_timestamp = send_time_->GetNowRtp(audio_frequency, audio_offset);
115 EXPECT_TRUE(audio.rtp_to_ntp.UpdateMeasurements(
116 ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000117 send_time_->IncreaseTimeMs(100);
118 receive_time_->IncreaseTimeMs(100);
asaperssonfe50b4d2016-12-22 07:53:51 -0800119 ntp_time = send_time_->GetNowNtp();
120 rtp_timestamp = send_time_->GetNowRtp(video_frequency, video_offset);
121 EXPECT_TRUE(video.rtp_to_ntp.UpdateMeasurements(
122 ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
asaperssonb7e7b492016-11-17 02:27:14 -0800123
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000124 send_time_->IncreaseTimeMs(900);
125 receive_time_->IncreaseTimeMs(900);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000126
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000127 // Capture an audio and a video frame at the same time.
asaperssonb7e7b492016-11-17 02:27:14 -0800128 audio.latest_timestamp =
129 send_time_->GetNowRtp(audio_frequency, audio_offset);
130 video.latest_timestamp =
131 send_time_->GetNowRtp(video_frequency, video_offset);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000132
133 if (audio_delay_ms > video_delay_ms) {
134 // Audio later than video.
135 receive_time_->IncreaseTimeMs(video_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000136 video.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000137 receive_time_->IncreaseTimeMs(audio_delay_ms - video_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000138 audio.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000139 } else {
140 // Video later than audio.
141 receive_time_->IncreaseTimeMs(audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000142 audio.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000143 receive_time_->IncreaseTimeMs(video_delay_ms - audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000144 video.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000145 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000146 int relative_delay_ms;
147 StreamSynchronization::ComputeRelativeDelay(audio, video,
148 &relative_delay_ms);
149 EXPECT_EQ(video_delay_ms - audio_delay_ms, relative_delay_ms);
150 return sync_->ComputeDelays(relative_delay_ms,
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000151 current_audio_delay_ms,
152 extra_audio_delay_ms,
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000153 total_video_delay_ms);
154 }
155
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000156 // Simulate audio playback 300 ms after capture and video rendering 100 ms
157 // after capture. Verify that the correct extra delays are calculated for
158 // audio and video, and that they change correctly when we simulate that
159 // NetEQ or the VCM adds more delay to the streams.
160 // TODO(holmer): This is currently wrong! We should simply change
161 // audio_delay_ms or video_delay_ms since those now include VCM and NetEQ
162 // delays.
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000163 void BothDelayedAudioLaterTest(int base_target_delay) {
164 int current_audio_delay_ms = base_target_delay;
165 int audio_delay_ms = base_target_delay + 300;
166 int video_delay_ms = base_target_delay + 100;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000167 int extra_audio_delay_ms = 0;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000168 int total_video_delay_ms = base_target_delay;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000169 int filtered_move = (audio_delay_ms - video_delay_ms) / kSmoothingFilter;
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000170 const int kNeteqDelayIncrease = 50;
171 const int kNeteqDelayDecrease = 10;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000172
173 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
174 video_delay_ms,
175 current_audio_delay_ms,
176 &extra_audio_delay_ms,
177 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000178 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000179 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000180 current_audio_delay_ms = extra_audio_delay_ms;
181
182 send_time_->IncreaseTimeMs(1000);
183 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
184 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000185 // Simulate base_target_delay minimum delay in the VCM.
186 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000187 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
188 video_delay_ms,
189 current_audio_delay_ms,
190 &extra_audio_delay_ms,
191 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000192 EXPECT_EQ(base_target_delay + 2 * filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000193 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000194 current_audio_delay_ms = extra_audio_delay_ms;
195
196 send_time_->IncreaseTimeMs(1000);
197 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
198 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000199 // Simulate base_target_delay minimum delay in the VCM.
200 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000201 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
202 video_delay_ms,
203 current_audio_delay_ms,
204 &extra_audio_delay_ms,
205 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000206 EXPECT_EQ(base_target_delay + 3 * filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000207 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000208
209 // Simulate that NetEQ introduces some audio delay.
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000210 current_audio_delay_ms = base_target_delay + kNeteqDelayIncrease;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000211 send_time_->IncreaseTimeMs(1000);
212 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
213 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000214 // Simulate base_target_delay minimum delay in the VCM.
215 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000216 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
217 video_delay_ms,
218 current_audio_delay_ms,
219 &extra_audio_delay_ms,
220 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000221 filtered_move = 3 * filtered_move +
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000222 (kNeteqDelayIncrease + audio_delay_ms - video_delay_ms) /
223 kSmoothingFilter;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000224 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000225 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000226
227 // Simulate that NetEQ reduces its delay.
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000228 current_audio_delay_ms = base_target_delay + kNeteqDelayDecrease;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000229 send_time_->IncreaseTimeMs(1000);
230 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
231 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000232 // Simulate base_target_delay minimum delay in the VCM.
233 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000234 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
235 video_delay_ms,
236 current_audio_delay_ms,
237 &extra_audio_delay_ms,
238 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000239
240 filtered_move = filtered_move +
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000241 (kNeteqDelayDecrease + audio_delay_ms - video_delay_ms) /
242 kSmoothingFilter;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000243
244 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000245 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
246 }
247
248 void BothDelayedVideoLaterTest(int base_target_delay) {
249 int current_audio_delay_ms = base_target_delay;
250 int audio_delay_ms = base_target_delay + 100;
251 int video_delay_ms = base_target_delay + 300;
252 int extra_audio_delay_ms = 0;
253 int total_video_delay_ms = base_target_delay;
254
255 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
256 video_delay_ms,
257 current_audio_delay_ms,
258 &extra_audio_delay_ms,
259 &total_video_delay_ms));
260 EXPECT_EQ(base_target_delay, total_video_delay_ms);
261 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000262 EXPECT_GE(base_target_delay + kMaxAudioDiffMs, extra_audio_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000263 current_audio_delay_ms = extra_audio_delay_ms;
264 int current_extra_delay_ms = extra_audio_delay_ms;
265
266 send_time_->IncreaseTimeMs(1000);
267 receive_time_->IncreaseTimeMs(800);
268 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
269 video_delay_ms,
270 current_audio_delay_ms,
271 &extra_audio_delay_ms,
272 &total_video_delay_ms));
273 EXPECT_EQ(base_target_delay, total_video_delay_ms);
274 // The audio delay is not allowed to change more than the half of the
275 // required change in delay.
276 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
277 current_audio_delay_ms,
278 base_target_delay + video_delay_ms - audio_delay_ms),
279 extra_audio_delay_ms);
280 current_audio_delay_ms = extra_audio_delay_ms;
281 current_extra_delay_ms = extra_audio_delay_ms;
282
283 send_time_->IncreaseTimeMs(1000);
284 receive_time_->IncreaseTimeMs(800);
285 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
286 video_delay_ms,
287 current_audio_delay_ms,
288 &extra_audio_delay_ms,
289 &total_video_delay_ms));
290 EXPECT_EQ(base_target_delay, total_video_delay_ms);
291 // The audio delay is not allowed to change more than the half of the
292 // required change in delay.
293 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
294 current_audio_delay_ms,
295 base_target_delay + video_delay_ms - audio_delay_ms),
296 extra_audio_delay_ms);
297 current_extra_delay_ms = extra_audio_delay_ms;
298
299 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000300 current_audio_delay_ms = base_target_delay + 10;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000301 send_time_->IncreaseTimeMs(1000);
302 receive_time_->IncreaseTimeMs(800);
303 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
304 video_delay_ms,
305 current_audio_delay_ms,
306 &extra_audio_delay_ms,
307 &total_video_delay_ms));
308 EXPECT_EQ(base_target_delay, total_video_delay_ms);
309 // Since we only can ask NetEQ for a certain amount of extra delay, and
310 // we only measure the total NetEQ delay, we will ask for additional delay
311 // here to try to stay in sync.
312 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
313 current_audio_delay_ms,
314 base_target_delay + video_delay_ms - audio_delay_ms),
315 extra_audio_delay_ms);
316 current_extra_delay_ms = extra_audio_delay_ms;
317
318 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000319 current_audio_delay_ms = base_target_delay + 350;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000320 send_time_->IncreaseTimeMs(1000);
321 receive_time_->IncreaseTimeMs(800);
322 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
323 video_delay_ms,
324 current_audio_delay_ms,
325 &extra_audio_delay_ms,
326 &total_video_delay_ms));
327 EXPECT_EQ(base_target_delay, total_video_delay_ms);
328 // The audio delay is not allowed to change more than the half of the
329 // required change in delay.
330 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
331 current_audio_delay_ms,
332 base_target_delay + video_delay_ms - audio_delay_ms),
333 extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000334 }
335
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000336 int MaxAudioDelayIncrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000337 return std::min((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000338 static_cast<int>(kMaxAudioDiffMs));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000339 }
340
341 int MaxAudioDelayDecrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000342 return std::max((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
343 -kMaxAudioDiffMs);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000344 }
345
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000346 enum { kSendTimeOffsetMs = 98765 };
347 enum { kReceiveTimeOffsetMs = 43210 };
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000348
349 StreamSynchronization* sync_;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000350 Time* send_time_; // The simulated clock at the sender.
351 Time* receive_time_; // The simulated clock at the receiver.
352 double audio_clock_drift_;
353 double video_clock_drift_;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000354};
355
356TEST_F(StreamSynchronizationTest, NoDelay) {
357 uint32_t current_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000358 int extra_audio_delay_ms = 0;
359 int total_video_delay_ms = 0;
360
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000361 EXPECT_FALSE(DelayedStreams(0, 0, current_audio_delay_ms,
362 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000363 EXPECT_EQ(0, extra_audio_delay_ms);
364 EXPECT_EQ(0, total_video_delay_ms);
365}
366
367TEST_F(StreamSynchronizationTest, VideoDelay) {
368 uint32_t current_audio_delay_ms = 0;
369 int delay_ms = 200;
370 int extra_audio_delay_ms = 0;
371 int total_video_delay_ms = 0;
372
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000373 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
374 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000375 EXPECT_EQ(0, extra_audio_delay_ms);
376 // The video delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000377 EXPECT_EQ(delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000378
379 send_time_->IncreaseTimeMs(1000);
380 receive_time_->IncreaseTimeMs(800);
381 // Simulate 0 minimum delay in the VCM.
382 total_video_delay_ms = 0;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000383 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
384 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000385 EXPECT_EQ(0, extra_audio_delay_ms);
386 // The video delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000387 EXPECT_EQ(2 * delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000388
389 send_time_->IncreaseTimeMs(1000);
390 receive_time_->IncreaseTimeMs(800);
391 // Simulate 0 minimum delay in the VCM.
392 total_video_delay_ms = 0;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000393 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
394 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000395 EXPECT_EQ(0, extra_audio_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000396 EXPECT_EQ(3 * delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000397}
398
399TEST_F(StreamSynchronizationTest, AudioDelay) {
400 int current_audio_delay_ms = 0;
401 int delay_ms = 200;
402 int extra_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000403 int total_video_delay_ms = 0;
404
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000405 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
406 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000407 EXPECT_EQ(0, total_video_delay_ms);
408 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000409 EXPECT_EQ(delay_ms / kSmoothingFilter, extra_audio_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000410 current_audio_delay_ms = extra_audio_delay_ms;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000411 int current_extra_delay_ms = extra_audio_delay_ms;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000412
413 send_time_->IncreaseTimeMs(1000);
414 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000415 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
416 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000417 EXPECT_EQ(0, total_video_delay_ms);
418 // The audio delay is not allowed to change more than the half of the required
419 // change in delay.
420 EXPECT_EQ(current_extra_delay_ms +
421 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
422 extra_audio_delay_ms);
423 current_audio_delay_ms = extra_audio_delay_ms;
424 current_extra_delay_ms = extra_audio_delay_ms;
425
426 send_time_->IncreaseTimeMs(1000);
427 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000428 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
429 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000430 EXPECT_EQ(0, total_video_delay_ms);
431 // The audio delay is not allowed to change more than the half of the required
432 // change in delay.
433 EXPECT_EQ(current_extra_delay_ms +
434 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
435 extra_audio_delay_ms);
436 current_extra_delay_ms = extra_audio_delay_ms;
437
438 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000439 current_audio_delay_ms = 10;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000440 send_time_->IncreaseTimeMs(1000);
441 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000442 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
443 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000444 EXPECT_EQ(0, total_video_delay_ms);
445 // Since we only can ask NetEQ for a certain amount of extra delay, and
446 // we only measure the total NetEQ delay, we will ask for additional delay
447 // here to try to
448 EXPECT_EQ(current_extra_delay_ms +
449 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
450 extra_audio_delay_ms);
451 current_extra_delay_ms = extra_audio_delay_ms;
452
453 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000454 current_audio_delay_ms = 350;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000455 send_time_->IncreaseTimeMs(1000);
456 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000457 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
458 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000459 EXPECT_EQ(0, total_video_delay_ms);
460 // The audio delay is not allowed to change more than the half of the required
461 // change in delay.
462 EXPECT_EQ(current_extra_delay_ms +
463 MaxAudioDelayDecrease(current_audio_delay_ms, delay_ms),
464 extra_audio_delay_ms);
465}
466
467TEST_F(StreamSynchronizationTest, BothDelayedVideoLater) {
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000468 BothDelayedVideoLaterTest(0);
469}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000470
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000471TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterAudioClockDrift) {
472 audio_clock_drift_ = 1.05;
473 BothDelayedVideoLaterTest(0);
474}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000475
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000476TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterVideoClockDrift) {
477 video_clock_drift_ = 1.05;
478 BothDelayedVideoLaterTest(0);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000479}
480
481TEST_F(StreamSynchronizationTest, BothDelayedAudioLater) {
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000482 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000483}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000484
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000485TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDrift) {
486 audio_clock_drift_ = 1.05;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000487 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000488}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000489
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000490TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDrift) {
491 video_clock_drift_ = 1.05;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000492 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000493}
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000494
495TEST_F(StreamSynchronizationTest, BaseDelay) {
496 int base_target_delay_ms = 2000;
497 int current_audio_delay_ms = 2000;
498 int extra_audio_delay_ms = 0;
499 int total_video_delay_ms = base_target_delay_ms;
500 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000501 // We are in sync don't change.
502 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
503 current_audio_delay_ms,
504 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.org0d8d0102013-02-22 19:30:44 +0000505 // Triggering another call with the same values. Delay should not be modified.
506 base_target_delay_ms = 2000;
507 current_audio_delay_ms = base_target_delay_ms;
508 total_video_delay_ms = base_target_delay_ms;
509 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000510 // We are in sync don't change.
511 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
512 current_audio_delay_ms,
513 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.org0d8d0102013-02-22 19:30:44 +0000514 // Changing delay value - intended to test this module only. In practice it
515 // would take VoE time to adapt.
516 base_target_delay_ms = 5000;
517 current_audio_delay_ms = base_target_delay_ms;
518 total_video_delay_ms = base_target_delay_ms;
519 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000520 // We are in sync don't change.
521 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
522 current_audio_delay_ms,
523 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000524}
525
526TEST_F(StreamSynchronizationTest, BothDelayedAudioLaterWithBaseDelay) {
527 int base_target_delay_ms = 3000;
528 sync_->SetTargetBufferingDelay(base_target_delay_ms);
529 BothDelayedAudioLaterTest(base_target_delay_ms);
530}
531
532TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDriftWithBaseDelay) {
533 int base_target_delay_ms = 3000;
534 sync_->SetTargetBufferingDelay(base_target_delay_ms);
535 audio_clock_drift_ = 1.05;
536 BothDelayedAudioLaterTest(base_target_delay_ms);
537}
538
539TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDriftWithBaseDelay) {
540 int base_target_delay_ms = 3000;
541 sync_->SetTargetBufferingDelay(base_target_delay_ms);
542 video_clock_drift_ = 1.05;
543 BothDelayedAudioLaterTest(base_target_delay_ms);
544}
545
546TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterWithBaseDelay) {
547 int base_target_delay_ms = 2000;
548 sync_->SetTargetBufferingDelay(base_target_delay_ms);
549 BothDelayedVideoLaterTest(base_target_delay_ms);
550}
551
552TEST_F(StreamSynchronizationTest,
553 BothDelayedVideoLaterAudioClockDriftWithBaseDelay) {
554 int base_target_delay_ms = 2000;
555 audio_clock_drift_ = 1.05;
556 sync_->SetTargetBufferingDelay(base_target_delay_ms);
557 BothDelayedVideoLaterTest(base_target_delay_ms);
558}
559
560TEST_F(StreamSynchronizationTest,
561 BothDelayedVideoLaterVideoClockDriftWithBaseDelay) {
562 int base_target_delay_ms = 2000;
563 video_clock_drift_ = 1.05;
564 sync_->SetTargetBufferingDelay(base_target_delay_ms);
565 BothDelayedVideoLaterTest(base_target_delay_ms);
566}
567
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000568} // namespace webrtc