blob: f693b753f50d369e13afa64845bd5057c6cef944 [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;
28
stefan@webrtc.org5f284982012-06-28 07:51:16 +000029class Time {
30 public:
31 explicit Time(int64_t offset)
32 : kNtpJan1970(2208988800UL),
33 time_now_ms_(offset) {}
34
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000035 synchronization::RtcpMeasurement GenerateRtcp(int frequency,
36 uint32_t offset) const {
37 synchronization::RtcpMeasurement rtcp;
38 NowNtp(&rtcp.ntp_secs, &rtcp.ntp_frac);
39 rtcp.rtp_timestamp = NowRtp(frequency, offset);
40 return rtcp;
41 }
42
stefan@webrtc.org5f284982012-06-28 07:51:16 +000043 void NowNtp(uint32_t* ntp_secs, uint32_t* ntp_frac) const {
44 *ntp_secs = time_now_ms_ / 1000 + kNtpJan1970;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000045 int64_t remainder_ms = time_now_ms_ % 1000;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000046 *ntp_frac = static_cast<uint32_t>(
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000047 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;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000052 }
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 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000061
stefan@webrtc.org5f284982012-06-28 07:51:16 +000062 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);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000074 audio_clock_drift_ = 1.0;
75 video_clock_drift_ = 1.0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000076 }
77
78 virtual void TearDown() {
79 delete sync_;
80 delete send_time_;
81 delete receive_time_;
82 }
83
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000084 // 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;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000101 StreamSynchronization::Measurements audio;
102 StreamSynchronization::Measurements video;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000103 // 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);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000120
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000121 // Capture an audio and a video frame at the same time.
122 audio.latest_timestamp = send_time_->NowRtp(audio_frequency,
123 audio_offset);
124 video.latest_timestamp = send_time_->NowRtp(video_frequency,
125 video_offset);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000126
127 if (audio_delay_ms > video_delay_ms) {
128 // Audio later than video.
129 receive_time_->IncreaseTimeMs(video_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000130 video.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000131 receive_time_->IncreaseTimeMs(audio_delay_ms - video_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000132 audio.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000133 } else {
134 // Video later than audio.
135 receive_time_->IncreaseTimeMs(audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000136 audio.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000137 receive_time_->IncreaseTimeMs(video_delay_ms - audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000138 video.latest_receive_time_ms = receive_time_->time_now_ms();
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000139 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000140 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,
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000145 current_audio_delay_ms,
146 extra_audio_delay_ms,
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000147 total_video_delay_ms);
148 }
149
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000150 // 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.
157 void BothDelayedAudioLaterTest() {
158 int current_audio_delay_ms = 0;
159 int audio_delay_ms = 300;
160 int video_delay_ms = 100;
161 int extra_audio_delay_ms = 0;
162 int total_video_delay_ms = 0;
163
164 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
165 video_delay_ms,
166 current_audio_delay_ms,
167 &extra_audio_delay_ms,
168 &total_video_delay_ms));
169 EXPECT_EQ(kMaxVideoDiffMs, total_video_delay_ms);
170 EXPECT_EQ(0, extra_audio_delay_ms);
171 current_audio_delay_ms = extra_audio_delay_ms;
172
173 send_time_->IncreaseTimeMs(1000);
174 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
175 video_delay_ms));
176 // Simulate 0 minimum delay in the VCM.
177 total_video_delay_ms = 0;
178 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
179 video_delay_ms,
180 current_audio_delay_ms,
181 &extra_audio_delay_ms,
182 &total_video_delay_ms));
183 EXPECT_EQ(2 * kMaxVideoDiffMs, total_video_delay_ms);
184 EXPECT_EQ(0, extra_audio_delay_ms);
185 current_audio_delay_ms = extra_audio_delay_ms;
186
187 send_time_->IncreaseTimeMs(1000);
188 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
189 video_delay_ms));
190 // Simulate 0 minimum delay in the VCM.
191 total_video_delay_ms = 0;
192 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
193 video_delay_ms,
194 current_audio_delay_ms,
195 &extra_audio_delay_ms,
196 &total_video_delay_ms));
197 EXPECT_EQ(audio_delay_ms - video_delay_ms, total_video_delay_ms);
198 EXPECT_EQ(0, extra_audio_delay_ms);
199
200 // Simulate that NetEQ introduces some audio delay.
201 current_audio_delay_ms = 50;
202 send_time_->IncreaseTimeMs(1000);
203 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
204 video_delay_ms));
205 // Simulate 0 minimum delay in the VCM.
206 total_video_delay_ms = 0;
207 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
208 video_delay_ms,
209 current_audio_delay_ms,
210 &extra_audio_delay_ms,
211 &total_video_delay_ms));
212 EXPECT_EQ(audio_delay_ms - video_delay_ms + current_audio_delay_ms,
213 total_video_delay_ms);
214 EXPECT_EQ(0, extra_audio_delay_ms);
215
216 // Simulate that NetEQ reduces its delay.
217 current_audio_delay_ms = 10;
218 send_time_->IncreaseTimeMs(1000);
219 receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
220 video_delay_ms));
221 // Simulate 0 minimum delay in the VCM.
222 total_video_delay_ms = 0;
223 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
224 video_delay_ms,
225 current_audio_delay_ms,
226 &extra_audio_delay_ms,
227 &total_video_delay_ms));
228 EXPECT_EQ(audio_delay_ms - video_delay_ms + current_audio_delay_ms,
229 total_video_delay_ms);
230 EXPECT_EQ(0, extra_audio_delay_ms);
231 }
232
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000233 int MaxAudioDelayIncrease(int current_audio_delay_ms, int delay_ms) {
234 return std::min((delay_ms - current_audio_delay_ms) / 2,
235 static_cast<int>(kMaxAudioDiffMs));
236 }
237
238 int MaxAudioDelayDecrease(int current_audio_delay_ms, int delay_ms) {
239 return std::max((delay_ms - current_audio_delay_ms) / 2, -kMaxAudioDiffMs);
240 }
241
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000242 enum { kSendTimeOffsetMs = 98765 };
243 enum { kReceiveTimeOffsetMs = 43210 };
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000244
245 StreamSynchronization* sync_;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000246 Time* send_time_; // The simulated clock at the sender.
247 Time* receive_time_; // The simulated clock at the receiver.
248 double audio_clock_drift_;
249 double video_clock_drift_;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000250};
251
252TEST_F(StreamSynchronizationTest, NoDelay) {
253 uint32_t current_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000254 int extra_audio_delay_ms = 0;
255 int total_video_delay_ms = 0;
256
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000257 EXPECT_TRUE(DelayedStreams(0, 0, current_audio_delay_ms,
258 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000259 EXPECT_EQ(0, extra_audio_delay_ms);
260 EXPECT_EQ(0, total_video_delay_ms);
261}
262
263TEST_F(StreamSynchronizationTest, VideoDelay) {
264 uint32_t current_audio_delay_ms = 0;
265 int delay_ms = 200;
266 int extra_audio_delay_ms = 0;
267 int total_video_delay_ms = 0;
268
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000269 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
270 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000271 EXPECT_EQ(0, extra_audio_delay_ms);
272 // The video delay is not allowed to change more than this in 1 second.
273 EXPECT_EQ(kMaxVideoDiffMs, total_video_delay_ms);
274
275 send_time_->IncreaseTimeMs(1000);
276 receive_time_->IncreaseTimeMs(800);
277 // Simulate 0 minimum delay in the VCM.
278 total_video_delay_ms = 0;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000279 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
280 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000281 EXPECT_EQ(0, extra_audio_delay_ms);
282 // The video delay is not allowed to change more than this in 1 second.
283 EXPECT_EQ(2*kMaxVideoDiffMs, total_video_delay_ms);
284
285 send_time_->IncreaseTimeMs(1000);
286 receive_time_->IncreaseTimeMs(800);
287 // Simulate 0 minimum delay in the VCM.
288 total_video_delay_ms = 0;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000289 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
290 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000291 EXPECT_EQ(0, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000292 // Enough time should have elapsed for the requested total video delay to be
293 // equal to the relative delay between audio and video, i.e., we are in sync.
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000294 EXPECT_EQ(delay_ms, total_video_delay_ms);
295}
296
297TEST_F(StreamSynchronizationTest, AudioDelay) {
298 int current_audio_delay_ms = 0;
299 int delay_ms = 200;
300 int extra_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000301 int total_video_delay_ms = 0;
302
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000303 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
304 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000305 EXPECT_EQ(0, total_video_delay_ms);
306 // The audio delay is not allowed to change more than this in 1 second.
307 EXPECT_EQ(kMaxAudioDiffMs, extra_audio_delay_ms);
308 current_audio_delay_ms = extra_audio_delay_ms;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000309 int current_extra_delay_ms = extra_audio_delay_ms;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000310
311 send_time_->IncreaseTimeMs(1000);
312 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000313 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
314 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000315 EXPECT_EQ(0, total_video_delay_ms);
316 // The audio delay is not allowed to change more than the half of the required
317 // change in delay.
318 EXPECT_EQ(current_extra_delay_ms +
319 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
320 extra_audio_delay_ms);
321 current_audio_delay_ms = extra_audio_delay_ms;
322 current_extra_delay_ms = extra_audio_delay_ms;
323
324 send_time_->IncreaseTimeMs(1000);
325 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000326 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
327 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000328 EXPECT_EQ(0, total_video_delay_ms);
329 // The audio delay is not allowed to change more than the half of the required
330 // change in delay.
331 EXPECT_EQ(current_extra_delay_ms +
332 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
333 extra_audio_delay_ms);
334 current_extra_delay_ms = extra_audio_delay_ms;
335
336 // Simulate that NetEQ for some reason reduced the delay.
337 current_audio_delay_ms = 170;
338 send_time_->IncreaseTimeMs(1000);
339 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000340 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
341 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000342 EXPECT_EQ(0, total_video_delay_ms);
343 // Since we only can ask NetEQ for a certain amount of extra delay, and
344 // we only measure the total NetEQ delay, we will ask for additional delay
345 // here to try to
346 EXPECT_EQ(current_extra_delay_ms +
347 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
348 extra_audio_delay_ms);
349 current_extra_delay_ms = extra_audio_delay_ms;
350
351 // Simulate that NetEQ for some reason significantly increased the delay.
352 current_audio_delay_ms = 250;
353 send_time_->IncreaseTimeMs(1000);
354 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000355 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
356 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000357 EXPECT_EQ(0, total_video_delay_ms);
358 // The audio delay is not allowed to change more than the half of the required
359 // change in delay.
360 EXPECT_EQ(current_extra_delay_ms +
361 MaxAudioDelayDecrease(current_audio_delay_ms, delay_ms),
362 extra_audio_delay_ms);
363}
364
365TEST_F(StreamSynchronizationTest, BothDelayedVideoLater) {
366 int current_audio_delay_ms = 0;
367 int audio_delay_ms = 100;
368 int video_delay_ms = 300;
369 int extra_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000370 int total_video_delay_ms = 0;
371
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000372 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
373 video_delay_ms,
374 current_audio_delay_ms,
375 &extra_audio_delay_ms,
376 &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000377 EXPECT_EQ(0, total_video_delay_ms);
378 // The audio delay is not allowed to change more than this in 1 second.
379 EXPECT_EQ(kMaxAudioDiffMs, extra_audio_delay_ms);
380 current_audio_delay_ms = extra_audio_delay_ms;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000381 int current_extra_delay_ms = extra_audio_delay_ms;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000382
383 send_time_->IncreaseTimeMs(1000);
384 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000385 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
386 video_delay_ms,
387 current_audio_delay_ms,
388 &extra_audio_delay_ms,
389 &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000390 EXPECT_EQ(0, total_video_delay_ms);
391 // The audio delay is not allowed to change more than the half of the required
392 // change in delay.
393 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
394 current_audio_delay_ms, video_delay_ms - audio_delay_ms),
395 extra_audio_delay_ms);
396 current_audio_delay_ms = extra_audio_delay_ms;
397 current_extra_delay_ms = extra_audio_delay_ms;
398
399 send_time_->IncreaseTimeMs(1000);
400 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000401 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
402 video_delay_ms,
403 current_audio_delay_ms,
404 &extra_audio_delay_ms,
405 &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000406 EXPECT_EQ(0, total_video_delay_ms);
407 // The audio delay is not allowed to change more than the half of the required
408 // change in delay.
409 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
410 current_audio_delay_ms, video_delay_ms - audio_delay_ms),
411 extra_audio_delay_ms);
412 current_extra_delay_ms = extra_audio_delay_ms;
413
414 // Simulate that NetEQ for some reason reduced the delay.
415 current_audio_delay_ms = 170;
416 send_time_->IncreaseTimeMs(1000);
417 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000418 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
419 video_delay_ms,
420 current_audio_delay_ms,
421 &extra_audio_delay_ms,
422 &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000423 EXPECT_EQ(0, total_video_delay_ms);
424 // Since we only can ask NetEQ for a certain amount of extra delay, and
425 // we only measure the total NetEQ delay, we will ask for additional delay
426 // here to try to stay in sync.
427 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
428 current_audio_delay_ms, video_delay_ms - audio_delay_ms),
429 extra_audio_delay_ms);
430 current_extra_delay_ms = extra_audio_delay_ms;
431
432 // Simulate that NetEQ for some reason significantly increased the delay.
433 current_audio_delay_ms = 250;
434 send_time_->IncreaseTimeMs(1000);
435 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000436 EXPECT_TRUE(DelayedStreams(audio_delay_ms,
437 video_delay_ms,
438 current_audio_delay_ms,
439 &extra_audio_delay_ms,
440 &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000441 EXPECT_EQ(0, total_video_delay_ms);
442 // The audio delay is not allowed to change more than the half of the required
443 // change in delay.
444 EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
445 current_audio_delay_ms, video_delay_ms - audio_delay_ms),
446 extra_audio_delay_ms);
447}
448
449TEST_F(StreamSynchronizationTest, BothDelayedAudioLater) {
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000450 BothDelayedAudioLaterTest();
451}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000452
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000453TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDrift) {
454 audio_clock_drift_ = 1.05;
455 BothDelayedAudioLaterTest();
456}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000457
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000458TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDrift) {
459 video_clock_drift_ = 1.05;
460 BothDelayedAudioLaterTest();
461}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000462} // namespace webrtc