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