blob: 5eccdcf8eb86cf80d5c20e69bf2caee8a0efdbe1 [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öller834a5542019-09-23 10:31:16 +020015#include "api/rtp_headers.h"
Niels Möller5ceb4ac2019-08-13 15:54:15 +020016#include "modules/audio_coding/acm2/acm_receiver.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
18#include "modules/audio_coding/include/audio_coding_module.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#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 TargetDelayBufferMinMax() {
57 const int kTargetMinDelayMs = kNum10msPerFrame * 10;
58 ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs));
59 for (int m = 0; m < 30; ++m) // Run enough iterations to fill the buffer.
60 Run(true);
61 int clean_optimal_delay = GetCurrentOptimalDelayMs();
62 EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay);
63
64 const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10);
65 ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs));
66 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer.
67 Run(false);
68
69 int capped_optimal_delay = GetCurrentOptimalDelayMs();
70 EXPECT_EQ(kTargetMaxDelayMs, capped_optimal_delay);
71 }
72
73 private:
74 static const int kSampleRateHz = 16000;
75 static const int kNum10msPerFrame = 2;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000076 static const size_t kFrameSizeSamples = 320; // 20 ms @ 16 kHz.
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000077 // payload-len = frame-samples * 2 bytes/sample.
78 static const int kPayloadLenBytes = 320 * 2;
79 // Inter-arrival time in number of packets in a jittery channel. One is no
80 // jitter.
81 static const int kInterarrivalJitterPacket = 2;
82
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000083 void Push() {
Niels Möllerafb5dbb2019-02-15 15:21:47 +010084 rtp_header_.timestamp += kFrameSizeSamples;
85 rtp_header_.sequenceNumber++;
Niels Möller5ceb4ac2019-08-13 15:54:15 +020086 ASSERT_EQ(0, receiver_.InsertPacket(rtp_header_,
87 rtc::ArrayView<const uint8_t>(
88 payload_, kFrameSizeSamples * 2)));
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000089 }
90
91 // Pull audio equivalent to the amount of audio in one RTP packet.
92 void Pull() {
93 AudioFrame frame;
henrik.lundind4ccb002016-05-17 12:21:55 -070094 bool muted;
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000095 for (int k = 0; k < kNum10msPerFrame; ++k) { // Pull one frame.
Niels Möller5ceb4ac2019-08-13 15:54:15 +020096 ASSERT_EQ(0, receiver_.GetAudio(-1, &frame, &muted));
henrik.lundind4ccb002016-05-17 12:21:55 -070097 ASSERT_FALSE(muted);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +000098 // Had to use ASSERT_TRUE, ASSERT_EQ generated error.
99 ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_);
Peter Kasting69558702016-01-12 16:26:35 -0800100 ASSERT_EQ(1u, frame.num_channels_);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000101 ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_);
102 }
103 }
104
105 void Run(bool clean) {
106 for (int n = 0; n < 10; ++n) {
107 for (int m = 0; m < 5; ++m) {
108 Push();
109 Pull();
110 }
111
112 if (!clean) {
113 for (int m = 0; m < 10; ++m) { // Long enough to trigger delay change.
114 Push();
115 for (int n = 0; n < kInterarrivalJitterPacket; ++n)
116 Pull();
117 }
118 }
119 }
120 }
121
122 int SetMinimumDelay(int delay_ms) {
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200123 return receiver_.SetMinimumDelay(delay_ms);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000124 }
125
pwestin@webrtc.org401ef362013-08-06 21:01:36 +0000126 int SetMaximumDelay(int delay_ms) {
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200127 return receiver_.SetMaximumDelay(delay_ms);
pwestin@webrtc.org401ef362013-08-06 21:01:36 +0000128 }
129
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000130 int GetCurrentOptimalDelayMs() {
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000131 NetworkStatistics stats;
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200132 receiver_.GetNetworkStatistics(&stats);
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000133 return stats.preferredBufferSize;
134 }
135
Niels Möller5ceb4ac2019-08-13 15:54:15 +0200136 acm2::AcmReceiver receiver_;
Niels Möllerafb5dbb2019-02-15 15:21:47 +0100137 RTPHeader rtp_header_;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000138 uint8_t payload_[kPayloadLenBytes];
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000139};
140
kjellanderb7d24f62017-02-26 22:10:14 -0800141// Flaky on iOS: webrtc:7057.
142#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100143#define MAYBE_OutOfRangeInput DISABLED_OutOfRangeInput
144#else
145#define MAYBE_OutOfRangeInput OutOfRangeInput
146#endif
147TEST_F(TargetDelayTest, MAYBE_OutOfRangeInput) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000148 OutOfRangeInput();
turaj@webrtc.orge46c8d32013-05-22 20:39:43 +0000149}
150
kjellanderb7d24f62017-02-26 22:10:14 -0800151// Flaky on iOS: webrtc:7057.
152#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
Peter Boströme2976c82016-01-04 22:44:05 +0100153#define MAYBE_TargetDelayBufferMinMax DISABLED_TargetDelayBufferMinMax
154#else
155#define MAYBE_TargetDelayBufferMinMax TargetDelayBufferMinMax
156#endif
157TEST_F(TargetDelayTest, MAYBE_TargetDelayBufferMinMax) {
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +0000158 TargetDelayBufferMinMax();
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000159}
160
161} // namespace webrtc