blob: 575dd706b5683b40ac9e9b4f0d3d79a6ea44caa2 [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
Karl Wiberg5817d3d2018-04-06 10:06:42 +020013#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Mirko Bonadei71207422017-09-15 13:58:09 +020014#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
16#include "modules/audio_coding/include/audio_coding_module.h"
17#include "modules/audio_coding/test/utility.h"
18#include "modules/include/module_common_types.h"
19#include "test/gtest.h"
20#include "test/testsupport/fileutils.h"
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000021
22namespace webrtc {
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000023
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +000024class TargetDelayTest : public ::testing::Test {
25 protected:
Karl Wiberg5817d3d2018-04-06 10:06:42 +020026 TargetDelayTest()
27 : acm_(AudioCodingModule::Create(
28 AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))) {}
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000029
30 ~TargetDelayTest() {}
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000031
32 void SetUp() {
andrew@webrtc.org89df0922013-09-12 01:27:43 +000033 EXPECT_TRUE(acm_.get() != NULL);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000034
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000035 ASSERT_EQ(0, acm_->InitializeReceiver());
kwibergda2bf4e2016-10-24 13:47:09 -070036 constexpr int pltype = 108;
37 ASSERT_EQ(true,
38 acm_->RegisterReceiveCodec(pltype, {"L16", kSampleRateHz, 1}));
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000039
kwibergda2bf4e2016-10-24 13:47:09 -070040 rtp_info_.header.payloadType = pltype;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000041 rtp_info_.header.timestamp = 0;
42 rtp_info_.header.ssrc = 0x12345678;
43 rtp_info_.header.markerBit = false;
44 rtp_info_.header.sequenceNumber = 0;
45 rtp_info_.type.Audio.channel = 1;
46 rtp_info_.type.Audio.isCNG = false;
47 rtp_info_.frameType = kAudioFrameSpeech;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000048
49 int16_t audio[kFrameSizeSamples];
50 const int kRange = 0x7FF; // 2047, easy for masking.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000051 for (size_t n = 0; n < kFrameSizeSamples; ++n)
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000052 audio[n] = (rand() & kRange) - kRange / 2;
53 WebRtcPcm16b_Encode(audio, kFrameSizeSamples, payload_);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000054 }
55
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000056 void OutOfRangeInput() {
57 EXPECT_EQ(-1, SetMinimumDelay(-1));
58 EXPECT_EQ(-1, SetMinimumDelay(10001));
59 }
60
61 void NoTargetDelayBufferSizeChanges() {
62 for (int n = 0; n < 30; ++n) // Run enough iterations.
63 Run(true);
64 int clean_optimal_delay = GetCurrentOptimalDelayMs();
65 Run(false); // Run with jitter.
66 int jittery_optimal_delay = GetCurrentOptimalDelayMs();
67 EXPECT_GT(jittery_optimal_delay, clean_optimal_delay);
68 int required_delay = RequiredDelay();
69 EXPECT_GT(required_delay, 0);
70 EXPECT_NEAR(required_delay, jittery_optimal_delay, 1);
71 }
72
73 void WithTargetDelayBufferNotChanging() {
74 // A target delay that is one packet larger than jitter.
75 const int kTargetDelayMs = (kInterarrivalJitterPacket + 1) *
76 kNum10msPerFrame * 10;
77 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs));
78 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer.
79 Run(true);
80 int clean_optimal_delay = GetCurrentOptimalDelayMs();
81 EXPECT_EQ(kTargetDelayMs, clean_optimal_delay);
82 Run(false); // Run with jitter.
83 int jittery_optimal_delay = GetCurrentOptimalDelayMs();
84 EXPECT_EQ(jittery_optimal_delay, clean_optimal_delay);
85 }
86
87 void RequiredDelayAtCorrectRange() {
88 for (int n = 0; n < 30; ++n) // Run clean and store delay.
89 Run(true);
90 int clean_optimal_delay = GetCurrentOptimalDelayMs();
91
92 // A relatively large delay.
93 const int kTargetDelayMs = (kInterarrivalJitterPacket + 10) *
94 kNum10msPerFrame * 10;
95 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs));
96 for (int n = 0; n < 300; ++n) // Run enough iterations to fill the buffer.
97 Run(true);
98 Run(false); // Run with jitter.
99
100 int jittery_optimal_delay = GetCurrentOptimalDelayMs();
101 EXPECT_EQ(kTargetDelayMs, jittery_optimal_delay);
102
103 int required_delay = RequiredDelay();
104
105 // Checking |required_delay| is in correct range.
106 EXPECT_GT(required_delay, 0);
107 EXPECT_GT(jittery_optimal_delay, required_delay);
108 EXPECT_GT(required_delay, clean_optimal_delay);
109
110 // A tighter check for the value of |required_delay|.
111 // The jitter forces a delay of
112 // |kInterarrivalJitterPacket * kNum10msPerFrame * 10| milliseconds. So we
113 // expect |required_delay| be close to that.
114 EXPECT_NEAR(kInterarrivalJitterPacket * kNum10msPerFrame * 10,
115 required_delay, 1);
116 }
117
118 void TargetDelayBufferMinMax() {
119 const int kTargetMinDelayMs = kNum10msPerFrame * 10;
120 ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs));
121 for (int m = 0; m < 30; ++m) // Run enough iterations to fill the buffer.
122 Run(true);
123 int clean_optimal_delay = GetCurrentOptimalDelayMs();
124 EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay);
125
126 const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10);
127 ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs));
128 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer.
129 Run(false);
130
131 int capped_optimal_delay = GetCurrentOptimalDelayMs();
132 EXPECT_EQ(kTargetMaxDelayMs, capped_optimal_delay);
133 }
134
135 private:
136 static const int kSampleRateHz = 16000;
137 static const int kNum10msPerFrame = 2;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000138 static const size_t kFrameSizeSamples = 320; // 20 ms @ 16 kHz.
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000139 // payload-len = frame-samples * 2 bytes/sample.
140 static const int kPayloadLenBytes = 320 * 2;
141 // Inter-arrival time in number of packets in a jittery channel. One is no
142 // jitter.
143 static const int kInterarrivalJitterPacket = 2;
144
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000145 void Push() {
146 rtp_info_.header.timestamp += kFrameSizeSamples;
147 rtp_info_.header.sequenceNumber++;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000148 ASSERT_EQ(0, acm_->IncomingPacket(payload_, kFrameSizeSamples * 2,
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000149 rtp_info_));
150 }
151
152 // Pull audio equivalent to the amount of audio in one RTP packet.
153 void Pull() {
154 AudioFrame frame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700155 bool muted;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000156 for (int k = 0; k < kNum10msPerFrame; ++k) { // Pull one frame.
henrik.lundind4ccb002016-05-17 12:21:55 -0700157 ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &frame, &muted));
158 ASSERT_FALSE(muted);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000159 // Had to use ASSERT_TRUE, ASSERT_EQ generated error.
160 ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_);
Peter Kasting69558702016-01-12 16:26:35 -0800161 ASSERT_EQ(1u, frame.num_channels_);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000162 ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_);
163 }
164 }
165
166 void Run(bool clean) {
167 for (int n = 0; n < 10; ++n) {
168 for (int m = 0; m < 5; ++m) {
169 Push();
170 Pull();
171 }
172
173 if (!clean) {
174 for (int m = 0; m < 10; ++m) { // Long enough to trigger delay change.
175 Push();
176 for (int n = 0; n < kInterarrivalJitterPacket; ++n)
177 Pull();
178 }
179 }
180 }
181 }
182
183 int SetMinimumDelay(int delay_ms) {
184 return acm_->SetMinimumPlayoutDelay(delay_ms);
185 }
186
pwestin@webrtc.org401ef362013-08-06 21:01:36 +0000187 int SetMaximumDelay(int delay_ms) {
188 return acm_->SetMaximumPlayoutDelay(delay_ms);
189 }
190
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000191 int GetCurrentOptimalDelayMs() {
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000192 NetworkStatistics stats;
193 acm_->GetNetworkStatistics(&stats);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000194 return stats.preferredBufferSize;
195 }
196
197 int RequiredDelay() {
198 return acm_->LeastRequiredDelayMs();
199 }
200
kwiberg37478382016-02-14 20:40:57 -0800201 std::unique_ptr<AudioCodingModule> acm_;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000202 WebRtcRTPHeader rtp_info_;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000203 uint8_t payload_[kPayloadLenBytes];
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000204};
205
kjellanderb7d24f62017-02-26 22:10:14 -0800206// Flaky on iOS: webrtc:7057.
207#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100208#define MAYBE_OutOfRangeInput DISABLED_OutOfRangeInput
209#else
210#define MAYBE_OutOfRangeInput OutOfRangeInput
211#endif
212TEST_F(TargetDelayTest, MAYBE_OutOfRangeInput) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000213 OutOfRangeInput();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000214}
215
kjellanderb7d24f62017-02-26 22:10:14 -0800216// Flaky on iOS: webrtc:7057.
217#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100218#define MAYBE_NoTargetDelayBufferSizeChanges \
219 DISABLED_NoTargetDelayBufferSizeChanges
220#else
221#define MAYBE_NoTargetDelayBufferSizeChanges NoTargetDelayBufferSizeChanges
222#endif
223TEST_F(TargetDelayTest, MAYBE_NoTargetDelayBufferSizeChanges) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000224 NoTargetDelayBufferSizeChanges();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000225}
226
kjellanderb7d24f62017-02-26 22:10:14 -0800227// Flaky on iOS: webrtc:7057.
228#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100229#define MAYBE_WithTargetDelayBufferNotChanging \
230 DISABLED_WithTargetDelayBufferNotChanging
231#else
232#define MAYBE_WithTargetDelayBufferNotChanging WithTargetDelayBufferNotChanging
233#endif
234TEST_F(TargetDelayTest, MAYBE_WithTargetDelayBufferNotChanging) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000235 WithTargetDelayBufferNotChanging();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000236}
237
kjellanderb7d24f62017-02-26 22:10:14 -0800238// Flaky on iOS: webrtc:7057.
239#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100240#define MAYBE_RequiredDelayAtCorrectRange DISABLED_RequiredDelayAtCorrectRange
241#else
242#define MAYBE_RequiredDelayAtCorrectRange RequiredDelayAtCorrectRange
243#endif
244TEST_F(TargetDelayTest, MAYBE_RequiredDelayAtCorrectRange) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000245 RequiredDelayAtCorrectRange();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000246}
247
kjellanderb7d24f62017-02-26 22:10:14 -0800248// Flaky on iOS: webrtc:7057.
249#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100250#define MAYBE_TargetDelayBufferMinMax DISABLED_TargetDelayBufferMinMax
251#else
252#define MAYBE_TargetDelayBufferMinMax TargetDelayBufferMinMax
253#endif
254TEST_F(TargetDelayTest, MAYBE_TargetDelayBufferMinMax) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000255 TargetDelayBufferMinMax();
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000256}
257
258} // namespace webrtc