blob: d328d6af437ff5c8761f73ecbc46e425efa9beb8 [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
kwiberg77eab702016-09-28 17:42:01 -070015#include "webrtc/test/gtest.h"
Peter Boström7623ce42015-12-09 12:13:30 +010016#include "webrtc/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
wu@webrtc.org66773a02014-05-07 17:09:44 +000037 RtcpMeasurement GenerateRtcp(int frequency, uint32_t offset) const {
38 RtcpMeasurement rtcp;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000039 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);
asaperssonde9e5ff2016-11-02 07:14:03 -0700101 bool new_sr;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000102 int video_offset = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000103 StreamSynchronization::Measurements audio;
104 StreamSynchronization::Measurements video;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000105 // Generate NTP/RTP timestamp pair for both streams corresponding to RTCP.
asaperssonde9e5ff2016-11-02 07:14:03 -0700106 RtcpMeasurement rtcp =
107 send_time_->GenerateRtcp(audio_frequency, audio_offset);
108 EXPECT_TRUE(UpdateRtcpList(rtcp.ntp_secs, rtcp.ntp_frac, rtcp.rtp_timestamp,
109 &audio.rtcp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000110 send_time_->IncreaseTimeMs(100);
111 receive_time_->IncreaseTimeMs(100);
asaperssonde9e5ff2016-11-02 07:14:03 -0700112 rtcp = send_time_->GenerateRtcp(video_frequency, video_offset);
113 EXPECT_TRUE(UpdateRtcpList(rtcp.ntp_secs, rtcp.ntp_frac, rtcp.rtp_timestamp,
114 &video.rtcp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000115 send_time_->IncreaseTimeMs(900);
116 receive_time_->IncreaseTimeMs(900);
asaperssonde9e5ff2016-11-02 07:14:03 -0700117 rtcp = send_time_->GenerateRtcp(audio_frequency, audio_offset);
118 EXPECT_TRUE(UpdateRtcpList(rtcp.ntp_secs, rtcp.ntp_frac, rtcp.rtp_timestamp,
119 &audio.rtcp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000120 send_time_->IncreaseTimeMs(100);
121 receive_time_->IncreaseTimeMs(100);
asaperssonde9e5ff2016-11-02 07:14:03 -0700122 rtcp = send_time_->GenerateRtcp(video_frequency, video_offset);
123 EXPECT_TRUE(UpdateRtcpList(rtcp.ntp_secs, rtcp.ntp_frac, rtcp.rtp_timestamp,
124 &video.rtcp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000125 send_time_->IncreaseTimeMs(900);
126 receive_time_->IncreaseTimeMs(900);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000127
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000128 // Capture an audio and a video frame at the same time.
129 audio.latest_timestamp = send_time_->NowRtp(audio_frequency,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000130 audio_offset);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000131 video.latest_timestamp = send_time_->NowRtp(video_frequency,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000132 video_offset);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000133
134 if (audio_delay_ms > video_delay_ms) {
135 // Audio later than video.
136 receive_time_->IncreaseTimeMs(video_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000137 video.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000138 receive_time_->IncreaseTimeMs(audio_delay_ms - video_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000139 audio.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000140 } else {
141 // Video later than audio.
142 receive_time_->IncreaseTimeMs(audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000143 audio.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000144 receive_time_->IncreaseTimeMs(video_delay_ms - audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000145 video.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000146 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000147 int relative_delay_ms;
148 StreamSynchronization::ComputeRelativeDelay(audio, video,
149 &relative_delay_ms);
150 EXPECT_EQ(video_delay_ms - audio_delay_ms, relative_delay_ms);
151 return sync_->ComputeDelays(relative_delay_ms,
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000152 current_audio_delay_ms,
153 extra_audio_delay_ms,
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000154 total_video_delay_ms);
155 }
156
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000157 // Simulate audio playback 300 ms after capture and video rendering 100 ms
158 // after capture. Verify that the correct extra delays are calculated for
159 // audio and video, and that they change correctly when we simulate that
160 // NetEQ or the VCM adds more delay to the streams.
161 // TODO(holmer): This is currently wrong! We should simply change
162 // audio_delay_ms or video_delay_ms since those now include VCM and NetEQ
163 // delays.
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000164 void BothDelayedAudioLaterTest(int base_target_delay) {
165 int current_audio_delay_ms = base_target_delay;
166 int audio_delay_ms = base_target_delay + 300;
167 int video_delay_ms = base_target_delay + 100;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000168 int extra_audio_delay_ms = 0;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000169 int total_video_delay_ms = base_target_delay;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000170 int filtered_move = (audio_delay_ms - video_delay_ms) / kSmoothingFilter;
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000171 const int kNeteqDelayIncrease = 50;
172 const int kNeteqDelayDecrease = 10;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000173
174 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
175 video_delay_ms,
176 current_audio_delay_ms,
177 &extra_audio_delay_ms,
178 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000179 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000180 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000181 current_audio_delay_ms = extra_audio_delay_ms;
182
183 send_time_->IncreaseTimeMs(1000);
184 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
185 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000186 // Simulate base_target_delay minimum delay in the VCM.
187 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000188 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
189 video_delay_ms,
190 current_audio_delay_ms,
191 &extra_audio_delay_ms,
192 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000193 EXPECT_EQ(base_target_delay + 2 * filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000194 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000195 current_audio_delay_ms = extra_audio_delay_ms;
196
197 send_time_->IncreaseTimeMs(1000);
198 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
199 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000200 // Simulate base_target_delay minimum delay in the VCM.
201 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000202 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
203 video_delay_ms,
204 current_audio_delay_ms,
205 &extra_audio_delay_ms,
206 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000207 EXPECT_EQ(base_target_delay + 3 * filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000208 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000209
210 // Simulate that NetEQ introduces some audio delay.
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000211 current_audio_delay_ms = base_target_delay + kNeteqDelayIncrease;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000212 send_time_->IncreaseTimeMs(1000);
213 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
214 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000215 // Simulate base_target_delay minimum delay in the VCM.
216 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000217 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
218 video_delay_ms,
219 current_audio_delay_ms,
220 &extra_audio_delay_ms,
221 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000222 filtered_move = 3 * filtered_move +
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000223 (kNeteqDelayIncrease + audio_delay_ms - video_delay_ms) /
224 kSmoothingFilter;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000225 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000226 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000227
228 // Simulate that NetEQ reduces its delay.
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000229 current_audio_delay_ms = base_target_delay + kNeteqDelayDecrease;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000230 send_time_->IncreaseTimeMs(1000);
231 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
232 video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000233 // Simulate base_target_delay minimum delay in the VCM.
234 total_video_delay_ms = base_target_delay;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000235 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
236 video_delay_ms,
237 current_audio_delay_ms,
238 &extra_audio_delay_ms,
239 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000240
241 filtered_move = filtered_move +
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000242 (kNeteqDelayDecrease + audio_delay_ms - video_delay_ms) /
243 kSmoothingFilter;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000244
245 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000246 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
247 }
248
249 void BothDelayedVideoLaterTest(int base_target_delay) {
250 int current_audio_delay_ms = base_target_delay;
251 int audio_delay_ms = base_target_delay + 100;
252 int video_delay_ms = base_target_delay + 300;
253 int extra_audio_delay_ms = 0;
254 int total_video_delay_ms = base_target_delay;
255
256 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
257 video_delay_ms,
258 current_audio_delay_ms,
259 &extra_audio_delay_ms,
260 &total_video_delay_ms));
261 EXPECT_EQ(base_target_delay, total_video_delay_ms);
262 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000263 EXPECT_GE(base_target_delay + kMaxAudioDiffMs, extra_audio_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000264 current_audio_delay_ms = extra_audio_delay_ms;
265 int current_extra_delay_ms = extra_audio_delay_ms;
266
267 send_time_->IncreaseTimeMs(1000);
268 receive_time_->IncreaseTimeMs(800);
269 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
270 video_delay_ms,
271 current_audio_delay_ms,
272 &extra_audio_delay_ms,
273 &total_video_delay_ms));
274 EXPECT_EQ(base_target_delay, total_video_delay_ms);
275 // The audio delay is not allowed to change more than the half of the
276 // required change in delay.
277 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
278 current_audio_delay_ms,
279 base_target_delay + video_delay_ms - audio_delay_ms),
280 extra_audio_delay_ms);
281 current_audio_delay_ms = extra_audio_delay_ms;
282 current_extra_delay_ms = extra_audio_delay_ms;
283
284 send_time_->IncreaseTimeMs(1000);
285 receive_time_->IncreaseTimeMs(800);
286 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
287 video_delay_ms,
288 current_audio_delay_ms,
289 &extra_audio_delay_ms,
290 &total_video_delay_ms));
291 EXPECT_EQ(base_target_delay, total_video_delay_ms);
292 // The audio delay is not allowed to change more than the half of the
293 // required change in delay.
294 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
295 current_audio_delay_ms,
296 base_target_delay + video_delay_ms - audio_delay_ms),
297 extra_audio_delay_ms);
298 current_extra_delay_ms = extra_audio_delay_ms;
299
300 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000301 current_audio_delay_ms = base_target_delay + 10;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000302 send_time_->IncreaseTimeMs(1000);
303 receive_time_->IncreaseTimeMs(800);
304 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
305 video_delay_ms,
306 current_audio_delay_ms,
307 &extra_audio_delay_ms,
308 &total_video_delay_ms));
309 EXPECT_EQ(base_target_delay, total_video_delay_ms);
310 // Since we only can ask NetEQ for a certain amount of extra delay, and
311 // we only measure the total NetEQ delay, we will ask for additional delay
312 // here to try to stay in sync.
313 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
314 current_audio_delay_ms,
315 base_target_delay + video_delay_ms - audio_delay_ms),
316 extra_audio_delay_ms);
317 current_extra_delay_ms = extra_audio_delay_ms;
318
319 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000320 current_audio_delay_ms = base_target_delay + 350;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000321 send_time_->IncreaseTimeMs(1000);
322 receive_time_->IncreaseTimeMs(800);
323 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
324 video_delay_ms,
325 current_audio_delay_ms,
326 &extra_audio_delay_ms,
327 &total_video_delay_ms));
328 EXPECT_EQ(base_target_delay, total_video_delay_ms);
329 // The audio delay is not allowed to change more than the half of the
330 // required change in delay.
331 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
332 current_audio_delay_ms,
333 base_target_delay + video_delay_ms - audio_delay_ms),
334 extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000335 }
336
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000337 int MaxAudioDelayIncrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000338 return std::min((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000339 static_cast<int>(kMaxAudioDiffMs));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000340 }
341
342 int MaxAudioDelayDecrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000343 return std::max((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
344 -kMaxAudioDiffMs);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000345 }
346
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000347 enum { kSendTimeOffsetMs = 98765 };
348 enum { kReceiveTimeOffsetMs = 43210 };
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000349
350 StreamSynchronization* sync_;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000351 Time* send_time_; // The simulated clock at the sender.
352 Time* receive_time_; // The simulated clock at the receiver.
353 double audio_clock_drift_;
354 double video_clock_drift_;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000355};
356
357TEST_F(StreamSynchronizationTest, NoDelay) {
358 uint32_t current_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000359 int extra_audio_delay_ms = 0;
360 int total_video_delay_ms = 0;
361
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000362 EXPECT_FALSE(DelayedStreams(0, 0, current_audio_delay_ms,
363 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000364 EXPECT_EQ(0, extra_audio_delay_ms);
365 EXPECT_EQ(0, total_video_delay_ms);
366}
367
368TEST_F(StreamSynchronizationTest, VideoDelay) {
369 uint32_t current_audio_delay_ms = 0;
370 int delay_ms = 200;
371 int extra_audio_delay_ms = 0;
372 int total_video_delay_ms = 0;
373
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(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);
387 // The video delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000388 EXPECT_EQ(2 * delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000389
390 send_time_->IncreaseTimeMs(1000);
391 receive_time_->IncreaseTimeMs(800);
392 // Simulate 0 minimum delay in the VCM.
393 total_video_delay_ms = 0;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000394 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
395 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000396 EXPECT_EQ(0, extra_audio_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000397 EXPECT_EQ(3 * delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000398}
399
400TEST_F(StreamSynchronizationTest, AudioDelay) {
401 int current_audio_delay_ms = 0;
402 int delay_ms = 200;
403 int extra_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000404 int total_video_delay_ms = 0;
405
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000406 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
407 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000408 EXPECT_EQ(0, total_video_delay_ms);
409 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000410 EXPECT_EQ(delay_ms / kSmoothingFilter, extra_audio_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000411 current_audio_delay_ms = extra_audio_delay_ms;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000412 int current_extra_delay_ms = extra_audio_delay_ms;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000413
414 send_time_->IncreaseTimeMs(1000);
415 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000416 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
417 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000418 EXPECT_EQ(0, total_video_delay_ms);
419 // The audio delay is not allowed to change more than the half of the required
420 // change in delay.
421 EXPECT_EQ(current_extra_delay_ms +
422 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
423 extra_audio_delay_ms);
424 current_audio_delay_ms = extra_audio_delay_ms;
425 current_extra_delay_ms = extra_audio_delay_ms;
426
427 send_time_->IncreaseTimeMs(1000);
428 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000429 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
430 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000431 EXPECT_EQ(0, total_video_delay_ms);
432 // The audio delay is not allowed to change more than the half of the required
433 // change in delay.
434 EXPECT_EQ(current_extra_delay_ms +
435 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
436 extra_audio_delay_ms);
437 current_extra_delay_ms = extra_audio_delay_ms;
438
439 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000440 current_audio_delay_ms = 10;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000441 send_time_->IncreaseTimeMs(1000);
442 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000443 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
444 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000445 EXPECT_EQ(0, total_video_delay_ms);
446 // Since we only can ask NetEQ for a certain amount of extra delay, and
447 // we only measure the total NetEQ delay, we will ask for additional delay
448 // here to try to
449 EXPECT_EQ(current_extra_delay_ms +
450 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
451 extra_audio_delay_ms);
452 current_extra_delay_ms = extra_audio_delay_ms;
453
454 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000455 current_audio_delay_ms = 350;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000456 send_time_->IncreaseTimeMs(1000);
457 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000458 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
459 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000460 EXPECT_EQ(0, total_video_delay_ms);
461 // The audio delay is not allowed to change more than the half of the required
462 // change in delay.
463 EXPECT_EQ(current_extra_delay_ms +
464 MaxAudioDelayDecrease(current_audio_delay_ms, delay_ms),
465 extra_audio_delay_ms);
466}
467
468TEST_F(StreamSynchronizationTest, BothDelayedVideoLater) {
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000469 BothDelayedVideoLaterTest(0);
470}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000471
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000472TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterAudioClockDrift) {
473 audio_clock_drift_ = 1.05;
474 BothDelayedVideoLaterTest(0);
475}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000476
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000477TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterVideoClockDrift) {
478 video_clock_drift_ = 1.05;
479 BothDelayedVideoLaterTest(0);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000480}
481
482TEST_F(StreamSynchronizationTest, BothDelayedAudioLater) {
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000483 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000484}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000485
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000486TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDrift) {
487 audio_clock_drift_ = 1.05;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000488 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000489}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000490
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000491TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDrift) {
492 video_clock_drift_ = 1.05;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000493 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000494}
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000495
496TEST_F(StreamSynchronizationTest, BaseDelay) {
497 int base_target_delay_ms = 2000;
498 int current_audio_delay_ms = 2000;
499 int extra_audio_delay_ms = 0;
500 int total_video_delay_ms = base_target_delay_ms;
501 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000502 // We are in sync don't change.
503 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
504 current_audio_delay_ms,
505 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.org0d8d0102013-02-22 19:30:44 +0000506 // Triggering another call with the same values. Delay should not be modified.
507 base_target_delay_ms = 2000;
508 current_audio_delay_ms = base_target_delay_ms;
509 total_video_delay_ms = base_target_delay_ms;
510 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000511 // We are in sync don't change.
512 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
513 current_audio_delay_ms,
514 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.org0d8d0102013-02-22 19:30:44 +0000515 // Changing delay value - intended to test this module only. In practice it
516 // would take VoE time to adapt.
517 base_target_delay_ms = 5000;
518 current_audio_delay_ms = base_target_delay_ms;
519 total_video_delay_ms = base_target_delay_ms;
520 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000521 // We are in sync don't change.
522 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
523 current_audio_delay_ms,
524 &extra_audio_delay_ms, &total_video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000525}
526
527TEST_F(StreamSynchronizationTest, BothDelayedAudioLaterWithBaseDelay) {
528 int base_target_delay_ms = 3000;
529 sync_->SetTargetBufferingDelay(base_target_delay_ms);
530 BothDelayedAudioLaterTest(base_target_delay_ms);
531}
532
533TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDriftWithBaseDelay) {
534 int base_target_delay_ms = 3000;
535 sync_->SetTargetBufferingDelay(base_target_delay_ms);
536 audio_clock_drift_ = 1.05;
537 BothDelayedAudioLaterTest(base_target_delay_ms);
538}
539
540TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDriftWithBaseDelay) {
541 int base_target_delay_ms = 3000;
542 sync_->SetTargetBufferingDelay(base_target_delay_ms);
543 video_clock_drift_ = 1.05;
544 BothDelayedAudioLaterTest(base_target_delay_ms);
545}
546
547TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterWithBaseDelay) {
548 int base_target_delay_ms = 2000;
549 sync_->SetTargetBufferingDelay(base_target_delay_ms);
550 BothDelayedVideoLaterTest(base_target_delay_ms);
551}
552
553TEST_F(StreamSynchronizationTest,
554 BothDelayedVideoLaterAudioClockDriftWithBaseDelay) {
555 int base_target_delay_ms = 2000;
556 audio_clock_drift_ = 1.05;
557 sync_->SetTargetBufferingDelay(base_target_delay_ms);
558 BothDelayedVideoLaterTest(base_target_delay_ms);
559}
560
561TEST_F(StreamSynchronizationTest,
562 BothDelayedVideoLaterVideoClockDriftWithBaseDelay) {
563 int base_target_delay_ms = 2000;
564 video_clock_drift_ = 1.05;
565 sync_->SetTargetBufferingDelay(base_target_delay_ms);
566 BothDelayedVideoLaterTest(base_target_delay_ms);
567}
568
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000569} // namespace webrtc