BufferQueue_test.cpp revision d48ff338b8338c1e3e54e0f9dcd03567a0aa9de4
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/** \file BufferQueue_test.cpp */ 18 19#define LOG_NDEBUG 0 20#define LOG_TAG "BufferQueue_test" 21 22#ifdef ANDROID 23#include <utils/Log.h> 24#else 25#define LOGV printf 26#endif 27 28#include <assert.h> 29#include <math.h> 30#include <stdio.h> 31#include <stdlib.h> 32#include <unistd.h> 33#include "SLES/OpenSLES.h" 34#include "SLES/OpenSLESUT.h" 35#include <gtest/gtest.h> 36 37typedef struct { 38 short left; 39 short right; 40} stereo; 41 42// 1 second of stereo audio at 44.1 kHz 43static stereo stereoBuffer1[44100 * 1]; 44static const SLuint32 invalidNumBuffers[] = { 0, 0xFFFFFFFF, 0x80000000, 0x10002, 0x102, 45 0x101, 0x100 }; 46static const SLuint32 validNumBuffers[] = { 1, 2, 3, 4, 5, 6, 7, 8, 255 }; 47 48//----------------------------------------------------------------- 49/* Checks for error. If any errors exit the application! */ 50void CheckErr(SLresult res) { 51 if (SL_RESULT_SUCCESS != res) { 52 fprintf(stderr, "CheckErr failure: %s (0x%x), exiting\n", slesutResultToString(res), 53 (unsigned) res); 54 //Fail the test case 55 FAIL(); 56 } 57} 58 59static const SLInterfaceID ids[1] = { SL_IID_BUFFERQUEUE }; 60static const SLboolean flags[1] = { SL_BOOLEAN_TRUE }; 61 62// The fixture for testing class BufferQueue 63class TestBufferQueue: public ::testing::Test { 64public: 65 SLresult res; 66 SLObjectItf outputmixObject; 67 SLObjectItf engineObject; 68 69 SLDataSource audiosrc; 70 SLDataSink audiosnk; 71 SLDataFormat_PCM pcm; 72 SLDataLocator_OutputMix locator_outputmix; 73 SLDataLocator_BufferQueue locator_bufferqueue; 74 SLBufferQueueItf playerBufferQueue; 75 SLBufferQueueState bufferqueueState; 76 SLPlayItf playerPlay; 77 SLObjectItf playerObject; 78 SLEngineItf engineEngine; 79 SLuint32 playerState; 80 81protected: 82 TestBufferQueue() { 83 } 84 85 virtual ~TestBufferQueue() { 86 87 } 88 89 /*Test setup*/ 90 virtual void SetUp() { 91 92 // create engine 93 res = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 94 CheckErr(res); 95 res = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 96 CheckErr(res); 97 res = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 98 CheckErr(res); 99 100 // create output mix 101 res = (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL); 102 CheckErr(res); 103 res = (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE); 104 CheckErr(res); 105 106 locator_bufferqueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE; 107 locator_bufferqueue.numBuffers = 0; 108 locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 109 locator_outputmix.outputMix = outputmixObject; 110 111 pcm.formatType = SL_DATAFORMAT_PCM; 112 pcm.numChannels = 2; 113 pcm.samplesPerSec = SL_SAMPLINGRATE_44_1; 114 pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; 115 pcm.containerSize = 16; 116 pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 117 pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; 118 119 audiosrc.pLocator = &locator_bufferqueue; 120 audiosrc.pFormat = &pcm; 121 audiosnk.pLocator = &locator_outputmix; 122 audiosnk.pFormat = NULL; 123 124 // initialize the test tone to be a sine sweep from 441 Hz to 882 Hz 125 unsigned nframes = sizeof(stereoBuffer1) / sizeof(stereoBuffer1[0]); 126 float nframes_ = (float) nframes; 127 SLuint32 i; 128 for (i = 0; i < nframes; ++i) { 129 float i_ = (float) i; 130 float pcm_ = sin((i_ * (1.0f + 0.5f * (i_ / nframes_)) * 0.01 * M_PI * 2.0)); 131 int pcm = (int) (pcm_ * 32766.0); 132 ASSERT_TRUE(-32768 <= pcm && pcm <= 32767) << "pcm out of bound " << pcm; 133 stereoBuffer1[i].left = pcm; 134 stereoBuffer1[nframes - 1 - i].right = pcm; 135 } 136 } 137 138 virtual void TearDown() { 139 // Clean up the mixer and the engine 140 // (must be done in that order, and after player destroyed) 141 if (outputmixObject){ 142 (*outputmixObject)->Destroy(outputmixObject); 143 outputmixObject = NULL; 144 } 145 if (engineObject){ 146 (*engineObject)->Destroy(engineObject); 147 engineObject = NULL; 148 } 149 } 150 151 void DestroyPlayer() { 152 if (playerObject){ 153 //printf("destroy player\n"); 154 (*playerObject)->Destroy(playerObject); 155 playerObject = NULL; 156 } 157 } 158 159 /* Test case for creating audio player with various invalid values for numBuffers*/ 160 void InvalidBuffer() { 161 162 for (unsigned i = 0; i < sizeof(invalidNumBuffers) / sizeof(invalidNumBuffers[0]); ++i) { 163 SLuint32 numBuffers = invalidNumBuffers[i]; 164 165 locator_bufferqueue.numBuffers = numBuffers; 166 //printf("create audio player - invalid\n"); 167 SLresult result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, 168 &audiosrc, &audiosnk, 1, ids, flags); 169 ASSERT_EQ(SL_RESULT_PARAMETER_INVALID, result); 170 ASSERT_EQ(NULL, playerObject); 171 172 } 173 } 174 175 /*Prepare the buffer*/ 176 void PrepareValidBuffer(SLuint32 numBuffers) { 177 178 locator_bufferqueue.numBuffers = numBuffers; 179 //printf("create audio player - valid\n"); 180 res = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 181 1, ids, flags); 182 CheckErr(res); 183 res = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 184 CheckErr(res); 185 // get the play interface 186 res = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 187 CheckErr(res); 188 // verify that player is initially stopped 189 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 190 CheckErr(res); 191 ASSERT_EQ(SL_PLAYSTATE_STOPPED, playerState); 192 193 // get the buffer queue interface 194 res = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, &playerBufferQueue); 195 CheckErr(res); 196 197 // verify that buffer queue is initially empty 198 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 199 CheckErr(res); 200 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 201 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 202 } 203 204 void EnqueueMaxBuffer(SLuint32 numBuffers) { 205 SLuint32 j; 206 207 for (j = 0; j < numBuffers; ++j) { 208 res = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 209 CheckErr(res); 210 // verify that each buffer is enqueued properly and increments the buffer count 211 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 212 CheckErr(res); 213 ASSERT_EQ(j + 1, bufferqueueState.count); 214 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 215 } 216 } 217 218 void EnqueueExtraBuffer(SLuint32 numBuffers) { 219 // enqueue one more buffer and make sure it fails 220 res = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 221 ASSERT_EQ(SL_RESULT_BUFFER_INSUFFICIENT, res); 222 // verify that the failed enqueue did not affect the buffer count 223 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 224 CheckErr(res); 225 ASSERT_EQ(numBuffers, bufferqueueState.count); 226 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 227 } 228 229 void SetPlayerState(SLuint32 state) { 230 res = (*playerPlay)->SetPlayState(playerPlay, state); 231 CheckErr(res); 232 //verify the state can set correctly 233 GetPlayerState(state); 234 } 235 236 void GetPlayerState(SLuint32 state) { 237 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 238 CheckErr(res); 239 ASSERT_EQ(state, playerState); 240 } 241 242 void ClearQueue() { 243 // now clear the buffer queue 244 res = (*playerBufferQueue)->Clear(playerBufferQueue); 245 CheckErr(res); 246 // make sure the clear works 247 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 248 CheckErr(res); 249 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 250 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 251 } 252 253 void CheckBufferCount(SLuint32 ExpectedCount, SLuint32 ExpectedPlayIndex) { 254 // changing the play state should not affect the buffer count 255 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 256 CheckErr(res); 257 ASSERT_EQ(ExpectedCount, bufferqueueState.count); 258 ASSERT_EQ(ExpectedPlayIndex, bufferqueueState.playIndex); 259 } 260 261 void PlayBufferQueue() { 262 // enqueue a buffer 263 res = (*playerBufferQueue)->Enqueue(playerBufferQueue, stereoBuffer1, 264 sizeof(stereoBuffer1)); 265 CheckErr(res); 266 // set play state to playing 267 res = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 268 CheckErr(res); 269 // state should be playing immediately after enqueue 270 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 271 CheckErr(res); 272 ASSERT_EQ(SL_PLAYSTATE_PLAYING, playerState); 273 // buffer should still be on the queue 274 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 275 CheckErr(res); 276 ASSERT_EQ((SLuint32) 1, bufferqueueState.count); 277 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 278 LOGV("Before 1.5 sec"); 279 // wait 1.5 seconds 280 usleep(1500000); 281 LOGV("After 1.5 sec"); 282 // state should still be playing 283 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 284 LOGV("GetPlayState"); 285 CheckErr(res); 286 ASSERT_EQ(SL_PLAYSTATE_PLAYING, playerState); 287 // buffer should be removed from the queue 288 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 289 CheckErr(res); 290 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 291 ASSERT_EQ((SLuint32) 1, bufferqueueState.playIndex); 292 LOGV("TestEnd"); 293 } 294}; 295 296TEST_F(TestBufferQueue, testInvalidBuffer){ 297 LOGV("Test Fixture: InvalidBuffer"); 298 InvalidBuffer(); 299} 300 301TEST_F(TestBufferQueue, testValidBuffer) { 302 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 303 SLuint32 numBuffers = validNumBuffers[i]; 304 PrepareValidBuffer(numBuffers); 305 DestroyPlayer(); 306 } 307} 308 309TEST_F(TestBufferQueue, testEnqueueMaxBuffer) { 310 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 311 SLuint32 numBuffers = validNumBuffers[i]; 312 PrepareValidBuffer(numBuffers); 313 EnqueueMaxBuffer(numBuffers); 314 DestroyPlayer(); 315 } 316} 317 318TEST_F(TestBufferQueue, testEnqueueExtraBuffer) { 319 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 320 SLuint32 numBuffers = validNumBuffers[i]; 321 PrepareValidBuffer(numBuffers); 322 EnqueueMaxBuffer(numBuffers); 323 EnqueueExtraBuffer(numBuffers); 324 GetPlayerState(SL_PLAYSTATE_STOPPED); 325 DestroyPlayer(); 326 } 327} 328 329TEST_F(TestBufferQueue, testEnqueueAtStopped) { 330 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 331 SLuint32 numBuffers = validNumBuffers[i]; 332 PrepareValidBuffer(numBuffers); 333 SetPlayerState(SL_PLAYSTATE_STOPPED); 334 EnqueueMaxBuffer(numBuffers); 335 CheckBufferCount(numBuffers, (SLuint32) 0); 336 DestroyPlayer(); 337 } 338} 339 340TEST_F(TestBufferQueue, testEnqueueAtPaused) { 341 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 342 SLuint32 numBuffers = validNumBuffers[i]; 343 PrepareValidBuffer(numBuffers); 344 SetPlayerState(SL_PLAYSTATE_PAUSED); 345 EnqueueMaxBuffer(numBuffers); 346 CheckBufferCount(numBuffers, (SLuint32) 0); 347 DestroyPlayer(); 348 } 349} 350 351TEST_F(TestBufferQueue, testClearQueue) { 352 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 353 SLuint32 numBuffers = validNumBuffers[i]; 354 PrepareValidBuffer(numBuffers); 355 EnqueueMaxBuffer(numBuffers); 356 ClearQueue(); 357 DestroyPlayer(); 358 } 359} 360 361TEST_F(TestBufferQueue, testStateTransitionEmptyQueue) { 362 static const SLuint32 newStates[] = { 363 SL_PLAYSTATE_PAUSED, // paused -> paused 364 SL_PLAYSTATE_STOPPED, // paused -> stopped 365 SL_PLAYSTATE_PAUSED, // stopped -> paused 366 SL_PLAYSTATE_PLAYING, // paused -> playing 367 SL_PLAYSTATE_PLAYING, // playing -> playing 368 SL_PLAYSTATE_STOPPED, // playing -> stopped 369 SL_PLAYSTATE_STOPPED, // stopped -> stopped 370 SL_PLAYSTATE_PLAYING, // stopped -> playing 371 SL_PLAYSTATE_PAUSED // playing -> paused 372 }; 373 374 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 375 SLuint32 numBuffers = validNumBuffers[i]; 376 SLuint32 j; 377 378 PrepareValidBuffer(numBuffers); 379 /* Set initial state to paused*/ 380 SetPlayerState(SL_PLAYSTATE_PAUSED); 381 382 for (j = 0; j < sizeof(newStates) / sizeof(newStates[0]); ++j) { 383 SetPlayerState(newStates[j]); 384 CheckBufferCount((SLuint32) 0, (SLuint32) 0); 385 } 386 DestroyPlayer(); 387 } 388} 389 390TEST_F(TestBufferQueue, testStateTransitionNonEmptyQueue) { 391 static const SLuint32 newStates[] = { 392 SL_PLAYSTATE_PAUSED, // paused -> paused 393 SL_PLAYSTATE_STOPPED, // paused -> stopped 394 SL_PLAYSTATE_STOPPED, // stopped -> stopped 395 SL_PLAYSTATE_PAUSED // stopped -> paused 396 }; 397 398 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 399 SLuint32 numBuffers = validNumBuffers[i]; 400 SLuint32 j; 401 402 /* Prepare the player */ 403 PrepareValidBuffer(numBuffers); 404 EnqueueMaxBuffer(numBuffers); 405 SetPlayerState(SL_PLAYSTATE_PAUSED); 406 407 for (j = 0; j < sizeof(newStates) / sizeof(newStates[0]); ++j) { 408 SetPlayerState(newStates[j]); 409 CheckBufferCount(numBuffers, (SLuint32) 0); 410 } 411 DestroyPlayer(); 412 } 413} 414 415TEST_F(TestBufferQueue, testStatePlayBuffer){ 416 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 417 SLuint32 numBuffers = validNumBuffers[i]; 418 PrepareValidBuffer(numBuffers); 419 PlayBufferQueue(); 420 DestroyPlayer(); 421 } 422} 423 424int main(int argc, char **argv) { 425 testing::InitGoogleTest(&argc, argv); 426 return RUN_ALL_TESTS(); 427} 428