OLD | NEW |
| (Empty) |
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 "testing/gtest/include/gtest/gtest.h" | |
12 #include "webrtc/base/scoped_ptr.h" | |
13 #include "webrtc/common_types.h" | |
14 #include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" | |
15 #include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" | |
16 #include "webrtc/modules/audio_coding/main/test/utility.h" | |
17 #include "webrtc/modules/include/module_common_types.h" | |
18 #include "webrtc/system_wrappers/include/sleep.h" | |
19 #include "webrtc/test/testsupport/fileutils.h" | |
20 #include "webrtc/test/testsupport/gtest_disable.h" | |
21 | |
22 namespace webrtc { | |
23 | |
24 class TargetDelayTest : public ::testing::Test { | |
25 protected: | |
26 TargetDelayTest() : acm_(AudioCodingModule::Create(0)) {} | |
27 | |
28 ~TargetDelayTest() {} | |
29 | |
30 void SetUp() { | |
31 EXPECT_TRUE(acm_.get() != NULL); | |
32 | |
33 CodecInst codec; | |
34 ASSERT_EQ(0, AudioCodingModule::Codec("L16", &codec, kSampleRateHz, 1)); | |
35 ASSERT_EQ(0, acm_->InitializeReceiver()); | |
36 ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec)); | |
37 | |
38 rtp_info_.header.payloadType = codec.pltype; | |
39 rtp_info_.header.timestamp = 0; | |
40 rtp_info_.header.ssrc = 0x12345678; | |
41 rtp_info_.header.markerBit = false; | |
42 rtp_info_.header.sequenceNumber = 0; | |
43 rtp_info_.type.Audio.channel = 1; | |
44 rtp_info_.type.Audio.isCNG = false; | |
45 rtp_info_.frameType = kAudioFrameSpeech; | |
46 | |
47 int16_t audio[kFrameSizeSamples]; | |
48 const int kRange = 0x7FF; // 2047, easy for masking. | |
49 for (size_t n = 0; n < kFrameSizeSamples; ++n) | |
50 audio[n] = (rand() & kRange) - kRange / 2; | |
51 WebRtcPcm16b_Encode(audio, kFrameSizeSamples, payload_); | |
52 } | |
53 | |
54 void OutOfRangeInput() { | |
55 EXPECT_EQ(-1, SetMinimumDelay(-1)); | |
56 EXPECT_EQ(-1, SetMinimumDelay(10001)); | |
57 } | |
58 | |
59 void NoTargetDelayBufferSizeChanges() { | |
60 for (int n = 0; n < 30; ++n) // Run enough iterations. | |
61 Run(true); | |
62 int clean_optimal_delay = GetCurrentOptimalDelayMs(); | |
63 Run(false); // Run with jitter. | |
64 int jittery_optimal_delay = GetCurrentOptimalDelayMs(); | |
65 EXPECT_GT(jittery_optimal_delay, clean_optimal_delay); | |
66 int required_delay = RequiredDelay(); | |
67 EXPECT_GT(required_delay, 0); | |
68 EXPECT_NEAR(required_delay, jittery_optimal_delay, 1); | |
69 } | |
70 | |
71 void WithTargetDelayBufferNotChanging() { | |
72 // A target delay that is one packet larger than jitter. | |
73 const int kTargetDelayMs = (kInterarrivalJitterPacket + 1) * | |
74 kNum10msPerFrame * 10; | |
75 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs)); | |
76 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer. | |
77 Run(true); | |
78 int clean_optimal_delay = GetCurrentOptimalDelayMs(); | |
79 EXPECT_EQ(kTargetDelayMs, clean_optimal_delay); | |
80 Run(false); // Run with jitter. | |
81 int jittery_optimal_delay = GetCurrentOptimalDelayMs(); | |
82 EXPECT_EQ(jittery_optimal_delay, clean_optimal_delay); | |
83 } | |
84 | |
85 void RequiredDelayAtCorrectRange() { | |
86 for (int n = 0; n < 30; ++n) // Run clean and store delay. | |
87 Run(true); | |
88 int clean_optimal_delay = GetCurrentOptimalDelayMs(); | |
89 | |
90 // A relatively large delay. | |
91 const int kTargetDelayMs = (kInterarrivalJitterPacket + 10) * | |
92 kNum10msPerFrame * 10; | |
93 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs)); | |
94 for (int n = 0; n < 300; ++n) // Run enough iterations to fill the buffer. | |
95 Run(true); | |
96 Run(false); // Run with jitter. | |
97 | |
98 int jittery_optimal_delay = GetCurrentOptimalDelayMs(); | |
99 EXPECT_EQ(kTargetDelayMs, jittery_optimal_delay); | |
100 | |
101 int required_delay = RequiredDelay(); | |
102 | |
103 // Checking |required_delay| is in correct range. | |
104 EXPECT_GT(required_delay, 0); | |
105 EXPECT_GT(jittery_optimal_delay, required_delay); | |
106 EXPECT_GT(required_delay, clean_optimal_delay); | |
107 | |
108 // A tighter check for the value of |required_delay|. | |
109 // The jitter forces a delay of | |
110 // |kInterarrivalJitterPacket * kNum10msPerFrame * 10| milliseconds. So we | |
111 // expect |required_delay| be close to that. | |
112 EXPECT_NEAR(kInterarrivalJitterPacket * kNum10msPerFrame * 10, | |
113 required_delay, 1); | |
114 } | |
115 | |
116 void TargetDelayBufferMinMax() { | |
117 const int kTargetMinDelayMs = kNum10msPerFrame * 10; | |
118 ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs)); | |
119 for (int m = 0; m < 30; ++m) // Run enough iterations to fill the buffer. | |
120 Run(true); | |
121 int clean_optimal_delay = GetCurrentOptimalDelayMs(); | |
122 EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay); | |
123 | |
124 const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10); | |
125 ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs)); | |
126 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer. | |
127 Run(false); | |
128 | |
129 int capped_optimal_delay = GetCurrentOptimalDelayMs(); | |
130 EXPECT_EQ(kTargetMaxDelayMs, capped_optimal_delay); | |
131 } | |
132 | |
133 private: | |
134 static const int kSampleRateHz = 16000; | |
135 static const int kNum10msPerFrame = 2; | |
136 static const size_t kFrameSizeSamples = 320; // 20 ms @ 16 kHz. | |
137 // payload-len = frame-samples * 2 bytes/sample. | |
138 static const int kPayloadLenBytes = 320 * 2; | |
139 // Inter-arrival time in number of packets in a jittery channel. One is no | |
140 // jitter. | |
141 static const int kInterarrivalJitterPacket = 2; | |
142 | |
143 void Push() { | |
144 rtp_info_.header.timestamp += kFrameSizeSamples; | |
145 rtp_info_.header.sequenceNumber++; | |
146 ASSERT_EQ(0, acm_->IncomingPacket(payload_, kFrameSizeSamples * 2, | |
147 rtp_info_)); | |
148 } | |
149 | |
150 // Pull audio equivalent to the amount of audio in one RTP packet. | |
151 void Pull() { | |
152 AudioFrame frame; | |
153 for (int k = 0; k < kNum10msPerFrame; ++k) { // Pull one frame. | |
154 ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &frame)); | |
155 // Had to use ASSERT_TRUE, ASSERT_EQ generated error. | |
156 ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_); | |
157 ASSERT_EQ(1, frame.num_channels_); | |
158 ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_); | |
159 } | |
160 } | |
161 | |
162 void Run(bool clean) { | |
163 for (int n = 0; n < 10; ++n) { | |
164 for (int m = 0; m < 5; ++m) { | |
165 Push(); | |
166 Pull(); | |
167 } | |
168 | |
169 if (!clean) { | |
170 for (int m = 0; m < 10; ++m) { // Long enough to trigger delay change. | |
171 Push(); | |
172 for (int n = 0; n < kInterarrivalJitterPacket; ++n) | |
173 Pull(); | |
174 } | |
175 } | |
176 } | |
177 } | |
178 | |
179 int SetMinimumDelay(int delay_ms) { | |
180 return acm_->SetMinimumPlayoutDelay(delay_ms); | |
181 } | |
182 | |
183 int SetMaximumDelay(int delay_ms) { | |
184 return acm_->SetMaximumPlayoutDelay(delay_ms); | |
185 } | |
186 | |
187 int GetCurrentOptimalDelayMs() { | |
188 NetworkStatistics stats; | |
189 acm_->GetNetworkStatistics(&stats); | |
190 return stats.preferredBufferSize; | |
191 } | |
192 | |
193 int RequiredDelay() { | |
194 return acm_->LeastRequiredDelayMs(); | |
195 } | |
196 | |
197 rtc::scoped_ptr<AudioCodingModule> acm_; | |
198 WebRtcRTPHeader rtp_info_; | |
199 uint8_t payload_[kPayloadLenBytes]; | |
200 }; | |
201 | |
202 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(OutOfRangeInput)) { | |
203 OutOfRangeInput(); | |
204 } | |
205 | |
206 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(NoTargetDelayBufferSizeChanges)) { | |
207 NoTargetDelayBufferSizeChanges(); | |
208 } | |
209 | |
210 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(WithTargetDelayBufferNotChanging)) { | |
211 WithTargetDelayBufferNotChanging(); | |
212 } | |
213 | |
214 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(RequiredDelayAtCorrectRange)) { | |
215 RequiredDelayAtCorrectRange(); | |
216 } | |
217 | |
218 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(TargetDelayBufferMinMax)) { | |
219 TargetDelayBufferMinMax(); | |
220 } | |
221 | |
222 } // namespace webrtc | |
223 | |
OLD | NEW |