blob: 395556b5e00662451973698858a6d6ba1cf02e2d [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
11#include <math.h>
12#include <algorithm>
13
14#include "gtest/gtest.h"
15#include "video_engine/stream_synchronization.h"
16
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
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000024// Test constants.
25enum { kDefaultAudioFrequency = 8000 };
26enum { kDefaultVideoFrequency = 90000 };
27const double kNtpFracPerMs = 4.294967296E6;
pwestin@webrtc.org63117332013-04-22 18:57:14 +000028static const int kSmoothingFilter = 4 * 2;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000029
stefan@webrtc.org5f284982012-06-28 07:51:16 +000030class Time {
31 public:
32 explicit Time(int64_t offset)
33 : kNtpJan1970(2208988800UL),
34 time_now_ms_(offset) {}
35
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000036 synchronization::RtcpMeasurement GenerateRtcp(int frequency,
37 uint32_t offset) const {
38 synchronization::RtcpMeasurement rtcp;
39 NowNtp(&rtcp.ntp_secs, &rtcp.ntp_frac);
40 rtcp.rtp_timestamp = NowRtp(frequency, offset);
41 return rtcp;
42 }
43
stefan@webrtc.org5f284982012-06-28 07:51:16 +000044 void NowNtp(uint32_t* ntp_secs, uint32_t* ntp_frac) const {
45 *ntp_secs = time_now_ms_ / 1000 + kNtpJan1970;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000046 int64_t remainder_ms = time_now_ms_ % 1000;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000047 *ntp_frac = static_cast<uint32_t>(
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000048 static_cast<double>(remainder_ms) * kNtpFracPerMs + 0.5);
49 }
50
51 uint32_t NowRtp(int frequency, uint32_t offset) const {
52 return frequency * time_now_ms_ / 1000 + offset;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000053 }
54
55 void IncreaseTimeMs(int64_t inc) {
56 time_now_ms_ += inc;
57 }
58
59 int64_t time_now_ms() const {
60 return time_now_ms_;
61 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000062
stefan@webrtc.org5f284982012-06-28 07:51:16 +000063 private:
64 // January 1970, in NTP seconds.
65 const uint32_t kNtpJan1970;
66 int64_t time_now_ms_;
67};
68
69class StreamSynchronizationTest : public ::testing::Test {
70 protected:
71 virtual void SetUp() {
72 sync_ = new StreamSynchronization(0, 0);
73 send_time_ = new Time(kSendTimeOffsetMs);
74 receive_time_ = new Time(kReceiveTimeOffsetMs);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000075 audio_clock_drift_ = 1.0;
76 video_clock_drift_ = 1.0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000077 }
78
79 virtual void TearDown() {
80 delete sync_;
81 delete send_time_;
82 delete receive_time_;
83 }
84
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000085 // Generates the necessary RTCP measurements and RTP timestamps and computes
86 // the audio and video delays needed to get the two streams in sync.
87 // |audio_delay_ms| and |video_delay_ms| are the number of milliseconds after
88 // capture which the frames are rendered.
89 // |current_audio_delay_ms| is the number of milliseconds which audio is
90 // currently being delayed by the receiver.
91 bool DelayedStreams(int audio_delay_ms,
92 int video_delay_ms,
93 int current_audio_delay_ms,
94 int* extra_audio_delay_ms,
95 int* total_video_delay_ms) {
96 int audio_frequency = static_cast<int>(kDefaultAudioFrequency *
97 audio_clock_drift_ + 0.5);
98 int audio_offset = 0;
99 int video_frequency = static_cast<int>(kDefaultVideoFrequency *
100 video_clock_drift_ + 0.5);
101 int video_offset = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000102 StreamSynchronization::Measurements audio;
103 StreamSynchronization::Measurements video;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000104 // Generate NTP/RTP timestamp pair for both streams corresponding to RTCP.
105 audio.rtcp.push_front(send_time_->GenerateRtcp(audio_frequency,
106 audio_offset));
107 send_time_->IncreaseTimeMs(100);
108 receive_time_->IncreaseTimeMs(100);
109 video.rtcp.push_front(send_time_->GenerateRtcp(video_frequency,
110 video_offset));
111 send_time_->IncreaseTimeMs(900);
112 receive_time_->IncreaseTimeMs(900);
113 audio.rtcp.push_front(send_time_->GenerateRtcp(audio_frequency,
114 audio_offset));
115 send_time_->IncreaseTimeMs(100);
116 receive_time_->IncreaseTimeMs(100);
117 video.rtcp.push_front(send_time_->GenerateRtcp(video_frequency,
118 video_offset));
119 send_time_->IncreaseTimeMs(900);
120 receive_time_->IncreaseTimeMs(900);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000121
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000122 // Capture an audio and a video frame at the same time.
123 audio.latest_timestamp = send_time_->NowRtp(audio_frequency,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000124 audio_offset);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000125 video.latest_timestamp = send_time_->NowRtp(video_frequency,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000126 video_offset);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000127
128 if (audio_delay_ms > video_delay_ms) {
129 // Audio later than video.
130 receive_time_->IncreaseTimeMs(video_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000131 video.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000132 receive_time_->IncreaseTimeMs(audio_delay_ms - video_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000133 audio.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000134 } else {
135 // Video later than audio.
136 receive_time_->IncreaseTimeMs(audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000137 audio.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000138 receive_time_->IncreaseTimeMs(video_delay_ms - audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000139 video.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000140 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000141 int relative_delay_ms;
142 StreamSynchronization::ComputeRelativeDelay(audio, video,
143 &relative_delay_ms);
144 EXPECT_EQ(video_delay_ms - audio_delay_ms, relative_delay_ms);
145 return sync_->ComputeDelays(relative_delay_ms,
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000146 current_audio_delay_ms,
147 extra_audio_delay_ms,
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000148 total_video_delay_ms);
149 }
150
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000151 // Simulate audio playback 300 ms after capture and video rendering 100 ms
152 // after capture. Verify that the correct extra delays are calculated for
153 // audio and video, and that they change correctly when we simulate that
154 // NetEQ or the VCM adds more delay to the streams.
155 // TODO(holmer): This is currently wrong! We should simply change
156 // audio_delay_ms or video_delay_ms since those now include VCM and NetEQ
157 // delays.
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000158 void BothDelayedAudioLaterTest(int base_target_delay) {
159 int current_audio_delay_ms = base_target_delay;
160 int audio_delay_ms = base_target_delay + 300;
161 int video_delay_ms = base_target_delay + 100;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000162 int extra_audio_delay_ms = 0;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000163 int total_video_delay_ms = base_target_delay;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000164 int filtered_move = (audio_delay_ms - video_delay_ms) / kSmoothingFilter;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000165
166 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
167 video_delay_ms,
168 current_audio_delay_ms,
169 &extra_audio_delay_ms,
170 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000171 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000172 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000173 current_audio_delay_ms = extra_audio_delay_ms;
174
175 send_time_->IncreaseTimeMs(1000);
176 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
177 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000178 // Simulate base_target_delay minimum delay in the VCM.
179 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000180 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
181 video_delay_ms,
182 current_audio_delay_ms,
183 &extra_audio_delay_ms,
184 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000185 EXPECT_EQ(base_target_delay + 2 * filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000186 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000187 current_audio_delay_ms = extra_audio_delay_ms;
188
189 send_time_->IncreaseTimeMs(1000);
190 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
191 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000192 // Simulate base_target_delay minimum delay in the VCM.
193 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000194 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
195 video_delay_ms,
196 current_audio_delay_ms,
197 &extra_audio_delay_ms,
198 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000199 EXPECT_EQ(base_target_delay + 3 * filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000200 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000201
202 // Simulate that NetEQ introduces some audio delay.
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000203 current_audio_delay_ms = base_target_delay + 50;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000204 send_time_->IncreaseTimeMs(1000);
205 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
206 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000207 // Simulate base_target_delay minimum delay in the VCM.
208 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000209 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
210 video_delay_ms,
211 current_audio_delay_ms,
212 &extra_audio_delay_ms,
213 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000214 filtered_move = 3 * filtered_move +
215 (50 + audio_delay_ms - video_delay_ms) / kSmoothingFilter;
216 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000217 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000218
219 // Simulate that NetEQ reduces its delay.
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000220 current_audio_delay_ms = base_target_delay + 10;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000221 send_time_->IncreaseTimeMs(1000);
222 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
223 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000224 // Simulate base_target_delay minimum delay in the VCM.
225 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000226 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
227 video_delay_ms,
228 current_audio_delay_ms,
229 &extra_audio_delay_ms,
230 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000231
232 filtered_move = filtered_move +
233 (10 + audio_delay_ms - video_delay_ms) / kSmoothingFilter;
234
235 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000236 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
237 }
238
239 void BothDelayedVideoLaterTest(int base_target_delay) {
240 int current_audio_delay_ms = base_target_delay;
241 int audio_delay_ms = base_target_delay + 100;
242 int video_delay_ms = base_target_delay + 300;
243 int extra_audio_delay_ms = 0;
244 int total_video_delay_ms = base_target_delay;
245
246 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
247 video_delay_ms,
248 current_audio_delay_ms,
249 &extra_audio_delay_ms,
250 &total_video_delay_ms));
251 EXPECT_EQ(base_target_delay, total_video_delay_ms);
252 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000253 EXPECT_GE(base_target_delay + kMaxAudioDiffMs, extra_audio_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000254 current_audio_delay_ms = extra_audio_delay_ms;
255 int current_extra_delay_ms = extra_audio_delay_ms;
256
257 send_time_->IncreaseTimeMs(1000);
258 receive_time_->IncreaseTimeMs(800);
259 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
260 video_delay_ms,
261 current_audio_delay_ms,
262 &extra_audio_delay_ms,
263 &total_video_delay_ms));
264 EXPECT_EQ(base_target_delay, total_video_delay_ms);
265 // The audio delay is not allowed to change more than the half of the
266 // required change in delay.
267 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
268 current_audio_delay_ms,
269 base_target_delay + video_delay_ms - audio_delay_ms),
270 extra_audio_delay_ms);
271 current_audio_delay_ms = extra_audio_delay_ms;
272 current_extra_delay_ms = extra_audio_delay_ms;
273
274 send_time_->IncreaseTimeMs(1000);
275 receive_time_->IncreaseTimeMs(800);
276 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
277 video_delay_ms,
278 current_audio_delay_ms,
279 &extra_audio_delay_ms,
280 &total_video_delay_ms));
281 EXPECT_EQ(base_target_delay, total_video_delay_ms);
282 // The audio delay is not allowed to change more than the half of the
283 // required change in delay.
284 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
285 current_audio_delay_ms,
286 base_target_delay + video_delay_ms - audio_delay_ms),
287 extra_audio_delay_ms);
288 current_extra_delay_ms = extra_audio_delay_ms;
289
290 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000291 current_audio_delay_ms = base_target_delay + 10;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000292 send_time_->IncreaseTimeMs(1000);
293 receive_time_->IncreaseTimeMs(800);
294 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
295 video_delay_ms,
296 current_audio_delay_ms,
297 &extra_audio_delay_ms,
298 &total_video_delay_ms));
299 EXPECT_EQ(base_target_delay, total_video_delay_ms);
300 // Since we only can ask NetEQ for a certain amount of extra delay, and
301 // we only measure the total NetEQ delay, we will ask for additional delay
302 // here to try to stay in sync.
303 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
304 current_audio_delay_ms,
305 base_target_delay + video_delay_ms - audio_delay_ms),
306 extra_audio_delay_ms);
307 current_extra_delay_ms = extra_audio_delay_ms;
308
309 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000310 current_audio_delay_ms = base_target_delay + 350;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000311 send_time_->IncreaseTimeMs(1000);
312 receive_time_->IncreaseTimeMs(800);
313 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
314 video_delay_ms,
315 current_audio_delay_ms,
316 &extra_audio_delay_ms,
317 &total_video_delay_ms));
318 EXPECT_EQ(base_target_delay, total_video_delay_ms);
319 // The audio delay is not allowed to change more than the half of the
320 // required change in delay.
321 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
322 current_audio_delay_ms,
323 base_target_delay + video_delay_ms - audio_delay_ms),
324 extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000325 }
326
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000327 int MaxAudioDelayIncrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000328 return std::min((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000329 static_cast<int>(kMaxAudioDiffMs));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000330 }
331
332 int MaxAudioDelayDecrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000333 return std::max((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
334 -kMaxAudioDiffMs);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000335 }
336
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000337 enum { kSendTimeOffsetMs = 98765 };
338 enum { kReceiveTimeOffsetMs = 43210 };
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000339
340 StreamSynchronization* sync_;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000341 Time* send_time_; // The simulated clock at the sender.
342 Time* receive_time_; // The simulated clock at the receiver.
343 double audio_clock_drift_;
344 double video_clock_drift_;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000345};
346
347TEST_F(StreamSynchronizationTest, NoDelay) {
348 uint32_t current_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000349 int extra_audio_delay_ms = 0;
350 int total_video_delay_ms = 0;
351
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000352 EXPECT_FALSE(DelayedStreams(0, 0, current_audio_delay_ms,
353 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000354 EXPECT_EQ(0, extra_audio_delay_ms);
355 EXPECT_EQ(0, total_video_delay_ms);
356}
357
358TEST_F(StreamSynchronizationTest, VideoDelay) {
359 uint32_t current_audio_delay_ms = 0;
360 int delay_ms = 200;
361 int extra_audio_delay_ms = 0;
362 int total_video_delay_ms = 0;
363
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000364 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
365 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000366 EXPECT_EQ(0, extra_audio_delay_ms);
367 // The video delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000368 EXPECT_EQ(delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000369
370 send_time_->IncreaseTimeMs(1000);
371 receive_time_->IncreaseTimeMs(800);
372 // Simulate 0 minimum delay in the VCM.
373 total_video_delay_ms = 0;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000374 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
375 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000376 EXPECT_EQ(0, extra_audio_delay_ms);
377 // The video delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000378 EXPECT_EQ(2 * delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000379
380 send_time_->IncreaseTimeMs(1000);
381 receive_time_->IncreaseTimeMs(800);
382 // Simulate 0 minimum delay in the VCM.
383 total_video_delay_ms = 0;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000384 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
385 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000386 EXPECT_EQ(0, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000387 // Enough time should have elapsed for the requested total video delay to be
388 // equal to the relative delay between audio and video, i.e., we are in sync.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000389 EXPECT_EQ(3 * delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000390}
391
392TEST_F(StreamSynchronizationTest, AudioDelay) {
393 int current_audio_delay_ms = 0;
394 int delay_ms = 200;
395 int extra_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000396 int total_video_delay_ms = 0;
397
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000398 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
399 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000400 EXPECT_EQ(0, total_video_delay_ms);
401 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000402 EXPECT_EQ(delay_ms / kSmoothingFilter, extra_audio_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000403 current_audio_delay_ms = extra_audio_delay_ms;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000404 int current_extra_delay_ms = extra_audio_delay_ms;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000405
406 send_time_->IncreaseTimeMs(1000);
407 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000408 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
409 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000410 EXPECT_EQ(0, total_video_delay_ms);
411 // The audio delay is not allowed to change more than the half of the required
412 // change in delay.
413 EXPECT_EQ(current_extra_delay_ms +
414 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
415 extra_audio_delay_ms);
416 current_audio_delay_ms = extra_audio_delay_ms;
417 current_extra_delay_ms = extra_audio_delay_ms;
418
419 send_time_->IncreaseTimeMs(1000);
420 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000421 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
422 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000423 EXPECT_EQ(0, total_video_delay_ms);
424 // The audio delay is not allowed to change more than the half of the required
425 // change in delay.
426 EXPECT_EQ(current_extra_delay_ms +
427 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
428 extra_audio_delay_ms);
429 current_extra_delay_ms = extra_audio_delay_ms;
430
431 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000432 current_audio_delay_ms = 10;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000433 send_time_->IncreaseTimeMs(1000);
434 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000435 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
436 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000437 EXPECT_EQ(0, total_video_delay_ms);
438 // Since we only can ask NetEQ for a certain amount of extra delay, and
439 // we only measure the total NetEQ delay, we will ask for additional delay
440 // here to try to
441 EXPECT_EQ(current_extra_delay_ms +
442 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
443 extra_audio_delay_ms);
444 current_extra_delay_ms = extra_audio_delay_ms;
445
446 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000447 current_audio_delay_ms = 350;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000448 send_time_->IncreaseTimeMs(1000);
449 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000450 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
451 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000452 EXPECT_EQ(0, total_video_delay_ms);
453 // The audio delay is not allowed to change more than the half of the required
454 // change in delay.
455 EXPECT_EQ(current_extra_delay_ms +
456 MaxAudioDelayDecrease(current_audio_delay_ms, delay_ms),
457 extra_audio_delay_ms);
458}
459
460TEST_F(StreamSynchronizationTest, BothDelayedVideoLater) {
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000461 BothDelayedVideoLaterTest(0);
462}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000463
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000464TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterAudioClockDrift) {
465 audio_clock_drift_ = 1.05;
466 BothDelayedVideoLaterTest(0);
467}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000468
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000469TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterVideoClockDrift) {
470 video_clock_drift_ = 1.05;
471 BothDelayedVideoLaterTest(0);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000472}
473
474TEST_F(StreamSynchronizationTest, BothDelayedAudioLater) {
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000475 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000476}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000477
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000478TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDrift) {
479 audio_clock_drift_ = 1.05;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000480 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000481}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000482
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000483TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDrift) {
484 video_clock_drift_ = 1.05;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000485 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000486}
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000487
488TEST_F(StreamSynchronizationTest, BaseDelay) {
489 int base_target_delay_ms = 2000;
490 int current_audio_delay_ms = 2000;
491 int extra_audio_delay_ms = 0;
492 int total_video_delay_ms = base_target_delay_ms;
493 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000494 // We are in sync don't change.
495 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
496 current_audio_delay_ms,
497 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.org0d8d0102013-02-22 19:30:44 +0000498 // Triggering another call with the same values. Delay should not be modified.
499 base_target_delay_ms = 2000;
500 current_audio_delay_ms = base_target_delay_ms;
501 total_video_delay_ms = base_target_delay_ms;
502 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000503 // We are in sync don't change.
504 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
505 current_audio_delay_ms,
506 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.org0d8d0102013-02-22 19:30:44 +0000507 // Changing delay value - intended to test this module only. In practice it
508 // would take VoE time to adapt.
509 base_target_delay_ms = 5000;
510 current_audio_delay_ms = base_target_delay_ms;
511 total_video_delay_ms = base_target_delay_ms;
512 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000513 // We are in sync don't change.
514 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
515 current_audio_delay_ms,
516 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000517}
518
519TEST_F(StreamSynchronizationTest, BothDelayedAudioLaterWithBaseDelay) {
520 int base_target_delay_ms = 3000;
521 sync_->SetTargetBufferingDelay(base_target_delay_ms);
522 BothDelayedAudioLaterTest(base_target_delay_ms);
523}
524
525TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDriftWithBaseDelay) {
526 int base_target_delay_ms = 3000;
527 sync_->SetTargetBufferingDelay(base_target_delay_ms);
528 audio_clock_drift_ = 1.05;
529 BothDelayedAudioLaterTest(base_target_delay_ms);
530}
531
532TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDriftWithBaseDelay) {
533 int base_target_delay_ms = 3000;
534 sync_->SetTargetBufferingDelay(base_target_delay_ms);
535 video_clock_drift_ = 1.05;
536 BothDelayedAudioLaterTest(base_target_delay_ms);
537}
538
539TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterWithBaseDelay) {
540 int base_target_delay_ms = 2000;
541 sync_->SetTargetBufferingDelay(base_target_delay_ms);
542 BothDelayedVideoLaterTest(base_target_delay_ms);
543}
544
545TEST_F(StreamSynchronizationTest,
546 BothDelayedVideoLaterAudioClockDriftWithBaseDelay) {
547 int base_target_delay_ms = 2000;
548 audio_clock_drift_ = 1.05;
549 sync_->SetTargetBufferingDelay(base_target_delay_ms);
550 BothDelayedVideoLaterTest(base_target_delay_ms);
551}
552
553TEST_F(StreamSynchronizationTest,
554 BothDelayedVideoLaterVideoClockDriftWithBaseDelay) {
555 int base_target_delay_ms = 2000;
556 video_clock_drift_ = 1.05;
557 sync_->SetTargetBufferingDelay(base_target_delay_ms);
558 BothDelayedVideoLaterTest(base_target_delay_ms);
559}
560
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000561} // namespace webrtc