OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // Tests PPB_MediaStreamAudioTrack interface. | 5 // Tests PPB_MediaStreamAudioTrack interface. |
6 | 6 |
7 #include "ppapi/tests/test_media_stream_audio_track.h" | 7 #include "ppapi/tests/test_media_stream_audio_track.h" |
8 | 8 |
9 #include "ppapi/c/private/ppb_testing_private.h" | 9 #include "ppapi/c/private/ppb_testing_private.h" |
10 #include "ppapi/cpp/audio_buffer.h" | 10 #include "ppapi/cpp/audio_buffer.h" |
11 #include "ppapi/cpp/completion_callback.h" | 11 #include "ppapi/cpp/completion_callback.h" |
12 #include "ppapi/cpp/instance.h" | 12 #include "ppapi/cpp/instance.h" |
13 #include "ppapi/cpp/var.h" | 13 #include "ppapi/cpp/var.h" |
14 #include "ppapi/tests/test_utils.h" | 14 #include "ppapi/tests/test_utils.h" |
15 #include "ppapi/tests/testing_instance.h" | 15 #include "ppapi/tests/testing_instance.h" |
16 | 16 |
17 REGISTER_TEST_CASE(MediaStreamAudioTrack); | 17 REGISTER_TEST_CASE(MediaStreamAudioTrack); |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 // Real max defined in | 21 // Real constants defined in |
22 // content/renderer/pepper/pepper_media_stream_audio_track_host.cc. | 22 // content/renderer/pepper/pepper_media_stream_audio_track_host.cc. |
23 const int32_t kMaxNumberOfBuffers = 1000; | 23 const int32_t kMaxNumberOfBuffers = 1000; |
24 const int32_t kMinDuration = 10; | |
25 const int32_t kMaxDuration = 10000; | |
24 const int32_t kTimes = 3; | 26 const int32_t kTimes = 3; |
25 const char kJSCode[] = | 27 const char kJSCode[] = |
26 "function gotStream(stream) {" | 28 "function gotStream(stream) {" |
27 " test_stream = stream;" | 29 " test_stream = stream;" |
28 " var track = stream.getAudioTracks()[0];" | 30 " var track = stream.getAudioTracks()[0];" |
29 " var plugin = document.getElementById('plugin');" | 31 " var plugin = document.getElementById('plugin');" |
30 " plugin.postMessage(track);" | 32 " plugin.postMessage(track);" |
31 "}" | 33 "}" |
32 "var constraints = {" | 34 "var constraints = {" |
33 " audio: true," | 35 " audio: true," |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 ASSERT_TRUE(buffer.GetDataBuffer() == NULL); | 140 ASSERT_TRUE(buffer.GetDataBuffer() == NULL); |
139 } | 141 } |
140 | 142 |
141 // Close the track. | 143 // Close the track. |
142 audio_track_.Close(); | 144 audio_track_.Close(); |
143 ASSERT_TRUE(audio_track_.HasEnded()); | 145 ASSERT_TRUE(audio_track_.HasEnded()); |
144 audio_track_ = pp::MediaStreamAudioTrack(); | 146 audio_track_ = pp::MediaStreamAudioTrack(); |
145 PASS(); | 147 PASS(); |
146 } | 148 } |
147 | 149 |
150 std::string TestMediaStreamAudioTrack::CheckConfigure( | |
151 int32_t attrib_list[], int32_t expected_result) { | |
152 TestCompletionCallback cc_configure(instance_->pp_instance(), false); | |
153 cc_configure.WaitForResult( | |
154 audio_track_.Configure(attrib_list, cc_configure.GetCallback())); | |
155 ASSERT_EQ(expected_result, cc_configure.result()); | |
156 PASS(); | |
157 } | |
158 | |
159 std::string TestMediaStreamAudioTrack::CheckGetBuffer( | |
160 int times, int expected_duration) { | |
161 PP_TimeDelta timestamp = 0.0; | |
162 for (int j = 0; j < times; ++j) { | |
163 TestCompletionCallbackWithOutput<pp::AudioBuffer> cc_get_buffer( | |
164 instance_->pp_instance(), false); | |
165 cc_get_buffer.WaitForResult( | |
166 audio_track_.GetBuffer(cc_get_buffer.GetCallback())); | |
167 ASSERT_EQ(PP_OK, cc_get_buffer.result()); | |
168 pp::AudioBuffer buffer = cc_get_buffer.output(); | |
169 ASSERT_FALSE(buffer.is_null()); | |
170 ASSERT_TRUE(IsSampleRateValid(buffer.GetSampleRate())); | |
171 ASSERT_EQ(buffer.GetSampleSize(), PP_AUDIOBUFFER_SAMPLESIZE_16_BITS); | |
172 | |
173 ASSERT_GE(buffer.GetTimestamp(), timestamp); | |
174 timestamp = buffer.GetTimestamp(); | |
175 | |
176 // TODO(amistry): Figure out how to inject a predictable audio pattern, such | |
177 // as a sawtooth, and check the buffer data to make sure it's correct. | |
178 ASSERT_TRUE(buffer.GetDataBuffer() != NULL); | |
179 if (expected_duration > 0) { | |
180 uint32_t buffer_size = buffer.GetDataBufferSize(); | |
181 uint32_t channels = buffer.GetNumberOfChannels(); | |
182 uint32_t sample_rate = buffer.GetSampleRate(); | |
183 uint32_t bytes_per_frame = channels * 2; | |
184 int32_t duration = expected_duration; | |
185 ASSERT_EQ(buffer_size % bytes_per_frame, 0U); | |
186 ASSERT_EQ(buffer_size, | |
187 (duration * sample_rate * bytes_per_frame) / 1000); | |
188 } else { | |
189 ASSERT_GT(buffer.GetDataBufferSize(), 0U); | |
190 } | |
191 | |
192 audio_track_.RecycleBuffer(buffer); | |
193 } | |
194 PASS(); | |
195 } | |
196 | |
148 std::string TestMediaStreamAudioTrack::TestConfigure() { | 197 std::string TestMediaStreamAudioTrack::TestConfigure() { |
Peng
2014/07/24 15:38:37
The test is disabled in https://codereview.chromiu
Anand Mistry (off Chromium)
2014/07/25 03:38:15
Done.
| |
149 // Create a track. | 198 // Create a track. |
150 instance_->EvalScript(kJSCode); | 199 instance_->EvalScript(kJSCode); |
151 event_.Wait(); | 200 event_.Wait(); |
152 event_.Reset(); | 201 event_.Reset(); |
153 | 202 |
154 ASSERT_FALSE(audio_track_.is_null()); | 203 ASSERT_FALSE(audio_track_.is_null()); |
155 ASSERT_FALSE(audio_track_.HasEnded()); | 204 ASSERT_FALSE(audio_track_.HasEnded()); |
156 ASSERT_FALSE(audio_track_.GetId().empty()); | 205 ASSERT_FALSE(audio_track_.GetId().empty()); |
157 | 206 |
158 PP_TimeDelta timestamp = 0.0; | |
159 | |
160 // Configure number of buffers. | 207 // Configure number of buffers. |
161 struct { | 208 struct { |
162 int32_t buffers; | 209 int32_t buffers; |
163 int32_t expect_result; | 210 int32_t expect_result; |
164 } buffers[] = { | 211 } buffers[] = { |
165 { 8, PP_OK }, | 212 { 8, PP_OK }, |
166 { 100, PP_OK }, | 213 { 100, PP_OK }, |
167 { kMaxNumberOfBuffers, PP_OK }, | 214 { kMaxNumberOfBuffers, PP_OK }, |
168 { -1, PP_ERROR_BADARGUMENT }, | 215 { -1, PP_ERROR_BADARGUMENT }, |
169 { kMaxNumberOfBuffers + 1, PP_OK }, // Clipped to max value. | 216 { kMaxNumberOfBuffers + 1, PP_OK }, // Clipped to max value. |
170 { 0, PP_OK }, // Use default. | 217 { 0, PP_OK }, // Use default. |
171 }; | 218 }; |
172 for (size_t i = 0; i < sizeof(buffers) / sizeof(buffers[0]); ++i) { | 219 for (size_t i = 0; i < sizeof(buffers) / sizeof(buffers[0]); ++i) { |
173 TestCompletionCallback cc_configure(instance_->pp_instance(), false); | |
174 int32_t attrib_list[] = { | 220 int32_t attrib_list[] = { |
175 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, buffers[i].buffers, | 221 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, buffers[i].buffers, |
176 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE, | 222 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE, |
177 }; | 223 }; |
178 cc_configure.WaitForResult( | 224 ASSERT_SUBTEST_SUCCESS(CheckConfigure(attrib_list, |
179 audio_track_.Configure(attrib_list, cc_configure.GetCallback())); | 225 buffers[i].expect_result)); |
180 ASSERT_EQ(buffers[i].expect_result, cc_configure.result()); | 226 // Get some buffers. This should also succeed when configure fails. |
227 ASSERT_SUBTEST_SUCCESS(CheckGetBuffer(kTimes, -1)); | |
228 } | |
181 | 229 |
182 // Get some buffers. This should also succeed when configure fails. | 230 // Configure buffer duration. |
183 for (int j = 0; j < kTimes; ++j) { | 231 struct { |
184 TestCompletionCallbackWithOutput<pp::AudioBuffer> cc_get_buffer( | 232 int32_t duration; |
185 instance_->pp_instance(), false); | 233 int32_t expect_result; |
186 cc_get_buffer.WaitForResult( | 234 } durations[] = { |
187 audio_track_.GetBuffer(cc_get_buffer.GetCallback())); | 235 { kMinDuration, PP_OK }, |
188 ASSERT_EQ(PP_OK, cc_get_buffer.result()); | 236 { 123, PP_OK }, |
189 pp::AudioBuffer buffer = cc_get_buffer.output(); | 237 { kMinDuration - 1, PP_ERROR_BADARGUMENT }, |
190 ASSERT_FALSE(buffer.is_null()); | 238 { kMaxDuration + 1, PP_ERROR_BADARGUMENT }, |
191 ASSERT_TRUE(IsSampleRateValid(buffer.GetSampleRate())); | 239 }; |
192 ASSERT_EQ(buffer.GetSampleSize(), PP_AUDIOBUFFER_SAMPLESIZE_16_BITS); | 240 for (size_t i = 0; i < sizeof(durations) / sizeof(durations[0]); ++i) { |
241 int32_t attrib_list[] = { | |
242 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_DURATION, durations[i].duration, | |
243 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE, | |
244 }; | |
245 ASSERT_SUBTEST_SUCCESS(CheckConfigure(attrib_list, | |
246 durations[i].expect_result)); | |
193 | 247 |
194 ASSERT_GE(buffer.GetTimestamp(), timestamp); | 248 // Get some buffers. This always works, but the buffer size will vary. |
195 timestamp = buffer.GetTimestamp(); | 249 int duration = |
250 durations[i].expect_result == PP_OK ? durations[i].duration : -1; | |
251 ASSERT_SUBTEST_SUCCESS(CheckGetBuffer(kTimes, duration)); | |
252 } | |
253 // Test kMaxDuration separately since each GetBuffer will take 10 seconds. | |
254 int32_t attrib_list[] = { | |
255 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_DURATION, kMaxDuration, | |
256 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE, | |
257 }; | |
258 ASSERT_SUBTEST_SUCCESS(CheckConfigure(attrib_list, PP_OK)); | |
196 | 259 |
197 ASSERT_GT(buffer.GetDataBufferSize(), 0U); | |
198 ASSERT_TRUE(buffer.GetDataBuffer() != NULL); | |
199 | |
200 audio_track_.RecycleBuffer(buffer); | |
201 } | |
202 } | |
203 | 260 |
204 // Configure should fail while plugin holds buffers. | 261 // Configure should fail while plugin holds buffers. |
205 { | 262 { |
206 TestCompletionCallbackWithOutput<pp::AudioBuffer> cc_get_buffer( | 263 TestCompletionCallbackWithOutput<pp::AudioBuffer> cc_get_buffer( |
207 instance_->pp_instance(), false); | 264 instance_->pp_instance(), false); |
208 cc_get_buffer.WaitForResult( | 265 cc_get_buffer.WaitForResult( |
209 audio_track_.GetBuffer(cc_get_buffer.GetCallback())); | 266 audio_track_.GetBuffer(cc_get_buffer.GetCallback())); |
210 ASSERT_EQ(PP_OK, cc_get_buffer.result()); | 267 ASSERT_EQ(PP_OK, cc_get_buffer.result()); |
211 pp::AudioBuffer buffer = cc_get_buffer.output(); | 268 pp::AudioBuffer buffer = cc_get_buffer.output(); |
212 int32_t attrib_list[] = { | 269 int32_t attrib_list[] = { |
213 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, 0, | 270 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, 0, |
Peng
2014/07/24 15:38:37
Reset the duration to a small number, otherwise th
Anand Mistry (off Chromium)
2014/07/25 03:38:15
Done.
| |
214 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE, | 271 PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE, |
215 }; | 272 }; |
216 TestCompletionCallback cc_configure(instance_->pp_instance(), false); | 273 TestCompletionCallback cc_configure(instance_->pp_instance(), false); |
217 cc_configure.WaitForResult( | 274 cc_configure.WaitForResult( |
218 audio_track_.Configure(attrib_list, cc_configure.GetCallback())); | 275 audio_track_.Configure(attrib_list, cc_configure.GetCallback())); |
219 ASSERT_EQ(PP_ERROR_INPROGRESS, cc_configure.result()); | 276 ASSERT_EQ(PP_ERROR_INPROGRESS, cc_configure.result()); |
220 audio_track_.RecycleBuffer(buffer); | 277 audio_track_.RecycleBuffer(buffer); |
221 } | 278 } |
222 | 279 |
223 // Close the track. | 280 // Close the track. |
224 audio_track_.Close(); | 281 audio_track_.Close(); |
225 ASSERT_TRUE(audio_track_.HasEnded()); | 282 ASSERT_TRUE(audio_track_.HasEnded()); |
226 audio_track_ = pp::MediaStreamAudioTrack(); | 283 audio_track_ = pp::MediaStreamAudioTrack(); |
227 PASS(); | 284 PASS(); |
228 } | 285 } |
OLD | NEW |