blob: 071a6d898de6dc7611db355dd53c21e08b3d6f91 [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"
Fredrik Solenbergec0f45b2018-12-03 15:50:44 +000015#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"
Fredrik Solenbergec0f45b2018-12-03 15:50:44 +000018#include "modules/audio_coding/test/utility.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#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;
Fredrik Solenbergec0f45b2018-12-03 15:50:44 +000038 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;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000046 rtp_info_.frameType = kAudioFrameSpeech;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000047
48 int16_t audio[kFrameSizeSamples];
49 const int kRange = 0x7FF; // 2047, easy for masking.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000050 for (size_t n = 0; n < kFrameSizeSamples; ++n)
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000051 audio[n] = (rand() & kRange) - kRange / 2;
52 WebRtcPcm16b_Encode(audio, kFrameSizeSamples, payload_);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000053 }
54
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000055 void OutOfRangeInput() {
56 EXPECT_EQ(-1, SetMinimumDelay(-1));
57 EXPECT_EQ(-1, SetMinimumDelay(10001));
58 }
59
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000060 void WithTargetDelayBufferNotChanging() {
61 // A target delay that is one packet larger than jitter.
Yves Gerey665174f2018-06-19 15:03:05 +020062 const int kTargetDelayMs =
63 (kInterarrivalJitterPacket + 1) * kNum10msPerFrame * 10;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000064 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs));
65 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer.
66 Run(true);
67 int clean_optimal_delay = GetCurrentOptimalDelayMs();
68 EXPECT_EQ(kTargetDelayMs, clean_optimal_delay);
69 Run(false); // Run with jitter.
70 int jittery_optimal_delay = GetCurrentOptimalDelayMs();
71 EXPECT_EQ(jittery_optimal_delay, clean_optimal_delay);
72 }
73
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000074 void TargetDelayBufferMinMax() {
75 const int kTargetMinDelayMs = kNum10msPerFrame * 10;
76 ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs));
77 for (int m = 0; m < 30; ++m) // Run enough iterations to fill the buffer.
78 Run(true);
79 int clean_optimal_delay = GetCurrentOptimalDelayMs();
80 EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay);
81
82 const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10);
83 ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs));
84 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer.
85 Run(false);
86
87 int capped_optimal_delay = GetCurrentOptimalDelayMs();
88 EXPECT_EQ(kTargetMaxDelayMs, capped_optimal_delay);
89 }
90
91 private:
92 static const int kSampleRateHz = 16000;
93 static const int kNum10msPerFrame = 2;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000094 static const size_t kFrameSizeSamples = 320; // 20 ms @ 16 kHz.
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000095 // payload-len = frame-samples * 2 bytes/sample.
96 static const int kPayloadLenBytes = 320 * 2;
97 // Inter-arrival time in number of packets in a jittery channel. One is no
98 // jitter.
99 static const int kInterarrivalJitterPacket = 2;
100
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000101 void Push() {
102 rtp_info_.header.timestamp += kFrameSizeSamples;
103 rtp_info_.header.sequenceNumber++;
Yves Gerey665174f2018-06-19 15:03:05 +0200104 ASSERT_EQ(0,
105 acm_->IncomingPacket(payload_, kFrameSizeSamples * 2, rtp_info_));
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000106 }
107
108 // Pull audio equivalent to the amount of audio in one RTP packet.
109 void Pull() {
110 AudioFrame frame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700111 bool muted;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000112 for (int k = 0; k < kNum10msPerFrame; ++k) { // Pull one frame.
henrik.lundind4ccb002016-05-17 12:21:55 -0700113 ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &frame, &muted));
114 ASSERT_FALSE(muted);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000115 // Had to use ASSERT_TRUE, ASSERT_EQ generated error.
116 ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_);
Peter Kasting69558702016-01-12 16:26:35 -0800117 ASSERT_EQ(1u, frame.num_channels_);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000118 ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_);
119 }
120 }
121
122 void Run(bool clean) {
123 for (int n = 0; n < 10; ++n) {
124 for (int m = 0; m < 5; ++m) {
125 Push();
126 Pull();
127 }
128
129 if (!clean) {
130 for (int m = 0; m < 10; ++m) { // Long enough to trigger delay change.
131 Push();
132 for (int n = 0; n < kInterarrivalJitterPacket; ++n)
133 Pull();
134 }
135 }
136 }
137 }
138
139 int SetMinimumDelay(int delay_ms) {
140 return acm_->SetMinimumPlayoutDelay(delay_ms);
141 }
142
pwestin@webrtc.org401ef362013-08-06 21:01:36 +0000143 int SetMaximumDelay(int delay_ms) {
144 return acm_->SetMaximumPlayoutDelay(delay_ms);
145 }
146
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000147 int GetCurrentOptimalDelayMs() {
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000148 NetworkStatistics stats;
149 acm_->GetNetworkStatistics(&stats);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000150 return stats.preferredBufferSize;
151 }
152
kwiberg37478382016-02-14 20:40:57 -0800153 std::unique_ptr<AudioCodingModule> acm_;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000154 WebRtcRTPHeader rtp_info_;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000155 uint8_t payload_[kPayloadLenBytes];
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000156};
157
kjellanderb7d24f62017-02-26 22:10:14 -0800158// Flaky on iOS: webrtc:7057.
159#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100160#define MAYBE_OutOfRangeInput DISABLED_OutOfRangeInput
161#else
162#define MAYBE_OutOfRangeInput OutOfRangeInput
163#endif
164TEST_F(TargetDelayTest, MAYBE_OutOfRangeInput) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000165 OutOfRangeInput();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000166}
167
kjellanderb7d24f62017-02-26 22:10:14 -0800168// Flaky on iOS: webrtc:7057.
169#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100170#define MAYBE_WithTargetDelayBufferNotChanging \
171 DISABLED_WithTargetDelayBufferNotChanging
172#else
173#define MAYBE_WithTargetDelayBufferNotChanging WithTargetDelayBufferNotChanging
174#endif
175TEST_F(TargetDelayTest, MAYBE_WithTargetDelayBufferNotChanging) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000176 WithTargetDelayBufferNotChanging();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000177}
178
kjellanderb7d24f62017-02-26 22:10:14 -0800179// Flaky on iOS: webrtc:7057.
180#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100181#define MAYBE_TargetDelayBufferMinMax DISABLED_TargetDelayBufferMinMax
182#else
183#define MAYBE_TargetDelayBufferMinMax TargetDelayBufferMinMax
184#endif
185TEST_F(TargetDelayTest, MAYBE_TargetDelayBufferMinMax) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000186 TargetDelayBufferMinMax();
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000187}
188
189} // namespace webrtc