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