Chromium Code Reviews| 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 |