blob: 2bd7eaefaf1d7fa9c29b253f1d85d23edb9c2276 [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
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010011#include <algorithm>
12
Yves Gerey3e707812018-11-28 16:47:49 +010013#include "system_wrappers/include/ntp_time.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "test/gtest.h"
15#include "video/stream_synchronization.h"
stefan@webrtc.org5f284982012-06-28 07:51:16 +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
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)
Yves Gerey665174f2018-06-19 15:03:05 +020033 : kNtpJan1970(2208988800UL), time_now_ms_(offset) {}
stefan@webrtc.org5f284982012-06-28 07:51:16 +000034
asaperssonb7e7b492016-11-17 02:27:14 -080035 NtpTime GetNowNtp() const {
36 uint32_t ntp_secs = time_now_ms_ / 1000 + kNtpJan1970;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000037 int64_t remainder_ms = time_now_ms_ % 1000;
asaperssonb7e7b492016-11-17 02:27:14 -080038 uint32_t ntp_frac = static_cast<uint32_t>(
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000039 static_cast<double>(remainder_ms) * kNtpFracPerMs + 0.5);
asaperssonb7e7b492016-11-17 02:27:14 -080040 return NtpTime(ntp_secs, ntp_frac);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000041 }
42
asaperssonb7e7b492016-11-17 02:27:14 -080043 uint32_t GetNowRtp(int frequency, uint32_t offset) const {
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000044 return frequency * time_now_ms_ / 1000 + offset;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000045 }
46
Yves Gerey665174f2018-06-19 15:03:05 +020047 void IncreaseTimeMs(int64_t inc) { time_now_ms_ += inc; }
stefan@webrtc.org5f284982012-06-28 07:51:16 +000048
Yves Gerey665174f2018-06-19 15:03:05 +020049 int64_t time_now_ms() const { return time_now_ms_; }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000050
stefan@webrtc.org5f284982012-06-28 07:51:16 +000051 private:
52 // January 1970, in NTP seconds.
53 const uint32_t kNtpJan1970;
54 int64_t time_now_ms_;
55};
56
57class StreamSynchronizationTest : public ::testing::Test {
58 protected:
59 virtual void SetUp() {
60 sync_ = new StreamSynchronization(0, 0);
61 send_time_ = new Time(kSendTimeOffsetMs);
62 receive_time_ = new Time(kReceiveTimeOffsetMs);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000063 audio_clock_drift_ = 1.0;
64 video_clock_drift_ = 1.0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000065 }
66
67 virtual void TearDown() {
68 delete sync_;
69 delete send_time_;
70 delete receive_time_;
71 }
72
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000073 // Generates the necessary RTCP measurements and RTP timestamps and computes
74 // the audio and video delays needed to get the two streams in sync.
75 // |audio_delay_ms| and |video_delay_ms| are the number of milliseconds after
76 // capture which the frames are rendered.
77 // |current_audio_delay_ms| is the number of milliseconds which audio is
78 // currently being delayed by the receiver.
79 bool DelayedStreams(int audio_delay_ms,
80 int video_delay_ms,
81 int current_audio_delay_ms,
82 int* extra_audio_delay_ms,
83 int* total_video_delay_ms) {
Yves Gerey665174f2018-06-19 15:03:05 +020084 int audio_frequency =
85 static_cast<int>(kDefaultAudioFrequency * audio_clock_drift_ + 0.5);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000086 int audio_offset = 0;
Yves Gerey665174f2018-06-19 15:03:05 +020087 int video_frequency =
88 static_cast<int>(kDefaultVideoFrequency * video_clock_drift_ + 0.5);
asaperssonde9e5ff2016-11-02 07:14:03 -070089 bool new_sr;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000090 int video_offset = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +000091 StreamSynchronization::Measurements audio;
92 StreamSynchronization::Measurements video;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000093 // Generate NTP/RTP timestamp pair for both streams corresponding to RTCP.
asaperssonfe50b4d2016-12-22 07:53:51 -080094 NtpTime ntp_time = send_time_->GetNowNtp();
95 uint32_t rtp_timestamp =
96 send_time_->GetNowRtp(audio_frequency, audio_offset);
97 EXPECT_TRUE(audio.rtp_to_ntp.UpdateMeasurements(
98 ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +000099 send_time_->IncreaseTimeMs(100);
100 receive_time_->IncreaseTimeMs(100);
asaperssonfe50b4d2016-12-22 07:53:51 -0800101 ntp_time = send_time_->GetNowNtp();
102 rtp_timestamp = send_time_->GetNowRtp(video_frequency, video_offset);
103 EXPECT_TRUE(video.rtp_to_ntp.UpdateMeasurements(
104 ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000105 send_time_->IncreaseTimeMs(900);
106 receive_time_->IncreaseTimeMs(900);
asaperssonfe50b4d2016-12-22 07:53:51 -0800107 ntp_time = send_time_->GetNowNtp();
108 rtp_timestamp = send_time_->GetNowRtp(audio_frequency, audio_offset);
109 EXPECT_TRUE(audio.rtp_to_ntp.UpdateMeasurements(
110 ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000111 send_time_->IncreaseTimeMs(100);
112 receive_time_->IncreaseTimeMs(100);
asaperssonfe50b4d2016-12-22 07:53:51 -0800113 ntp_time = send_time_->GetNowNtp();
114 rtp_timestamp = send_time_->GetNowRtp(video_frequency, video_offset);
115 EXPECT_TRUE(video.rtp_to_ntp.UpdateMeasurements(
116 ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
asaperssonb7e7b492016-11-17 02:27:14 -0800117
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000118 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.
asaperssonb7e7b492016-11-17 02:27:14 -0800122 audio.latest_timestamp =
123 send_time_->GetNowRtp(audio_frequency, audio_offset);
124 video.latest_timestamp =
125 send_time_->GetNowRtp(video_frequency, 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);
Yves Gerey665174f2018-06-19 15:03:05 +0200144 return sync_->ComputeDelays(relative_delay_ms, current_audio_delay_ms,
145 extra_audio_delay_ms, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000146 }
147
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000148 // Simulate audio playback 300 ms after capture and video rendering 100 ms
149 // after capture. Verify that the correct extra delays are calculated for
150 // audio and video, and that they change correctly when we simulate that
151 // NetEQ or the VCM adds more delay to the streams.
152 // TODO(holmer): This is currently wrong! We should simply change
153 // audio_delay_ms or video_delay_ms since those now include VCM and NetEQ
154 // delays.
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000155 void BothDelayedAudioLaterTest(int base_target_delay) {
156 int current_audio_delay_ms = base_target_delay;
157 int audio_delay_ms = base_target_delay + 300;
158 int video_delay_ms = base_target_delay + 100;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000159 int extra_audio_delay_ms = 0;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000160 int total_video_delay_ms = base_target_delay;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000161 int filtered_move = (audio_delay_ms - video_delay_ms) / kSmoothingFilter;
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000162 const int kNeteqDelayIncrease = 50;
163 const int kNeteqDelayDecrease = 10;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000164
Yves Gerey665174f2018-06-19 15:03:05 +0200165 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
166 current_audio_delay_ms, &extra_audio_delay_ms,
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000167 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000168 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000169 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000170 current_audio_delay_ms = extra_audio_delay_ms;
171
172 send_time_->IncreaseTimeMs(1000);
Yves Gerey665174f2018-06-19 15:03:05 +0200173 receive_time_->IncreaseTimeMs(1000 -
174 std::max(audio_delay_ms, video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000175 // Simulate base_target_delay minimum delay in the VCM.
176 total_video_delay_ms = base_target_delay;
Yves Gerey665174f2018-06-19 15:03:05 +0200177 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
178 current_audio_delay_ms, &extra_audio_delay_ms,
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000179 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000180 EXPECT_EQ(base_target_delay + 2 * filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000181 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000182 current_audio_delay_ms = extra_audio_delay_ms;
183
184 send_time_->IncreaseTimeMs(1000);
Yves Gerey665174f2018-06-19 15:03:05 +0200185 receive_time_->IncreaseTimeMs(1000 -
186 std::max(audio_delay_ms, video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000187 // Simulate base_target_delay minimum delay in the VCM.
188 total_video_delay_ms = base_target_delay;
Yves Gerey665174f2018-06-19 15:03:05 +0200189 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
190 current_audio_delay_ms, &extra_audio_delay_ms,
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000191 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000192 EXPECT_EQ(base_target_delay + 3 * filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000193 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000194
195 // Simulate that NetEQ introduces some audio delay.
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000196 current_audio_delay_ms = base_target_delay + kNeteqDelayIncrease;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000197 send_time_->IncreaseTimeMs(1000);
Yves Gerey665174f2018-06-19 15:03:05 +0200198 receive_time_->IncreaseTimeMs(1000 -
199 std::max(audio_delay_ms, 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;
Yves Gerey665174f2018-06-19 15:03:05 +0200202 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
203 current_audio_delay_ms, &extra_audio_delay_ms,
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000204 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000205 filtered_move = 3 * filtered_move +
Yves Gerey665174f2018-06-19 15:03:05 +0200206 (kNeteqDelayIncrease + audio_delay_ms - video_delay_ms) /
207 kSmoothingFilter;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000208 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000209 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000210
211 // Simulate that NetEQ reduces its delay.
pwestin@webrtc.org4e545b32013-04-26 15:23:34 +0000212 current_audio_delay_ms = base_target_delay + kNeteqDelayDecrease;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000213 send_time_->IncreaseTimeMs(1000);
Yves Gerey665174f2018-06-19 15:03:05 +0200214 receive_time_->IncreaseTimeMs(1000 -
215 std::max(audio_delay_ms, video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000216 // Simulate base_target_delay minimum delay in the VCM.
217 total_video_delay_ms = base_target_delay;
Yves Gerey665174f2018-06-19 15:03:05 +0200218 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
219 current_audio_delay_ms, &extra_audio_delay_ms,
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000220 &total_video_delay_ms));
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000221
222 filtered_move = filtered_move +
Yves Gerey665174f2018-06-19 15:03:05 +0200223 (kNeteqDelayDecrease + audio_delay_ms - video_delay_ms) /
224 kSmoothingFilter;
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000225
226 EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000227 EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
228 }
229
230 void BothDelayedVideoLaterTest(int base_target_delay) {
231 int current_audio_delay_ms = base_target_delay;
232 int audio_delay_ms = base_target_delay + 100;
233 int video_delay_ms = base_target_delay + 300;
234 int extra_audio_delay_ms = 0;
235 int total_video_delay_ms = base_target_delay;
236
Yves Gerey665174f2018-06-19 15:03:05 +0200237 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
238 current_audio_delay_ms, &extra_audio_delay_ms,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000239 &total_video_delay_ms));
240 EXPECT_EQ(base_target_delay, total_video_delay_ms);
241 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000242 EXPECT_GE(base_target_delay + kMaxAudioDiffMs, extra_audio_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000243 current_audio_delay_ms = extra_audio_delay_ms;
244 int current_extra_delay_ms = extra_audio_delay_ms;
245
246 send_time_->IncreaseTimeMs(1000);
247 receive_time_->IncreaseTimeMs(800);
Yves Gerey665174f2018-06-19 15:03:05 +0200248 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
249 current_audio_delay_ms, &extra_audio_delay_ms,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000250 &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 the half of the
253 // required change in delay.
Yves Gerey665174f2018-06-19 15:03:05 +0200254 EXPECT_EQ(current_extra_delay_ms +
255 MaxAudioDelayIncrease(
256 current_audio_delay_ms,
257 base_target_delay + video_delay_ms - audio_delay_ms),
258 extra_audio_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000259 current_audio_delay_ms = extra_audio_delay_ms;
260 current_extra_delay_ms = extra_audio_delay_ms;
261
262 send_time_->IncreaseTimeMs(1000);
263 receive_time_->IncreaseTimeMs(800);
Yves Gerey665174f2018-06-19 15:03:05 +0200264 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
265 current_audio_delay_ms, &extra_audio_delay_ms,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000266 &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.
Yves Gerey665174f2018-06-19 15:03:05 +0200270 EXPECT_EQ(current_extra_delay_ms +
271 MaxAudioDelayIncrease(
272 current_audio_delay_ms,
273 base_target_delay + video_delay_ms - audio_delay_ms),
274 extra_audio_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000275 current_extra_delay_ms = extra_audio_delay_ms;
276
277 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000278 current_audio_delay_ms = base_target_delay + 10;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000279 send_time_->IncreaseTimeMs(1000);
280 receive_time_->IncreaseTimeMs(800);
Yves Gerey665174f2018-06-19 15:03:05 +0200281 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
282 current_audio_delay_ms, &extra_audio_delay_ms,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000283 &total_video_delay_ms));
284 EXPECT_EQ(base_target_delay, total_video_delay_ms);
285 // Since we only can ask NetEQ for a certain amount of extra delay, and
286 // we only measure the total NetEQ delay, we will ask for additional delay
287 // here to try to stay in sync.
Yves Gerey665174f2018-06-19 15:03:05 +0200288 EXPECT_EQ(current_extra_delay_ms +
289 MaxAudioDelayIncrease(
290 current_audio_delay_ms,
291 base_target_delay + video_delay_ms - audio_delay_ms),
292 extra_audio_delay_ms);
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000293 current_extra_delay_ms = extra_audio_delay_ms;
294
295 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000296 current_audio_delay_ms = base_target_delay + 350;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000297 send_time_->IncreaseTimeMs(1000);
298 receive_time_->IncreaseTimeMs(800);
Yves Gerey665174f2018-06-19 15:03:05 +0200299 EXPECT_TRUE(DelayedStreams(audio_delay_ms, video_delay_ms,
300 current_audio_delay_ms, &extra_audio_delay_ms,
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000301 &total_video_delay_ms));
302 EXPECT_EQ(base_target_delay, total_video_delay_ms);
303 // The audio delay is not allowed to change more than the half of the
304 // required change in delay.
Yves Gerey665174f2018-06-19 15:03:05 +0200305 EXPECT_EQ(current_extra_delay_ms +
306 MaxAudioDelayIncrease(
307 current_audio_delay_ms,
308 base_target_delay + video_delay_ms - audio_delay_ms),
309 extra_audio_delay_ms);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000310 }
311
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000312 int MaxAudioDelayIncrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000313 return std::min((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
Yves Gerey665174f2018-06-19 15:03:05 +0200314 static_cast<int>(kMaxAudioDiffMs));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000315 }
316
317 int MaxAudioDelayDecrease(int current_audio_delay_ms, int delay_ms) {
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000318 return std::max((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
319 -kMaxAudioDiffMs);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000320 }
321
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000322 enum { kSendTimeOffsetMs = 98765 };
323 enum { kReceiveTimeOffsetMs = 43210 };
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000324
325 StreamSynchronization* sync_;
Yves Gerey665174f2018-06-19 15:03:05 +0200326 Time* send_time_; // The simulated clock at the sender.
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000327 Time* receive_time_; // The simulated clock at the receiver.
328 double audio_clock_drift_;
329 double video_clock_drift_;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000330};
331
332TEST_F(StreamSynchronizationTest, NoDelay) {
333 uint32_t current_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000334 int extra_audio_delay_ms = 0;
335 int total_video_delay_ms = 0;
336
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000337 EXPECT_FALSE(DelayedStreams(0, 0, current_audio_delay_ms,
338 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000339 EXPECT_EQ(0, extra_audio_delay_ms);
340 EXPECT_EQ(0, total_video_delay_ms);
341}
342
343TEST_F(StreamSynchronizationTest, VideoDelay) {
344 uint32_t current_audio_delay_ms = 0;
345 int delay_ms = 200;
346 int extra_audio_delay_ms = 0;
347 int total_video_delay_ms = 0;
348
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000349 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
350 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000351 EXPECT_EQ(0, extra_audio_delay_ms);
352 // The video delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000353 EXPECT_EQ(delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000354
355 send_time_->IncreaseTimeMs(1000);
356 receive_time_->IncreaseTimeMs(800);
357 // Simulate 0 minimum delay in the VCM.
358 total_video_delay_ms = 0;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000359 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
360 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000361 EXPECT_EQ(0, extra_audio_delay_ms);
362 // The video delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000363 EXPECT_EQ(2 * delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000364
365 send_time_->IncreaseTimeMs(1000);
366 receive_time_->IncreaseTimeMs(800);
367 // Simulate 0 minimum delay in the VCM.
368 total_video_delay_ms = 0;
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000369 EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
370 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000371 EXPECT_EQ(0, extra_audio_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000372 EXPECT_EQ(3 * delay_ms / kSmoothingFilter, total_video_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000373}
374
375TEST_F(StreamSynchronizationTest, AudioDelay) {
376 int current_audio_delay_ms = 0;
377 int delay_ms = 200;
378 int extra_audio_delay_ms = 0;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000379 int total_video_delay_ms = 0;
380
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000381 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
382 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000383 EXPECT_EQ(0, total_video_delay_ms);
384 // The audio delay is not allowed to change more than this in 1 second.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000385 EXPECT_EQ(delay_ms / kSmoothingFilter, extra_audio_delay_ms);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000386 current_audio_delay_ms = extra_audio_delay_ms;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000387 int current_extra_delay_ms = extra_audio_delay_ms;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000388
389 send_time_->IncreaseTimeMs(1000);
390 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000391 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
392 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000393 EXPECT_EQ(0, total_video_delay_ms);
394 // The audio delay is not allowed to change more than the half of the required
395 // change in delay.
396 EXPECT_EQ(current_extra_delay_ms +
Yves Gerey665174f2018-06-19 15:03:05 +0200397 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000398 extra_audio_delay_ms);
399 current_audio_delay_ms = extra_audio_delay_ms;
400 current_extra_delay_ms = extra_audio_delay_ms;
401
402 send_time_->IncreaseTimeMs(1000);
403 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000404 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
405 &extra_audio_delay_ms, &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 +
Yves Gerey665174f2018-06-19 15:03:05 +0200410 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000411 extra_audio_delay_ms);
412 current_extra_delay_ms = extra_audio_delay_ms;
413
414 // Simulate that NetEQ for some reason reduced the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000415 current_audio_delay_ms = 10;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000416 send_time_->IncreaseTimeMs(1000);
417 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000418 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
419 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000420 EXPECT_EQ(0, total_video_delay_ms);
421 // Since we only can ask NetEQ for a certain amount of extra delay, and
422 // we only measure the total NetEQ delay, we will ask for additional delay
423 // here to try to
424 EXPECT_EQ(current_extra_delay_ms +
Yves Gerey665174f2018-06-19 15:03:05 +0200425 MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000426 extra_audio_delay_ms);
427 current_extra_delay_ms = extra_audio_delay_ms;
428
429 // Simulate that NetEQ for some reason significantly increased the delay.
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000430 current_audio_delay_ms = 350;
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000431 send_time_->IncreaseTimeMs(1000);
432 receive_time_->IncreaseTimeMs(800);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000433 EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
434 &extra_audio_delay_ms, &total_video_delay_ms));
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000435 EXPECT_EQ(0, total_video_delay_ms);
436 // The audio delay is not allowed to change more than the half of the required
437 // change in delay.
438 EXPECT_EQ(current_extra_delay_ms +
Yves Gerey665174f2018-06-19 15:03:05 +0200439 MaxAudioDelayDecrease(current_audio_delay_ms, delay_ms),
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000440 extra_audio_delay_ms);
441}
442
443TEST_F(StreamSynchronizationTest, BothDelayedVideoLater) {
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000444 BothDelayedVideoLaterTest(0);
445}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000446
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000447TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterAudioClockDrift) {
448 audio_clock_drift_ = 1.05;
449 BothDelayedVideoLaterTest(0);
450}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000451
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000452TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterVideoClockDrift) {
453 video_clock_drift_ = 1.05;
454 BothDelayedVideoLaterTest(0);
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000455}
456
457TEST_F(StreamSynchronizationTest, BothDelayedAudioLater) {
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000458 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000459}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000460
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000461TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDrift) {
462 audio_clock_drift_ = 1.05;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000463 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000464}
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000465
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000466TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDrift) {
467 video_clock_drift_ = 1.05;
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000468 BothDelayedAudioLaterTest(0);
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000469}
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000470
471TEST_F(StreamSynchronizationTest, BaseDelay) {
472 int base_target_delay_ms = 2000;
473 int current_audio_delay_ms = 2000;
474 int extra_audio_delay_ms = 0;
475 int total_video_delay_ms = base_target_delay_ms;
476 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000477 // We are in sync don't change.
478 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
Yves Gerey665174f2018-06-19 15:03:05 +0200479 current_audio_delay_ms, &extra_audio_delay_ms,
480 &total_video_delay_ms));
mikhal@webrtc.org0d8d0102013-02-22 19:30:44 +0000481 // Triggering another call with the same values. Delay should not be modified.
482 base_target_delay_ms = 2000;
483 current_audio_delay_ms = base_target_delay_ms;
484 total_video_delay_ms = base_target_delay_ms;
485 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000486 // We are in sync don't change.
487 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
Yves Gerey665174f2018-06-19 15:03:05 +0200488 current_audio_delay_ms, &extra_audio_delay_ms,
489 &total_video_delay_ms));
mikhal@webrtc.org0d8d0102013-02-22 19:30:44 +0000490 // Changing delay value - intended to test this module only. In practice it
491 // would take VoE time to adapt.
492 base_target_delay_ms = 5000;
493 current_audio_delay_ms = base_target_delay_ms;
494 total_video_delay_ms = base_target_delay_ms;
495 sync_->SetTargetBufferingDelay(base_target_delay_ms);
pwestin@webrtc.org63117332013-04-22 18:57:14 +0000496 // We are in sync don't change.
497 EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
Yves Gerey665174f2018-06-19 15:03:05 +0200498 current_audio_delay_ms, &extra_audio_delay_ms,
499 &total_video_delay_ms));
mikhal@webrtc.orgef9f76a2013-02-15 23:22:18 +0000500}
501
502TEST_F(StreamSynchronizationTest, BothDelayedAudioLaterWithBaseDelay) {
503 int base_target_delay_ms = 3000;
504 sync_->SetTargetBufferingDelay(base_target_delay_ms);
505 BothDelayedAudioLaterTest(base_target_delay_ms);
506}
507
508TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDriftWithBaseDelay) {
509 int base_target_delay_ms = 3000;
510 sync_->SetTargetBufferingDelay(base_target_delay_ms);
511 audio_clock_drift_ = 1.05;
512 BothDelayedAudioLaterTest(base_target_delay_ms);
513}
514
515TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDriftWithBaseDelay) {
516 int base_target_delay_ms = 3000;
517 sync_->SetTargetBufferingDelay(base_target_delay_ms);
518 video_clock_drift_ = 1.05;
519 BothDelayedAudioLaterTest(base_target_delay_ms);
520}
521
522TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterWithBaseDelay) {
523 int base_target_delay_ms = 2000;
524 sync_->SetTargetBufferingDelay(base_target_delay_ms);
525 BothDelayedVideoLaterTest(base_target_delay_ms);
526}
527
528TEST_F(StreamSynchronizationTest,
529 BothDelayedVideoLaterAudioClockDriftWithBaseDelay) {
530 int base_target_delay_ms = 2000;
531 audio_clock_drift_ = 1.05;
532 sync_->SetTargetBufferingDelay(base_target_delay_ms);
533 BothDelayedVideoLaterTest(base_target_delay_ms);
534}
535
536TEST_F(StreamSynchronizationTest,
537 BothDelayedVideoLaterVideoClockDriftWithBaseDelay) {
538 int base_target_delay_ms = 2000;
539 video_clock_drift_ = 1.05;
540 sync_->SetTargetBufferingDelay(base_target_delay_ms);
541 BothDelayedVideoLaterTest(base_target_delay_ms);
542}
543
stefan@webrtc.org5f284982012-06-28 07:51:16 +0000544} // namespace webrtc