blob: 77a2e5a456a2e15980c932cb15bbe456692dc990 [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"
Niels Möller5ceb4ac2019-08-13 15:54:15 +020015#include "modules/audio_coding/acm2/acm_receiver.h"
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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "modules/include/module_common_types.h"
19#include "test/gtest.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "test/testsupport/file_utils.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()
Niels Möller5ceb4ac2019-08-13 15:54:15 +020027 : receiver_(
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() {
kwibergda2bf4e2016-10-24 13:47:09 -070033 constexpr int pltype = 108;
Jonas Olssona4d87372019-07-05 19:08:33 +020034 std::map<int, SdpAudioFormat> receive_codecs = {
35 {pltype, {"L16", kSampleRateHz, 1}}};
Niels Möller5ceb4ac2019-08-13 15:54:15 +020036 receiver_.SetCodecs(receive_codecs);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000037
Niels Möllerafb5dbb2019-02-15 15:21:47 +010038 rtp_header_.payloadType = pltype;
39 rtp_header_.timestamp = 0;
40 rtp_header_.ssrc = 0x12345678;
41 rtp_header_.markerBit = false;
42 rtp_header_.sequenceNumber = 0;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000043
44 int16_t audio[kFrameSizeSamples];
45 const int kRange = 0x7FF; // 2047, easy for masking.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000046 for (size_t n = 0; n < kFrameSizeSamples; ++n)
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000047 audio[n] = (rand() & kRange) - kRange / 2;
48 WebRtcPcm16b_Encode(audio, kFrameSizeSamples, payload_);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000049 }
50
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000051 void OutOfRangeInput() {
52 EXPECT_EQ(-1, SetMinimumDelay(-1));
53 EXPECT_EQ(-1, SetMinimumDelay(10001));
54 }
55
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000056 void WithTargetDelayBufferNotChanging() {
57 // A target delay that is one packet larger than jitter.
Yves Gerey665174f2018-06-19 15:03:05 +020058 const int kTargetDelayMs =
59 (kInterarrivalJitterPacket + 1) * kNum10msPerFrame * 10;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000060 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs));
61 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer.
62 Run(true);
63 int clean_optimal_delay = GetCurrentOptimalDelayMs();
64 EXPECT_EQ(kTargetDelayMs, clean_optimal_delay);
65 Run(false); // Run with jitter.
66 int jittery_optimal_delay = GetCurrentOptimalDelayMs();
67 EXPECT_EQ(jittery_optimal_delay, clean_optimal_delay);
68 }
69
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000070 void TargetDelayBufferMinMax() {
71 const int kTargetMinDelayMs = kNum10msPerFrame * 10;
72 ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs));
73 for (int m = 0; m < 30; ++m) // Run enough iterations to fill the buffer.
74 Run(true);
75 int clean_optimal_delay = GetCurrentOptimalDelayMs();
76 EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay);
77
78 const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10);
79 ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs));
80 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer.
81 Run(false);
82
83 int capped_optimal_delay = GetCurrentOptimalDelayMs();
84 EXPECT_EQ(kTargetMaxDelayMs, capped_optimal_delay);
85 }
86
87 private:
88 static const int kSampleRateHz = 16000;
89 static const int kNum10msPerFrame = 2;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000090 static const size_t kFrameSizeSamples = 320; // 20 ms @ 16 kHz.
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000091 // payload-len = frame-samples * 2 bytes/sample.
92 static const int kPayloadLenBytes = 320 * 2;
93 // Inter-arrival time in number of packets in a jittery channel. One is no
94 // jitter.
95 static const int kInterarrivalJitterPacket = 2;
96
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000097 void Push() {
Niels Möllerafb5dbb2019-02-15 15:21:47 +010098 rtp_header_.timestamp += kFrameSizeSamples;
99 rtp_header_.sequenceNumber++;
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200100 ASSERT_EQ(0, receiver_.InsertPacket(rtp_header_,
101 rtc::ArrayView<const uint8_t>(
102 payload_, kFrameSizeSamples * 2)));
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000103 }
104
105 // Pull audio equivalent to the amount of audio in one RTP packet.
106 void Pull() {
107 AudioFrame frame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700108 bool muted;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000109 for (int k = 0; k < kNum10msPerFrame; ++k) { // Pull one frame.
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200110 ASSERT_EQ(0, receiver_.GetAudio(-1, &frame, &muted));
henrik.lundind4ccb002016-05-17 12:21:55 -0700111 ASSERT_FALSE(muted);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000112 // Had to use ASSERT_TRUE, ASSERT_EQ generated error.
113 ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_);
Peter Kasting69558702016-01-12 16:26:35 -0800114 ASSERT_EQ(1u, frame.num_channels_);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000115 ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_);
116 }
117 }
118
119 void Run(bool clean) {
120 for (int n = 0; n < 10; ++n) {
121 for (int m = 0; m < 5; ++m) {
122 Push();
123 Pull();
124 }
125
126 if (!clean) {
127 for (int m = 0; m < 10; ++m) { // Long enough to trigger delay change.
128 Push();
129 for (int n = 0; n < kInterarrivalJitterPacket; ++n)
130 Pull();
131 }
132 }
133 }
134 }
135
136 int SetMinimumDelay(int delay_ms) {
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200137 return receiver_.SetMinimumDelay(delay_ms);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000138 }
139
pwestin@webrtc.org401ef362013-08-06 21:01:36 +0000140 int SetMaximumDelay(int delay_ms) {
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200141 return receiver_.SetMaximumDelay(delay_ms);
pwestin@webrtc.org401ef362013-08-06 21:01:36 +0000142 }
143
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000144 int GetCurrentOptimalDelayMs() {
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000145 NetworkStatistics stats;
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200146 receiver_.GetNetworkStatistics(&stats);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000147 return stats.preferredBufferSize;
148 }
149
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200150 acm2::AcmReceiver receiver_;
Niels Möllerafb5dbb2019-02-15 15:21:47 +0100151 RTPHeader rtp_header_;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000152 uint8_t payload_[kPayloadLenBytes];
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000153};
154
kjellanderb7d24f62017-02-26 22:10:14 -0800155// Flaky on iOS: webrtc:7057.
156#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100157#define MAYBE_OutOfRangeInput DISABLED_OutOfRangeInput
158#else
159#define MAYBE_OutOfRangeInput OutOfRangeInput
160#endif
161TEST_F(TargetDelayTest, MAYBE_OutOfRangeInput) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000162 OutOfRangeInput();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000163}
164
kjellanderb7d24f62017-02-26 22:10:14 -0800165// Flaky on iOS: webrtc:7057.
166#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100167#define MAYBE_WithTargetDelayBufferNotChanging \
168 DISABLED_WithTargetDelayBufferNotChanging
169#else
170#define MAYBE_WithTargetDelayBufferNotChanging WithTargetDelayBufferNotChanging
171#endif
172TEST_F(TargetDelayTest, MAYBE_WithTargetDelayBufferNotChanging) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000173 WithTargetDelayBufferNotChanging();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000174}
175
kjellanderb7d24f62017-02-26 22:10:14 -0800176// Flaky on iOS: webrtc:7057.
177#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100178#define MAYBE_TargetDelayBufferMinMax DISABLED_TargetDelayBufferMinMax
179#else
180#define MAYBE_TargetDelayBufferMinMax TargetDelayBufferMinMax
181#endif
182TEST_F(TargetDelayTest, MAYBE_TargetDelayBufferMinMax) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000183 TargetDelayBufferMinMax();
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000184}
185
186} // namespace webrtc