blob: 7136f1e1c712d15dc95b61bd68b8f1067b90b953 [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +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
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000011#include <algorithm>
pbos@webrtc.org281cff82013-05-17 13:44:48 +000012#include <math.h>
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000013
pbos@webrtc.org281cff82013-05-17 13:44:48 +000014#include "testing/gtest/include/gtest/gtest.h"
15#include "webrtc/video_engine/stream_synchronization.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000016
17namespace webrtc {
18
19// These correspond to the same constants defined in vie_sync_module.cc.
20enum { kMaxVideoDiffMs = 80 };
21enum { kMaxAudioDiffMs = 80 };
22enum { kMaxDelay = 1500 };
23
24// Test constants.
25enum { kDefaultAudioFrequency = 8000 };
26enum { kDefaultVideoFrequency = 90000 };
27const double kNtpFracPerMs = 4.294967296E6;
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +000028static const int kSmoothingFilter = 4 * 2;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000029
30class Time {
31 public:
32 explicit Time(int64_t offset)
33 : kNtpJan1970(2208988800UL),
34 time_now_ms_(offset) {}
35
wu@webrtc.orgd2fb2592014-05-07 17:09:44 +000036 RtcpMeasurement GenerateRtcp(int frequency, uint32_t offset) const {
37 RtcpMeasurement rtcp;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000038 NowNtp(&rtcp.ntp_secs, &rtcp.ntp_frac);
39 rtcp.rtp_timestamp = NowRtp(frequency, offset);
40 return rtcp;
41 }
42
43 void NowNtp(uint32_t* ntp_secs, uint32_t* ntp_frac) const {
44 *ntp_secs = time_now_ms_ / 1000 + kNtpJan1970;
45 int64_t remainder_ms = time_now_ms_ % 1000;
46 *ntp_frac = static_cast<uint32_t>(
47 static_cast<double>(remainder_ms) * kNtpFracPerMs + 0.5);
48 }
49
50 uint32_t NowRtp(int frequency, uint32_t offset) const {
51 return frequency * time_now_ms_ / 1000 + offset;
52 }
53
54 void IncreaseTimeMs(int64_t inc) {
55 time_now_ms_ += inc;
56 }
57
58 int64_t time_now_ms() const {
59 return time_now_ms_;
60 }
61
62 private:
63 // January 1970, in NTP seconds.
64 const uint32_t kNtpJan1970;
65 int64_t time_now_ms_;
66};
67
68class StreamSynchronizationTest : public ::testing::Test {
69 protected:
70 virtual void SetUp() {
71 sync_ = new StreamSynchronization(0, 0);
72 send_time_ = new Time(kSendTimeOffsetMs);
73 receive_time_ = new Time(kReceiveTimeOffsetMs);
74 audio_clock_drift_ = 1.0;
75 video_clock_drift_ = 1.0;
76 }
77
78 virtual void TearDown() {
79 delete sync_;
80 delete send_time_;
81 delete receive_time_;
82 }
83
84 // Generates the necessary RTCP measurements and RTP timestamps and computes
85 // the audio and video delays needed to get the two streams in sync.
86 // |audio_delay_ms| and |video_delay_ms| are the number of milliseconds after
87 // capture which the frames are rendered.
88 // |current_audio_delay_ms| is the number of milliseconds which audio is
89 // currently being delayed by the receiver.
90 bool DelayedStreams(int audio_delay_ms,
91 int video_delay_ms,
92 int current_audio_delay_ms,
93 int* extra_audio_delay_ms,
94 int* total_video_delay_ms) {
95 int audio_frequency = static_cast<int>(kDefaultAudioFrequency *
96 audio_clock_drift_ + 0.5);
97 int audio_offset = 0;
98 int video_frequency = static_cast<int>(kDefaultVideoFrequency *
99 video_clock_drift_ + 0.5);
100 int video_offset = 0;
101 StreamSynchronization::Measurements audio;
102 StreamSynchronization::Measurements video;
103 // Generate NTP/RTP timestamp pair for both streams corresponding to RTCP.
104 audio.rtcp.push_front(send_time_->GenerateRtcp(audio_frequency,
105 audio_offset));
106 send_time_->IncreaseTimeMs(100);
107 receive_time_->IncreaseTimeMs(100);
108 video.rtcp.push_front(send_time_->GenerateRtcp(video_frequency,
109 video_offset));
110 send_time_->IncreaseTimeMs(900);
111 receive_time_->IncreaseTimeMs(900);
112 audio.rtcp.push_front(send_time_->GenerateRtcp(audio_frequency,
113 audio_offset));
114 send_time_->IncreaseTimeMs(100);
115 receive_time_->IncreaseTimeMs(100);
116 video.rtcp.push_front(send_time_->GenerateRtcp(video_frequency,
117 video_offset));
118 send_time_->IncreaseTimeMs(900);
119 receive_time_->IncreaseTimeMs(900);
120
121 // Capture an audio and a video frame at the same time.
122 audio.latest_timestamp = send_time_->NowRtp(audio_frequency,
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000123 audio_offset);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000124 video.latest_timestamp = send_time_->NowRtp(video_frequency,
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000125 video_offset);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000126
127 if (audio_delay_ms > video_delay_ms) {
128 // Audio later than video.
129 receive_time_->IncreaseTimeMs(video_delay_ms);
130 video.latest_receive_time_ms = receive_time_->time_now_ms();
131 receive_time_->IncreaseTimeMs(audio_delay_ms - video_delay_ms);
132 audio.latest_receive_time_ms = receive_time_->time_now_ms();
133 } else {
134 // Video later than audio.
135 receive_time_->IncreaseTimeMs(audio_delay_ms);
136 audio.latest_receive_time_ms = receive_time_->time_now_ms();
137 receive_time_->IncreaseTimeMs(video_delay_ms - audio_delay_ms);
138 video.latest_receive_time_ms = receive_time_->time_now_ms();
139 }
140 int relative_delay_ms;
141 StreamSynchronization::ComputeRelativeDelay(audio, video,
142 &relative_delay_ms);
143 EXPECT_EQ(video_delay_ms - audio_delay_ms, relative_delay_ms);
144 return sync_->ComputeDelays(relative_delay_ms,
145 current_audio_delay_ms,
146 extra_audio_delay_ms,
147 total_video_delay_ms);
148 }
149
150 // Simulate audio playback 300 ms after capture and video rendering 100 ms
151 // after capture. Verify that the correct extra delays are calculated for
152 // audio and video, and that they change correctly when we simulate that
153 // NetEQ or the VCM adds more delay to the streams.
154 // TODO(holmer): This is currently wrong! We should simply change
155 // audio_delay_ms or video_delay_ms since those now include VCM and NetEQ
156 // delays.
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000157 void BothDelayedAudioLaterTest(int base_target_delay) {
158 int current_audio_delay_ms = base_target_delay;
159 int audio_delay_ms = base_target_delay + 300;
160 int video_delay_ms = base_target_delay + 100;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000161 int extra_audio_delay_ms = 0;
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000162 int total_video_delay_ms = base_target_delay;
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000163 int filtered_move = (audio_delay_ms - video_delay_ms) / kSmoothingFilter;
pwestin@webrtc.orgb13f3942013-04-26 15:23:34 +0000164 const int kNeteqDelayIncrease = 50;
165 const int kNeteqDelayDecrease = 10;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000166
167 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
168 video_delay_ms,
169 current_audio_delay_ms,
170 &extra_audio_delay_ms,
171 &total_video_delay_ms));
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000172 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000173 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000174 current_audio_delay_ms = extra_audio_delay_ms;
175
176 send_time_->IncreaseTimeMs(1000);
177 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
178 video_delay_ms));
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000179 // Simulate base_target_delay minimum delay in the VCM.
180 total_video_delay_ms = base_target_delay;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000181 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
182 video_delay_ms,
183 current_audio_delay_ms,
184 &extra_audio_delay_ms,
185 &total_video_delay_ms));
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000186 EXPECT_EQ(base_target_delay + 2 * filtered_move, total_video_delay_ms);
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000187 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000188 current_audio_delay_ms = extra_audio_delay_ms;
189
190 send_time_->IncreaseTimeMs(1000);
191 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
192 video_delay_ms));
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000193 // Simulate base_target_delay minimum delay in the VCM.
194 total_video_delay_ms = base_target_delay;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000195 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
196 video_delay_ms,
197 current_audio_delay_ms,
198 &extra_audio_delay_ms,
199 &total_video_delay_ms));
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000200 EXPECT_EQ(base_target_delay + 3 * filtered_move, total_video_delay_ms);
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000201 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000202
203 // Simulate that NetEQ introduces some audio delay.
pwestin@webrtc.orgb13f3942013-04-26 15:23:34 +0000204 current_audio_delay_ms = base_target_delay + kNeteqDelayIncrease;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000205 send_time_->IncreaseTimeMs(1000);
206 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
207 video_delay_ms));
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000208 // Simulate base_target_delay minimum delay in the VCM.
209 total_video_delay_ms = base_target_delay;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000210 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
211 video_delay_ms,
212 current_audio_delay_ms,
213 &extra_audio_delay_ms,
214 &total_video_delay_ms));
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000215 filtered_move = 3 * filtered_move +
pwestin@webrtc.orgb13f3942013-04-26 15:23:34 +0000216 (kNeteqDelayIncrease + audio_delay_ms - video_delay_ms) /
217 kSmoothingFilter;
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000218 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000219 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000220
221 // Simulate that NetEQ reduces its delay.
pwestin@webrtc.orgb13f3942013-04-26 15:23:34 +0000222 current_audio_delay_ms = base_target_delay + kNeteqDelayDecrease;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000223 send_time_->IncreaseTimeMs(1000);
224 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
225 video_delay_ms));
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000226 // Simulate base_target_delay minimum delay in the VCM.
227 total_video_delay_ms = base_target_delay;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000228 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
229 video_delay_ms,
230 current_audio_delay_ms,
231 &extra_audio_delay_ms,
232 &total_video_delay_ms));
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000233
234 filtered_move = filtered_move +
pwestin@webrtc.orgb13f3942013-04-26 15:23:34 +0000235 (kNeteqDelayDecrease + audio_delay_ms - video_delay_ms) /
236 kSmoothingFilter;
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000237
238 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000239 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
240 }
241
242 void BothDelayedVideoLaterTest(int base_target_delay) {
243 int current_audio_delay_ms = base_target_delay;
244 int audio_delay_ms = base_target_delay + 100;
245 int video_delay_ms = base_target_delay + 300;
246 int extra_audio_delay_ms = 0;
247 int total_video_delay_ms = base_target_delay;
248
249 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
250 video_delay_ms,
251 current_audio_delay_ms,
252 &extra_audio_delay_ms,
253 &total_video_delay_ms));
254 EXPECT_EQ(base_target_delay, total_video_delay_ms);
255 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000256 EXPECT_GE(base_target_delay + kMaxAudioDiffMs, extra_audio_delay_ms);
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000257 current_audio_delay_ms = extra_audio_delay_ms;
258 int current_extra_delay_ms = extra_audio_delay_ms;
259
260 send_time_->IncreaseTimeMs(1000);
261 receive_time_->IncreaseTimeMs(800);
262 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
263 video_delay_ms,
264 current_audio_delay_ms,
265 &extra_audio_delay_ms,
266 &total_video_delay_ms));
267 EXPECT_EQ(base_target_delay, total_video_delay_ms);
268 // The audio delay is not allowed to change more than the half of the
269 // required change in delay.
270 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
271 current_audio_delay_ms,
272 base_target_delay + video_delay_ms - audio_delay_ms),
273 extra_audio_delay_ms);
274 current_audio_delay_ms = extra_audio_delay_ms;
275 current_extra_delay_ms = extra_audio_delay_ms;
276
277 send_time_->IncreaseTimeMs(1000);
278 receive_time_->IncreaseTimeMs(800);
279 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
280 video_delay_ms,
281 current_audio_delay_ms,
282 &extra_audio_delay_ms,
283 &total_video_delay_ms));
284 EXPECT_EQ(base_target_delay, total_video_delay_ms);
285 // The audio delay is not allowed to change more than the half of the
286 // required change in delay.
287 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
288 current_audio_delay_ms,
289 base_target_delay + video_delay_ms - audio_delay_ms),
290 extra_audio_delay_ms);
291 current_extra_delay_ms = extra_audio_delay_ms;
292
293 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000294 current_audio_delay_ms = base_target_delay + 10;
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000295 send_time_->IncreaseTimeMs(1000);
296 receive_time_->IncreaseTimeMs(800);
297 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
298 video_delay_ms,
299 current_audio_delay_ms,
300 &extra_audio_delay_ms,
301 &total_video_delay_ms));
302 EXPECT_EQ(base_target_delay, total_video_delay_ms);
303 // Since we only can ask NetEQ for a certain amount of extra delay, and
304 // we only measure the total NetEQ delay, we will ask for additional delay
305 // here to try to stay in sync.
306 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
307 current_audio_delay_ms,
308 base_target_delay + video_delay_ms - audio_delay_ms),
309 extra_audio_delay_ms);
310 current_extra_delay_ms = extra_audio_delay_ms;
311
312 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000313 current_audio_delay_ms = base_target_delay + 350;
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000314 send_time_->IncreaseTimeMs(1000);
315 receive_time_->IncreaseTimeMs(800);
316 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
317 video_delay_ms,
318 current_audio_delay_ms,
319 &extra_audio_delay_ms,
320 &total_video_delay_ms));
321 EXPECT_EQ(base_target_delay, total_video_delay_ms);
322 // The audio delay is not allowed to change more than the half of the
323 // required change in delay.
324 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
325 current_audio_delay_ms,
326 base_target_delay + video_delay_ms - audio_delay_ms),
327 extra_audio_delay_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000328 }
329
330 int MaxAudioDelayIncrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000331 return std::min((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000332 static_cast<int>(kMaxAudioDiffMs));
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000333 }
334
335 int MaxAudioDelayDecrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000336 return std::max((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
337 -kMaxAudioDiffMs);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000338 }
339
340 enum { kSendTimeOffsetMs = 98765 };
341 enum { kReceiveTimeOffsetMs = 43210 };
342
343 StreamSynchronization* sync_;
344 Time* send_time_; // The simulated clock at the sender.
345 Time* receive_time_; // The simulated clock at the receiver.
346 double audio_clock_drift_;
347 double video_clock_drift_;
348};
349
350TEST_F(StreamSynchronizationTest, NoDelay) {
351 uint32_t current_audio_delay_ms = 0;
352 int extra_audio_delay_ms = 0;
353 int total_video_delay_ms = 0;
354
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000355 EXPECT_FALSE(DelayedStreams(0, 0, current_audio_delay_ms,
356 &extra_audio_delay_ms, &total_video_delay_ms));
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000357 EXPECT_EQ(0, extra_audio_delay_ms);
358 EXPECT_EQ(0, total_video_delay_ms);
359}
360
361TEST_F(StreamSynchronizationTest, VideoDelay) {
362 uint32_t current_audio_delay_ms = 0;
363 int delay_ms = 200;
364 int extra_audio_delay_ms = 0;
365 int total_video_delay_ms = 0;
366
367 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
368 &extra_audio_delay_ms, &total_video_delay_ms));
369 EXPECT_EQ(0, extra_audio_delay_ms);
370 // The video delay is not allowed to change more than this in 1 second.
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000371 EXPECT_EQ(delay_ms / kSmoothingFilter, total_video_delay_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000372
373 send_time_->IncreaseTimeMs(1000);
374 receive_time_->IncreaseTimeMs(800);
375 // Simulate 0 minimum delay in the VCM.
376 total_video_delay_ms = 0;
377 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
378 &extra_audio_delay_ms, &total_video_delay_ms));
379 EXPECT_EQ(0, extra_audio_delay_ms);
380 // The video delay is not allowed to change more than this in 1 second.
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000381 EXPECT_EQ(2 * delay_ms / kSmoothingFilter, total_video_delay_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000382
383 send_time_->IncreaseTimeMs(1000);
384 receive_time_->IncreaseTimeMs(800);
385 // Simulate 0 minimum delay in the VCM.
386 total_video_delay_ms = 0;
387 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
388 &extra_audio_delay_ms, &total_video_delay_ms));
389 EXPECT_EQ(0, extra_audio_delay_ms);
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000390 EXPECT_EQ(3 * delay_ms / kSmoothingFilter, total_video_delay_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000391}
392
393TEST_F(StreamSynchronizationTest, AudioDelay) {
394 int current_audio_delay_ms = 0;
395 int delay_ms = 200;
396 int extra_audio_delay_ms = 0;
397 int total_video_delay_ms = 0;
398
399 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
400 &extra_audio_delay_ms, &total_video_delay_ms));
401 EXPECT_EQ(0, total_video_delay_ms);
402 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000403 EXPECT_EQ(delay_ms / kSmoothingFilter, extra_audio_delay_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000404 current_audio_delay_ms = extra_audio_delay_ms;
405 int current_extra_delay_ms = extra_audio_delay_ms;
406
407 send_time_->IncreaseTimeMs(1000);
408 receive_time_->IncreaseTimeMs(800);
409 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
410 &extra_audio_delay_ms, &total_video_delay_ms));
411 EXPECT_EQ(0, total_video_delay_ms);
412 // The audio delay is not allowed to change more than the half of the required
413 // change in delay.
414 EXPECT_EQ(current_extra_delay_ms +
415 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
416 extra_audio_delay_ms);
417 current_audio_delay_ms = extra_audio_delay_ms;
418 current_extra_delay_ms = extra_audio_delay_ms;
419
420 send_time_->IncreaseTimeMs(1000);
421 receive_time_->IncreaseTimeMs(800);
422 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
423 &extra_audio_delay_ms, &total_video_delay_ms));
424 EXPECT_EQ(0, total_video_delay_ms);
425 // The audio delay is not allowed to change more than the half of the required
426 // change in delay.
427 EXPECT_EQ(current_extra_delay_ms +
428 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
429 extra_audio_delay_ms);
430 current_extra_delay_ms = extra_audio_delay_ms;
431
432 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000433 current_audio_delay_ms = 10;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000434 send_time_->IncreaseTimeMs(1000);
435 receive_time_->IncreaseTimeMs(800);
436 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
437 &extra_audio_delay_ms, &total_video_delay_ms));
438 EXPECT_EQ(0, total_video_delay_ms);
439 // Since we only can ask NetEQ for a certain amount of extra delay, and
440 // we only measure the total NetEQ delay, we will ask for additional delay
441 // here to try to
442 EXPECT_EQ(current_extra_delay_ms +
443 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
444 extra_audio_delay_ms);
445 current_extra_delay_ms = extra_audio_delay_ms;
446
447 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000448 current_audio_delay_ms = 350;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000449 send_time_->IncreaseTimeMs(1000);
450 receive_time_->IncreaseTimeMs(800);
451 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
452 &extra_audio_delay_ms, &total_video_delay_ms));
453 EXPECT_EQ(0, total_video_delay_ms);
454 // The audio delay is not allowed to change more than the half of the required
455 // change in delay.
456 EXPECT_EQ(current_extra_delay_ms +
457 MaxAudioDelayDecrease(current_audio_delay_ms, delay_ms),
458 extra_audio_delay_ms);
459}
460
461TEST_F(StreamSynchronizationTest, BothDelayedVideoLater) {
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000462 BothDelayedVideoLaterTest(0);
463}
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000464
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000465TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterAudioClockDrift) {
466 audio_clock_drift_ = 1.05;
467 BothDelayedVideoLaterTest(0);
468}
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000469
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000470TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterVideoClockDrift) {
471 video_clock_drift_ = 1.05;
472 BothDelayedVideoLaterTest(0);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000473}
474
475TEST_F(StreamSynchronizationTest, BothDelayedAudioLater) {
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000476 BothDelayedAudioLaterTest(0);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000477}
478
479TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDrift) {
480 audio_clock_drift_ = 1.05;
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000481 BothDelayedAudioLaterTest(0);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000482}
483
484TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDrift) {
485 video_clock_drift_ = 1.05;
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000486 BothDelayedAudioLaterTest(0);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000487}
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000488
489TEST_F(StreamSynchronizationTest, BaseDelay) {
490 int base_target_delay_ms = 2000;
491 int current_audio_delay_ms = 2000;
492 int extra_audio_delay_ms = 0;
493 int total_video_delay_ms = base_target_delay_ms;
494 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000495 // We are in sync don't change.
496 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
497 current_audio_delay_ms,
498 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.org1601d4a2013-02-22 19:30:44 +0000499 // Triggering another call with the same values. Delay should not be modified.
500 base_target_delay_ms = 2000;
501 current_audio_delay_ms = base_target_delay_ms;
502 total_video_delay_ms = base_target_delay_ms;
503 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000504 // We are in sync don't change.
505 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
506 current_audio_delay_ms,
507 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.org1601d4a2013-02-22 19:30:44 +0000508 // Changing delay value - intended to test this module only. In practice it
509 // would take VoE time to adapt.
510 base_target_delay_ms = 5000;
511 current_audio_delay_ms = base_target_delay_ms;
512 total_video_delay_ms = base_target_delay_ms;
513 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.orgf13f1fc2013-04-22 18:57:14 +0000514 // We are in sync don't change.
515 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
516 current_audio_delay_ms,
517 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.org9d6fcb32013-02-15 23:22:18 +0000518}
519
520TEST_F(StreamSynchronizationTest, BothDelayedAudioLaterWithBaseDelay) {
521 int base_target_delay_ms = 3000;
522 sync_->SetTargetBufferingDelay(base_target_delay_ms);
523 BothDelayedAudioLaterTest(base_target_delay_ms);
524}
525
526TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDriftWithBaseDelay) {
527 int base_target_delay_ms = 3000;
528 sync_->SetTargetBufferingDelay(base_target_delay_ms);
529 audio_clock_drift_ = 1.05;
530 BothDelayedAudioLaterTest(base_target_delay_ms);
531}
532
533TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDriftWithBaseDelay) {
534 int base_target_delay_ms = 3000;
535 sync_->SetTargetBufferingDelay(base_target_delay_ms);
536 video_clock_drift_ = 1.05;
537 BothDelayedAudioLaterTest(base_target_delay_ms);
538}
539
540TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterWithBaseDelay) {
541 int base_target_delay_ms = 2000;
542 sync_->SetTargetBufferingDelay(base_target_delay_ms);
543 BothDelayedVideoLaterTest(base_target_delay_ms);
544}
545
546TEST_F(StreamSynchronizationTest,
547 BothDelayedVideoLaterAudioClockDriftWithBaseDelay) {
548 int base_target_delay_ms = 2000;
549 audio_clock_drift_ = 1.05;
550 sync_->SetTargetBufferingDelay(base_target_delay_ms);
551 BothDelayedVideoLaterTest(base_target_delay_ms);
552}
553
554TEST_F(StreamSynchronizationTest,
555 BothDelayedVideoLaterVideoClockDriftWithBaseDelay) {
556 int base_target_delay_ms = 2000;
557 video_clock_drift_ = 1.05;
558 sync_->SetTargetBufferingDelay(base_target_delay_ms);
559 BothDelayedVideoLaterTest(base_target_delay_ms);
560}
561
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000562} // namespace webrtc