BufferQueue_test.cpp revision 4597a7427b697df31d0bbf4c2040806d0c27b6e0
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#define LOG_NDEBUG 0 19#define LOG_TAG "bufferQueue" 20 21#ifdef ANDROID 22#include <utils/Log.h> 23#else 24#define LOGV printf 25#endif 26 27#include <assert.h> 28#include <math.h> 29#include <stdio.h> 30#include <stdlib.h> 31#include <unistd.h> 32#include "SLES/OpenSLES.h" 33 34#include <gtest/gtest.h> 35 36#ifdef ANDROID 37#include "gtest/gtest.h" 38#else 39#define ASSERT_EQ(x, y) assert((x) == (y)) 40#endif 41 42typedef struct { 43 short left; 44 short right; 45} stereo; 46 47// 1 second of stereo audio at 44.1 kHz 48static stereo stereoBuffer1[44100 * 1]; 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 (res != SL_RESULT_SUCCESS) { 55 fprintf(stderr, "%lu SL failure, exiting\n", res); 56 //Fail the test case 57 ASSERT_TRUE(false); 58 } 59} 60 61// The fixture for testing class BufferQueue 62class TestBufferQueue: public ::testing::Test { 63public: 64 SLresult res; 65 SLObjectItf sl; 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 virtual void SetUp() { 90 /*Test setup*/ 91 res = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 92 CheckErr(res); 93 res = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 94 CheckErr(res); 95 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 audiosrc.pLocator = &locator_bufferqueue; 118 audiosrc.pFormat = &pcm; 119 audiosnk.pLocator = &locator_outputmix; 120 audiosnk.pFormat = NULL; 121 122 // initialize the test tone to be a sine sweep from 441 Hz to 882 Hz 123 unsigned nframes = sizeof(stereoBuffer1) / sizeof(stereoBuffer1[0]); 124 float nframes_ = (float) nframes; 125 SLuint32 i; 126 for (i = 0; i < nframes; ++i) { 127 float i_ = (float) i; 128 float pcm_ = sin((i_ * (1.0f + 0.5f * (i_ / nframes_)) * 0.01 * M_PI * 2.0)); 129 int pcm = (int) (pcm_ * 32766.0); 130 ASSERT_TRUE(-32768 <= pcm && pcm <= 32767) << "pcm out of bound " << pcm; 131 stereoBuffer1[i].left = pcm; 132 stereoBuffer1[nframes - 1 - i].right = pcm; 133 } 134 } 135 136 virtual void TearDown() { 137 /* Clean up the player, mixer, and the engine (must be done in that order) */ 138 if (playerObject){ 139 (*playerObject)->Destroy(playerObject); 140 playerObject = NULL; 141 } 142 if (outputmixObject){ 143 (*outputmixObject)->Destroy(outputmixObject); 144 outputmixObject = NULL; 145 } 146 if (engineObject){ 147 (*engineObject)->Destroy(engineObject); 148 engineObject = NULL; 149 } 150 } 151 152 /* Test case for creating audio player with various invalid values for numBuffers*/ 153 void InvalidBuffer() { 154 unsigned nframes = sizeof(stereoBuffer1) / sizeof(stereoBuffer1[0]); 155 float nframes_ = (float) nframes; 156 SLuint32 i; 157 SLInterfaceID ids[1] = { SL_IID_BUFFERQUEUE }; 158 SLboolean flags[1] = { SL_BOOLEAN_TRUE }; 159 160 static const SLuint32 invalidNumBuffers[] = { 0, 0xFFFFFFFF, 0x80000000, 0x10002, 0x102, 161 0x101, 0x100 }; 162 for (i = 0; i < sizeof(invalidNumBuffers) / sizeof(invalidNumBuffers[0]); ++i) { 163 locator_bufferqueue.numBuffers = invalidNumBuffers[i]; 164 LOGV("allocation buffer\n"); 165 SLresult result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, 166 &audiosrc, &audiosnk, 1, ids, flags); 167 ASSERT_EQ(SL_RESULT_PARAMETER_INVALID, result); 168 } 169 } 170 171 /*Prepare the buffer*/ 172 void PrepareValidBuffer(SLuint32 numbuffer) { 173 SLInterfaceID ids2[1] = { SL_IID_BUFFERQUEUE }; 174 SLboolean flags2[1] = { SL_BOOLEAN_TRUE }; 175 176 locator_bufferqueue.numBuffers = validNumBuffers[numbuffer]; 177 res = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 178 1, ids2, flags2); 179 CheckErr(res); 180 res = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 181 CheckErr(res); 182 // get the play interface 183 res = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 184 CheckErr(res); 185 // verify that player is initially stopped 186 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 187 CheckErr(res); 188 ASSERT_EQ(SL_PLAYSTATE_STOPPED, playerState); 189 190 // get the buffer queue interface 191 res = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, &playerBufferQueue); 192 CheckErr(res); 193 194 // verify that buffer queue is initially empty 195 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 196 CheckErr(res); 197 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 198 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 199 } 200 201 void EnqueueMaxBuffer(SLuint32 i) { 202 SLuint32 j; 203 204 for (j = 0; j < validNumBuffers[i]; ++j) { 205 res = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 206 CheckErr(res); 207 // verify that each buffer is enqueued properly and increments the buffer count 208 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 209 CheckErr(res); 210 ASSERT_EQ(j + 1, bufferqueueState.count); 211 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 212 } 213 } 214 215 void EnqueueExtraBuffer(SLuint32 i) { 216 // enqueue one more buffer and make sure it fails 217 res = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 218 ASSERT_EQ(SL_RESULT_BUFFER_INSUFFICIENT, res); 219 // verify that the failed enqueue did not affect the buffer count 220 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 221 CheckErr(res); 222 ASSERT_EQ(validNumBuffers[i], bufferqueueState.count); 223 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 224 } 225 226 void SetPlayerState(SLuint32 state) { 227 res = (*playerPlay)->SetPlayState(playerPlay, state); 228 CheckErr(res); 229 //verify the state can set correctly 230 GetPlayerState(state); 231 } 232 233 void GetPlayerState(SLuint32 state) { 234 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 235 CheckErr(res); 236 ASSERT_EQ(state, playerState); 237 } 238 239 void ClearQueue() { 240 // now clear the buffer queue 241 res = (*playerBufferQueue)->Clear(playerBufferQueue); 242 CheckErr(res); 243 // make sure the clear works 244 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 245 CheckErr(res); 246 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 247 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 248 } 249 250 void CheckBufferCount(SLuint32 ExpectedCount, SLuint32 ExpectedPlayIndex) { 251 // changing the play state should not affect the buffer count 252 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 253 CheckErr(res); 254 ASSERT_EQ(ExpectedCount, bufferqueueState.count); 255 ASSERT_EQ(ExpectedPlayIndex, bufferqueueState.playIndex); 256 } 257 258 void PlayBufferQueue() { 259 // enqueue a buffer 260 res = (*playerBufferQueue)->Enqueue(playerBufferQueue, stereoBuffer1, 261 sizeof(stereoBuffer1)); 262 CheckErr(res); 263 // set play state to playing 264 res = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 265 CheckErr(res); 266 // state should be playing immediately after enqueue 267 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 268 CheckErr(res); 269 ASSERT_EQ(SL_PLAYSTATE_PLAYING, playerState); 270 // buffer should still be on the queue 271 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 272 CheckErr(res); 273 ASSERT_EQ((SLuint32) 1, bufferqueueState.count); 274 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 275 LOGV("Before 1.5 sec"); 276 // wait 1.5 seconds 277 usleep(1500000); 278 LOGV("After 1.5 sec"); 279 // state should still be playing 280 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 281 LOGV("GetPlayState"); 282 CheckErr(res); 283 ASSERT_EQ(SL_PLAYSTATE_PLAYING, playerState); 284 // buffer should be removed from the queue 285 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 286 CheckErr(res); 287 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 288 ASSERT_EQ((SLuint32) 1, bufferqueueState.playIndex); 289 LOGV("TestEnd"); 290 } 291}; 292 293TEST_F(TestBufferQueue, testInvalidBuffer){ 294 LOGV("Test Fixture: InvalidBuffer\n"); 295 InvalidBuffer(); 296} 297 298TEST_F(TestBufferQueue, testValidBuffer) { 299 PrepareValidBuffer(1); 300} 301 302TEST_F(TestBufferQueue, testEnqueueMaxBuffer) { 303 PrepareValidBuffer(1); 304 EnqueueMaxBuffer(1); 305} 306 307TEST_F(TestBufferQueue, testEnqueExtraBuffer) { 308 PrepareValidBuffer(1); 309 EnqueueMaxBuffer(1); 310 EnqueueExtraBuffer(1); 311 GetPlayerState(SL_PLAYSTATE_STOPPED); 312} 313 314TEST_F(TestBufferQueue, testEnqueAtPause) { 315 PrepareValidBuffer(1); 316 SetPlayerState(SL_PLAYSTATE_PAUSED); 317 GetPlayerState(SL_PLAYSTATE_PAUSED); 318 EnqueueMaxBuffer(1); 319 CheckBufferCount((SLuint32) 2, (SLuint32) 0); 320} 321 322TEST_F(TestBufferQueue, testClearQueue) { 323 PrepareValidBuffer(1); 324 EnqueueMaxBuffer(1); 325 ClearQueue(); 326} 327 328TEST_F(TestBufferQueue, testStateTransitionEmptyQueue) { 329 static const SLuint32 newStates[] = { 330 SL_PLAYSTATE_PAUSED, // paused -> paused 331 SL_PLAYSTATE_STOPPED, // paused -> stopped 332 SL_PLAYSTATE_PAUSED, // stopped -> paused 333 SL_PLAYSTATE_PLAYING, // paused -> playing 334 SL_PLAYSTATE_PLAYING, // playing -> playing 335 SL_PLAYSTATE_STOPPED, // playing -> stopped 336 SL_PLAYSTATE_STOPPED, // stopped -> stopped 337 SL_PLAYSTATE_PLAYING, // stopped -> playing 338 SL_PLAYSTATE_PAUSED // playing -> paused 339 }; 340 SLuint32 j; 341 342 PrepareValidBuffer(8); 343 /* Set inital state to pause*/ 344 SetPlayerState(SL_PLAYSTATE_PAUSED); 345 346 for (j = 0; j < sizeof(newStates) / sizeof(newStates[0]); ++j) { 347 SetPlayerState(newStates[j]); 348 CheckBufferCount((SLuint32) 0, (SLuint32) 0); 349 } 350} 351 352TEST_F(TestBufferQueue, testStateTransitionNonEmptyQueue) { 353 static const SLuint32 newStates[] = { 354 SL_PLAYSTATE_PAUSED, // paused -> paused 355 SL_PLAYSTATE_STOPPED, // paused -> stopped 356 SL_PLAYSTATE_STOPPED, // stopped -> stopped 357 SL_PLAYSTATE_PAUSED // stopped -> paused 358 }; 359 SLuint32 j; 360 361 /* Prepare the player */ 362 PrepareValidBuffer(2); 363 EnqueueMaxBuffer(2); 364 SetPlayerState(SL_PLAYSTATE_PAUSED); 365 366 for (j = 0; j < sizeof(newStates) / sizeof(newStates[0]); ++j) { 367 SetPlayerState(newStates[j]); 368 CheckBufferCount((SLuint32) 3, (SLuint32) 0); 369 } 370} 371 372TEST_F(TestBufferQueue, testStatePlayBuffer){ 373 PrepareValidBuffer(8); 374 PlayBufferQueue(); 375} 376 377int main(int argc, char **argv) { 378 testing::InitGoogleTest(&argc, argv); 379 return RUN_ALL_TESTS(); 380} 381