1 /*
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
11 #include <memory>
12
13 #include "api/audio/audio_frame.h"
14 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
15 #include "api/rtp_headers.h"
16 #include "modules/audio_coding/acm2/acm_receiver.h"
17 #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
18 #include "modules/audio_coding/include/audio_coding_module.h"
19 #include "test/gtest.h"
20 #include "test/testsupport/file_utils.h"
21
22 namespace webrtc {
23
24 class TargetDelayTest : public ::testing::Test {
25 protected:
TargetDelayTest()26 TargetDelayTest()
27 : receiver_(
28 AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())) {}
29
~TargetDelayTest()30 ~TargetDelayTest() {}
31
SetUp()32 void SetUp() {
33 constexpr int pltype = 108;
34 std::map<int, SdpAudioFormat> receive_codecs = {
35 {pltype, {"L16", kSampleRateHz, 1}}};
36 receiver_.SetCodecs(receive_codecs);
37
38 rtp_header_.payloadType = pltype;
39 rtp_header_.timestamp = 0;
40 rtp_header_.ssrc = 0x12345678;
41 rtp_header_.markerBit = false;
42 rtp_header_.sequenceNumber = 0;
43
44 int16_t audio[kFrameSizeSamples];
45 const int kRange = 0x7FF; // 2047, easy for masking.
46 for (size_t n = 0; n < kFrameSizeSamples; ++n)
47 audio[n] = (rand() & kRange) - kRange / 2;
48 WebRtcPcm16b_Encode(audio, kFrameSizeSamples, payload_);
49 }
50
OutOfRangeInput()51 void OutOfRangeInput() {
52 EXPECT_EQ(-1, SetMinimumDelay(-1));
53 EXPECT_EQ(-1, SetMinimumDelay(10001));
54 }
55
TargetDelayBufferMinMax()56 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;
76 static const size_t kFrameSizeSamples = 320; // 20 ms @ 16 kHz.
77 // 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
Push()83 void Push() {
84 rtp_header_.timestamp += kFrameSizeSamples;
85 rtp_header_.sequenceNumber++;
86 ASSERT_EQ(0, receiver_.InsertPacket(rtp_header_,
87 rtc::ArrayView<const uint8_t>(
88 payload_, kFrameSizeSamples * 2)));
89 }
90
91 // Pull audio equivalent to the amount of audio in one RTP packet.
Pull()92 void Pull() {
93 AudioFrame frame;
94 bool muted;
95 for (int k = 0; k < kNum10msPerFrame; ++k) { // Pull one frame.
96 ASSERT_EQ(0, receiver_.GetAudio(-1, &frame, &muted));
97 ASSERT_FALSE(muted);
98 // Had to use ASSERT_TRUE, ASSERT_EQ generated error.
99 ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_);
100 ASSERT_EQ(1u, frame.num_channels_);
101 ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_);
102 }
103 }
104
Run(bool clean)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
SetMinimumDelay(int delay_ms)122 int SetMinimumDelay(int delay_ms) {
123 return receiver_.SetMinimumDelay(delay_ms);
124 }
125
SetMaximumDelay(int delay_ms)126 int SetMaximumDelay(int delay_ms) {
127 return receiver_.SetMaximumDelay(delay_ms);
128 }
129
GetCurrentOptimalDelayMs()130 int GetCurrentOptimalDelayMs() {
131 NetworkStatistics stats;
132 receiver_.GetNetworkStatistics(&stats);
133 return stats.preferredBufferSize;
134 }
135
136 acm2::AcmReceiver receiver_;
137 RTPHeader rtp_header_;
138 uint8_t payload_[kPayloadLenBytes];
139 };
140
141 // Flaky on iOS: webrtc:7057.
142 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
143 #define MAYBE_OutOfRangeInput DISABLED_OutOfRangeInput
144 #else
145 #define MAYBE_OutOfRangeInput OutOfRangeInput
146 #endif
TEST_F(TargetDelayTest,MAYBE_OutOfRangeInput)147 TEST_F(TargetDelayTest, MAYBE_OutOfRangeInput) {
148 OutOfRangeInput();
149 }
150
151 // Flaky on iOS: webrtc:7057.
152 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
153 #define MAYBE_TargetDelayBufferMinMax DISABLED_TargetDelayBufferMinMax
154 #else
155 #define MAYBE_TargetDelayBufferMinMax TargetDelayBufferMinMax
156 #endif
TEST_F(TargetDelayTest,MAYBE_TargetDelayBufferMinMax)157 TEST_F(TargetDelayTest, MAYBE_TargetDelayBufferMinMax) {
158 TargetDelayBufferMinMax();
159 }
160
161 } // namespace webrtc
162