blob: 89bf34f43be15e4505ea68400e9537fcae8f52ef [file] [log] [blame]
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +00001/*
2 * Copyright (c) 2013 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
kwiberg37478382016-02-14 20:40:57 -080011#include <memory>
12
Fredrik Solenbergbbf21a32018-04-12 22:44:09 +020013#include "api/audio/audio_frame.h"
Karl Wiberg5817d3d2018-04-06 10:06:42 +020014#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Mirko Bonadei71207422017-09-15 13:58:09 +020015#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
17#include "modules/audio_coding/include/audio_coding_module.h"
18#include "modules/audio_coding/test/utility.h"
19#include "modules/include/module_common_types.h"
20#include "test/gtest.h"
21#include "test/testsupport/fileutils.h"
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000022
23namespace webrtc {
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000024
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +000025class TargetDelayTest : public ::testing::Test {
26 protected:
Karl Wiberg5817d3d2018-04-06 10:06:42 +020027 TargetDelayTest()
28 : acm_(AudioCodingModule::Create(
29 AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))) {}
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000030
31 ~TargetDelayTest() {}
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000032
33 void SetUp() {
andrew@webrtc.org89df0922013-09-12 01:27:43 +000034 EXPECT_TRUE(acm_.get() != NULL);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000035
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000036 ASSERT_EQ(0, acm_->InitializeReceiver());
kwibergda2bf4e2016-10-24 13:47:09 -070037 constexpr int pltype = 108;
38 ASSERT_EQ(true,
39 acm_->RegisterReceiveCodec(pltype, {"L16", kSampleRateHz, 1}));
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000040
kwibergda2bf4e2016-10-24 13:47:09 -070041 rtp_info_.header.payloadType = pltype;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000042 rtp_info_.header.timestamp = 0;
43 rtp_info_.header.ssrc = 0x12345678;
44 rtp_info_.header.markerBit = false;
45 rtp_info_.header.sequenceNumber = 0;
46 rtp_info_.type.Audio.channel = 1;
47 rtp_info_.type.Audio.isCNG = false;
48 rtp_info_.frameType = kAudioFrameSpeech;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000049
50 int16_t audio[kFrameSizeSamples];
51 const int kRange = 0x7FF; // 2047, easy for masking.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000052 for (size_t n = 0; n < kFrameSizeSamples; ++n)
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000053 audio[n] = (rand() & kRange) - kRange / 2;
54 WebRtcPcm16b_Encode(audio, kFrameSizeSamples, payload_);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000055 }
56
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000057 void OutOfRangeInput() {
58 EXPECT_EQ(-1, SetMinimumDelay(-1));
59 EXPECT_EQ(-1, SetMinimumDelay(10001));
60 }
61
62 void NoTargetDelayBufferSizeChanges() {
63 for (int n = 0; n < 30; ++n) // Run enough iterations.
64 Run(true);
65 int clean_optimal_delay = GetCurrentOptimalDelayMs();
66 Run(false); // Run with jitter.
67 int jittery_optimal_delay = GetCurrentOptimalDelayMs();
68 EXPECT_GT(jittery_optimal_delay, clean_optimal_delay);
69 int required_delay = RequiredDelay();
70 EXPECT_GT(required_delay, 0);
71 EXPECT_NEAR(required_delay, jittery_optimal_delay, 1);
72 }
73
74 void WithTargetDelayBufferNotChanging() {
75 // A target delay that is one packet larger than jitter.
76 const int kTargetDelayMs = (kInterarrivalJitterPacket + 1) *
77 kNum10msPerFrame * 10;
78 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs));
79 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer.
80 Run(true);
81 int clean_optimal_delay = GetCurrentOptimalDelayMs();
82 EXPECT_EQ(kTargetDelayMs, clean_optimal_delay);
83 Run(false); // Run with jitter.
84 int jittery_optimal_delay = GetCurrentOptimalDelayMs();
85 EXPECT_EQ(jittery_optimal_delay, clean_optimal_delay);
86 }
87
88 void RequiredDelayAtCorrectRange() {
89 for (int n = 0; n < 30; ++n) // Run clean and store delay.
90 Run(true);
91 int clean_optimal_delay = GetCurrentOptimalDelayMs();
92
93 // A relatively large delay.
94 const int kTargetDelayMs = (kInterarrivalJitterPacket + 10) *
95 kNum10msPerFrame * 10;
96 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs));
97 for (int n = 0; n < 300; ++n) // Run enough iterations to fill the buffer.
98 Run(true);
99 Run(false); // Run with jitter.
100
101 int jittery_optimal_delay = GetCurrentOptimalDelayMs();
102 EXPECT_EQ(kTargetDelayMs, jittery_optimal_delay);
103
104 int required_delay = RequiredDelay();
105
106 // Checking |required_delay| is in correct range.
107 EXPECT_GT(required_delay, 0);
108 EXPECT_GT(jittery_optimal_delay, required_delay);
109 EXPECT_GT(required_delay, clean_optimal_delay);
110
111 // A tighter check for the value of |required_delay|.
112 // The jitter forces a delay of
113 // |kInterarrivalJitterPacket * kNum10msPerFrame * 10| milliseconds. So we
114 // expect |required_delay| be close to that.
115 EXPECT_NEAR(kInterarrivalJitterPacket * kNum10msPerFrame * 10,
116 required_delay, 1);
117 }
118
119 void TargetDelayBufferMinMax() {
120 const int kTargetMinDelayMs = kNum10msPerFrame * 10;
121 ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs));
122 for (int m = 0; m < 30; ++m) // Run enough iterations to fill the buffer.
123 Run(true);
124 int clean_optimal_delay = GetCurrentOptimalDelayMs();
125 EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay);
126
127 const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10);
128 ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs));
129 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer.
130 Run(false);
131
132 int capped_optimal_delay = GetCurrentOptimalDelayMs();
133 EXPECT_EQ(kTargetMaxDelayMs, capped_optimal_delay);
134 }
135
136 private:
137 static const int kSampleRateHz = 16000;
138 static const int kNum10msPerFrame = 2;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000139 static const size_t kFrameSizeSamples = 320; // 20 ms @ 16 kHz.
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000140 // payload-len = frame-samples * 2 bytes/sample.
141 static const int kPayloadLenBytes = 320 * 2;
142 // Inter-arrival time in number of packets in a jittery channel. One is no
143 // jitter.
144 static const int kInterarrivalJitterPacket = 2;
145
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000146 void Push() {
147 rtp_info_.header.timestamp += kFrameSizeSamples;
148 rtp_info_.header.sequenceNumber++;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000149 ASSERT_EQ(0, acm_->IncomingPacket(payload_, kFrameSizeSamples * 2,
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000150 rtp_info_));
151 }
152
153 // Pull audio equivalent to the amount of audio in one RTP packet.
154 void Pull() {
155 AudioFrame frame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700156 bool muted;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000157 for (int k = 0; k < kNum10msPerFrame; ++k) { // Pull one frame.
henrik.lundind4ccb002016-05-17 12:21:55 -0700158 ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &frame, &muted));
159 ASSERT_FALSE(muted);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000160 // Had to use ASSERT_TRUE, ASSERT_EQ generated error.
161 ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_);
Peter Kasting69558702016-01-12 16:26:35 -0800162 ASSERT_EQ(1u, frame.num_channels_);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000163 ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_);
164 }
165 }
166
167 void Run(bool clean) {
168 for (int n = 0; n < 10; ++n) {
169 for (int m = 0; m < 5; ++m) {
170 Push();
171 Pull();
172 }
173
174 if (!clean) {
175 for (int m = 0; m < 10; ++m) { // Long enough to trigger delay change.
176 Push();
177 for (int n = 0; n < kInterarrivalJitterPacket; ++n)
178 Pull();
179 }
180 }
181 }
182 }
183
184 int SetMinimumDelay(int delay_ms) {
185 return acm_->SetMinimumPlayoutDelay(delay_ms);
186 }
187
pwestin@webrtc.org401ef362013-08-06 21:01:36 +0000188 int SetMaximumDelay(int delay_ms) {
189 return acm_->SetMaximumPlayoutDelay(delay_ms);
190 }
191
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000192 int GetCurrentOptimalDelayMs() {
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000193 NetworkStatistics stats;
194 acm_->GetNetworkStatistics(&stats);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000195 return stats.preferredBufferSize;
196 }
197
198 int RequiredDelay() {
199 return acm_->LeastRequiredDelayMs();
200 }
201
kwiberg37478382016-02-14 20:40:57 -0800202 std::unique_ptr<AudioCodingModule> acm_;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000203 WebRtcRTPHeader rtp_info_;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000204 uint8_t payload_[kPayloadLenBytes];
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000205};
206
kjellanderb7d24f62017-02-26 22:10:14 -0800207// Flaky on iOS: webrtc:7057.
208#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100209#define MAYBE_OutOfRangeInput DISABLED_OutOfRangeInput
210#else
211#define MAYBE_OutOfRangeInput OutOfRangeInput
212#endif
213TEST_F(TargetDelayTest, MAYBE_OutOfRangeInput) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000214 OutOfRangeInput();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000215}
216
kjellanderb7d24f62017-02-26 22:10:14 -0800217// Flaky on iOS: webrtc:7057.
218#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100219#define MAYBE_NoTargetDelayBufferSizeChanges \
220 DISABLED_NoTargetDelayBufferSizeChanges
221#else
222#define MAYBE_NoTargetDelayBufferSizeChanges NoTargetDelayBufferSizeChanges
223#endif
224TEST_F(TargetDelayTest, MAYBE_NoTargetDelayBufferSizeChanges) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000225 NoTargetDelayBufferSizeChanges();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000226}
227
kjellanderb7d24f62017-02-26 22:10:14 -0800228// Flaky on iOS: webrtc:7057.
229#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100230#define MAYBE_WithTargetDelayBufferNotChanging \
231 DISABLED_WithTargetDelayBufferNotChanging
232#else
233#define MAYBE_WithTargetDelayBufferNotChanging WithTargetDelayBufferNotChanging
234#endif
235TEST_F(TargetDelayTest, MAYBE_WithTargetDelayBufferNotChanging) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000236 WithTargetDelayBufferNotChanging();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000237}
238
kjellanderb7d24f62017-02-26 22:10:14 -0800239// Flaky on iOS: webrtc:7057.
240#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100241#define MAYBE_RequiredDelayAtCorrectRange DISABLED_RequiredDelayAtCorrectRange
242#else
243#define MAYBE_RequiredDelayAtCorrectRange RequiredDelayAtCorrectRange
244#endif
245TEST_F(TargetDelayTest, MAYBE_RequiredDelayAtCorrectRange) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000246 RequiredDelayAtCorrectRange();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000247}
248
kjellanderb7d24f62017-02-26 22:10:14 -0800249// Flaky on iOS: webrtc:7057.
250#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100251#define MAYBE_TargetDelayBufferMinMax DISABLED_TargetDelayBufferMinMax
252#else
253#define MAYBE_TargetDelayBufferMinMax TargetDelayBufferMinMax
254#endif
255TEST_F(TargetDelayTest, MAYBE_TargetDelayBufferMinMax) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000256 TargetDelayBufferMinMax();
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000257}
258
259} // namespace webrtc