sles.cpp revision d07ed7df4ec9338f97f12627690d58ed9b34f25b
1773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi/* 2773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project 3773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * 4773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 5773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * you may not use this file except in compliance with the License. 6773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * You may obtain a copy of the License at 7773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * 8773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 9773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * 10773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 11773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 12773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * See the License for the specific language governing permissions and 14773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * limitations under the License. 15773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi */ 16d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 17d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* OpenSL ES prototype */ 18d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 19773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi#include "sles_allinclusive.h" 20d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 21bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Private functions */ 22bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 23b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten// Map an IObject to it's "object ID" (which is really a class ID) 24b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 25b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn KastenSLuint32 IObjectToObjectID(IObject *this) 26b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 27b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(NULL != this); 28b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return this->mClass->mObjectID; 29b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 30b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 31bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Map SLInterfaceID to its minimal perfect hash (MPH), or -1 if unknown 32bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 3361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/*static*/ int IID_to_MPH(const SLInterfaceID iid) 34d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 35bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (&SL_IID_array[0] <= iid && &SL_IID_array[MPH_MAX] > iid) 36bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return iid - &SL_IID_array[0]; 37bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL != iid) { 38bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten // FIXME Replace this linear search by a good MPH algorithm 39bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct SLInterfaceID_ *srch = &SL_IID_array[0]; 40bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten unsigned MPH; 41bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten for (MPH = 0; MPH < MPH_MAX; ++MPH, ++srch) 42bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (!memcmp(iid, srch, sizeof(struct SLInterfaceID_))) 43bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return MPH; 44bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 45bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return -1; 46bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 47bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 48d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten// Convert POSIX pthread error code to OpenSL ES result code 49d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 50d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn KastenSLresult err_to_result(int err) 51d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten{ 52d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten if (EAGAIN == err || ENOMEM == err) 53d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_RESOURCE_ERROR; 54d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten if (0 != err) 55d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_INTERNAL_ERROR; 56d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_SUCCESS; 57d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} 58d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 5929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten// Check the interface IDs passed into a Create operation 6029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten 61979a3f8743646af9999a89dff9e13b972b7efd87Glenn KastenSLresult checkInterfaces(const ClassTable *class__, 62bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 63bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const SLboolean *pInterfaceRequired, unsigned *pExposedMask) 64bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 65bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten assert(NULL != class__ && NULL != pExposedMask); 66bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten unsigned exposedMask = 0; 67bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct iid_vtable *interfaces = class__->mInterfaces; 68bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 interfaceCount = class__->mInterfaceCount; 69bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 i; 70bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten // FIXME This section could be pre-computed per class 71bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten for (i = 0; i < interfaceCount; ++i) { 72bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten switch (interfaces[i].mInterface) { 73bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten case INTERFACE_IMPLICIT: 74bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten exposedMask |= 1 << i; 75bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 76bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten default: 77bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 78bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 79bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 80d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten if (0 < numInterfaces) { 81d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten if (NULL == pInterfaceIds || NULL == pInterfaceRequired) 82d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 83d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten for (i = 0; i < numInterfaces; ++i) { 84bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLInterfaceID iid = pInterfaceIds[i]; 85bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL == iid) 86bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 8729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten int MPH, index; 8829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten if ((0 > (MPH = IID_to_MPH(iid))) || 8929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten (0 > (index = class__->mMPH_to_index[MPH]))) { 90bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (pInterfaceRequired[i]) 91bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 92bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten continue; 93bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 9429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // FIXME this seems a bit strong? what is correct logic? 9529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // we are requesting a duplicate explicit interface, 9629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // or we are requesting one which is already implicit ? 9729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // if (exposedMask & (1 << index)) 9829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // return SL_RESULT_PARAMETER_INVALID; 99daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // can we request dynamic interfaces here? 10029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten exposedMask |= (1 << index); 101d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 102d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 103bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten *pExposedMask = exposedMask; 104d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 105d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 106d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 10761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten// private helper shared by decoder and encoder 10861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn KastenSLresult GetCodecCapabilities(SLuint32 decoderId, SLuint32 *pIndex, 10961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten SLAudioCodecDescriptor *pDescriptor, 11061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten const struct CodecDescriptor *codecDescriptors) 111bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 11261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (NULL == pIndex) 11361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 11461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten const struct CodecDescriptor *cd = codecDescriptors; 11561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten SLuint32 index; 11661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (NULL == pDescriptor) { 11761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten for (index = 0 ; NULL != cd->mDescriptor; ++cd) 11861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (cd->mCodecID == decoderId) 11961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ++index; 12061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten *pIndex = index; 12161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_SUCCESS; 12261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 12361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten index = *pIndex; 12461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten for ( ; NULL != cd->mDescriptor; ++cd) { 12561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (cd->mCodecID == decoderId) { 12661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (0 == index) { 12761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten *pDescriptor = *cd->mDescriptor; 12861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_SUCCESS; 12961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 13061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten --index; 13161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 13261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 13361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 134bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 1352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten 136daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult checkDataLocator(void *pLocator, DataLocator *pDataLocator) 137daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 138daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pLocator) { 139daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mLocatorType = 0; 140daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 141daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 142daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 locatorType = *(SLuint32 *)pLocator; 143daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (locatorType) { 144daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_ADDRESS: 145daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator; 146daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 < pDataLocator->mAddress.length && NULL == pDataLocator->mAddress.pAddress) 147daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 148daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 149daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 150daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator; 151daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 == pDataLocator->mBufferQueue.numBuffers) 152daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 153daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // pDataLocator->mBufferQueue.numBuffers = 2; 154daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // FIXME check against a max 155daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 156daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_IODEVICE: 157daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 158daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator; 159daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 deviceType = pDataLocator->mIODevice.deviceType; 160daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL != pDataLocator->mIODevice.device) { 161daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (IObjectToObjectID((IObject *) pDataLocator->mIODevice.device)) { 162daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_OBJECTID_LEDDEVICE: 163daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_LEDARRAY != deviceType) 164daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 165daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 166daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_OBJECTID_VIBRADEVICE: 167daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_VIBRA != deviceType) 168daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 169daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 170daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 171daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 172daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 173daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mIODevice.deviceID = 0; 174daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } else { 175daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataLocator->mIODevice.deviceID) { 176daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DEFAULTDEVICEID_LED: 177daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_LEDARRAY != deviceType) 178daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 179daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 180daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DEFAULTDEVICEID_VIBRA: 181daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_VIBRA != deviceType) 182daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 183daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 184daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DEFAULTDEVICEID_AUDIOINPUT: 185daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_AUDIOINPUT != deviceType) 186daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 187daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 188daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 189daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 190daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 191daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 192daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 193daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 194daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 195daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator; 196daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 == pDataLocator->mMIDIBufferQueue.tpqn) 197daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue.tpqn = 192; 198daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 == pDataLocator->mMIDIBufferQueue.numBuffers) 199daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue.numBuffers = 2; 200daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 201daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 202daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator; 203daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if ((NULL == pDataLocator->mOutputMix.outputMix) || (SL_OBJECTID_OUTPUTMIX != IObjectToObjectID((IObject *) pDataLocator->mOutputMix.outputMix))) 204daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 205daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 206daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 207daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 208daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mURI = *(SLDataLocator_URI *)pLocator; 209daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataLocator->mURI.URI) 210daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 211daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten size_t len = strlen((const char *) pDataLocator->mURI.URI); 212daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLchar *myURI = (SLchar *) malloc(len + 1); 213daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == myURI) 214daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_MEMORY_FAILURE; 215daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten memcpy(myURI, pDataLocator->mURI.URI, len + 1); 216daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // Verify that another thread didn't change the NUL-terminator after we used it 217daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // to determine length of string to copy. It's OK if the string became shorter. 218daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if ('\0' != myURI[len]) { 219daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(myURI); 220daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 221daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 222daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mURI.URI = myURI; 223daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 224daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 225daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 226daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 227daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 228daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // Verify that another thread didn't change the locatorType field after we used it 229daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // to determine sizeof struct to copy. 230daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (locatorType != pDataLocator->mLocatorType) 231daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 232daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 233daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 234daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 235daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic void freeDataLocator(DataLocator *pDataLocator) 236daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 237daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataLocator->mLocatorType) { 238daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 239daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(pDataLocator->mURI.URI); 24000d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten pDataLocator->mURI.URI = NULL; 241daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 242daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 243daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 244daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 245daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 246daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 247daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult checkDataFormat(void *pFormat, DataFormat *pDataFormat) 248daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 249daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pFormat) { 250daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mFormatType = 0; 251daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 252daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 253daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 formatType = *(SLuint32 *)pFormat; 254daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (formatType) { 255daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_PCM: 256daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat; 257daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.numChannels) { 258daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 1: 259daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 2: 260daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 261daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 0: 262daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 263daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 264daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 265daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 266daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.samplesPerSec) { 267daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_8: 268daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_11_025: 269daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_12: 270daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_16: 271daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_22_05: 272daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_24: 273daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_32: 274daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_44_1: 275daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_48: 276daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_64: 277daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_88_2: 278daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_96: 279daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_192: 280daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 281daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 0: 282daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 283daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 284daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 285daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 286daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.bitsPerSample) { 287daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_8: 288daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_16: 289daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 290daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_20: 291daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_24: 292daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_28: 293daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_32: 294daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 295daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 296daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 297daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 298daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.containerSize) { 299daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_8: 300daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_16: 301daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) 302daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 303daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 304daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 305daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 306daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 307daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.channelMask) { 308daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT: 309daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (2 != pDataFormat->mPCM.numChannels) 310daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 311daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 312daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SPEAKER_FRONT_LEFT: 313daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SPEAKER_FRONT_RIGHT: 314daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SPEAKER_FRONT_CENTER: 315daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (1 != pDataFormat->mPCM.numChannels) 316daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 317daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 318daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 0: 319daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ? SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER; 320daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 321daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 322daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 323daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 324daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.endianness) { 325daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_BYTEORDER_LITTLEENDIAN: 326daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 327daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_BYTEORDER_BIGENDIAN: 328daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 329daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 330daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 331daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 332daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 333daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_MIME: 334daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 335daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat; 336daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataFormat->mMIME.mimeType) 337daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 338daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten size_t len = strlen((const char *) pDataFormat->mMIME.mimeType); 339daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLchar *myMIME = (SLchar *) malloc(len + 1); 340daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == myMIME) 341daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_MEMORY_FAILURE; 342daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1); 343daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // ditto 344daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if ('\0' != myMIME[len]) { 345daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(myMIME); 346daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 347daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 348daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mMIME.mimeType = myMIME; 349daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 350daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 351daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 352daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 353daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 354daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (formatType != pDataFormat->mFormatType) 355daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 356daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 357daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 358daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 359daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic void freeDataFormat(DataFormat *pDataFormat) 360daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 361daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mFormatType) { 362daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_MIME: 363daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(pDataFormat->mMIME.mimeType); 36400d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten pDataFormat->mMIME.mimeType = NULL; 365daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 366daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 367daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 368daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 369daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 370daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 371daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn KastenSLresult checkDataSource(const SLDataSource *pDataSrc, DataLocatorFormat *pDataLocatorFormat) 372daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 373daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataSrc) 374daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 375daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataSource myDataSrc = *pDataSrc; 376daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLresult result; 377daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataLocator(myDataSrc.pLocator, &pDataLocatorFormat->mLocator); 378daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_RESULT_SUCCESS != result) 379daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 380daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataFormat(myDataSrc.pFormat, &pDataLocatorFormat->mFormat); 381daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_RESULT_SUCCESS != result) { 382daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 383daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 384daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 385acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 386acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 387daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 388daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 389daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 390daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn KastenSLresult checkDataSink(const SLDataSink *pDataSink, DataLocatorFormat *pDataLocatorFormat) 391daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 392daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataSink) 393daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 394daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataSink myDataSink = *pDataSink; 395daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLresult result; 396daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataLocator(myDataSink.pLocator, &pDataLocatorFormat->mLocator); 397daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_RESULT_SUCCESS != result) 398daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 399daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat); 400daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_RESULT_SUCCESS != result) { 401daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 402daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 403daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 404acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 405acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 406daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 407daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 408daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 409daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenvoid freeDataLocatorFormat(DataLocatorFormat *dlf) 410daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 411daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataLocator(&dlf->mLocator); 412daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataFormat(&dlf->mFormat); 413daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 414daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 41561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/* Interface initialization hooks */ 4162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten 417a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenextern void 418a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DCommit_init(void *), 419a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DDoppler_init(void *), 420a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DGrouping_init(void *), 421a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_init(void *), 422a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DMacroscopic_init(void *), 423a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DSource_init(void *), 42461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioDecoderCapabilities_init(void *), 42561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioEncoderCapabilities_init(void *), 42661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioEncoder_init(void *), 42761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioIODeviceCapabilities_init(void *), 428a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IBassBoost_init(void *), 4290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IBufferQueue_init(void *), 43061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDeviceVolume_init(void *), 43161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicInterfaceManagement_init(void *), 43261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicSource_init(void *), 43361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_init(void *), 4340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngineCapabilities_init(void *), 4350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_init(void *), 436a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEnvironmentalReverb_init(void *), 437a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEqualizer_init(void *), 43861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ILEDArray_init(void *), 4390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMessage_init(void *), 4400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMuteSolo_init(void *), 4410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITempo_init(void *), 4420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITime_init(void *), 44361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataExtraction_init(void *), 44461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataTraversal_init(void *), 44561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMuteSolo_init(void *), 44661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_init(void *), 4470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IOutputMix_init(void *), 44861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPitch_init(void *), 4490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_init(void *), 45061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPlaybackRate_init(void *), 45161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPrefetchStatus_init(void *), 452a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IPresetReverb_init(void *), 45361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRatePitch_init(void *), 45461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRecord_init(void *), 4550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten ISeek_init(void *), 45661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IThreadSync_init(void *), 45761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IVibra_init(void *), 458a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IVirtualizer_init(void *), 4590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IVisualization_init(void *), 4600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IVolume_init(void *); 461a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 462b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#ifdef USE_OUTPUTMIXEXT 463b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kastenextern void 464b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten IOutputMixExt_init(void *); 465b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#endif 466b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 46761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/*static*/ const struct MPH_init MPH_init_table[MPH_MAX] = { 468510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DCOMMIT, */ I3DCommit_init, NULL, NULL }, 469510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DDOPPLER, */ I3DDoppler_init, NULL, NULL }, 470510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DGROUPING, */ I3DGrouping_init, NULL, NULL }, 471510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DLOCATION, */ I3DLocation_init, NULL, NULL }, 472510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DMACROSCOPIC, */ I3DMacroscopic_init, NULL, NULL }, 473510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DSOURCE, */ I3DSource_init, NULL, NULL }, 474510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_AUDIODECODERCAPABILITIES, */ IAudioDecoderCapabilities_init, NULL, NULL }, 475510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_AUDIOENCODER, */ IAudioEncoder_init, NULL, NULL }, 476510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_AUDIOENCODERCAPABILITIES, */ IAudioEncoderCapabilities_init, NULL, NULL }, 477510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_AUDIOIODEVICECAPABILITIES, */ IAudioIODeviceCapabilities_init, NULL, NULL }, 478510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_BASSBOOST, */ IBassBoost_init, NULL, NULL }, 479510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_BUFFERQUEUE, */ IBufferQueue_init, NULL, NULL }, 480510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_DEVICEVOLUME, */ IDeviceVolume_init, NULL, NULL }, 481510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ IDynamicInterfaceManagement_init, NULL, NULL }, 482510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_DYNAMICSOURCE, */ IDynamicSource_init, NULL, NULL }, 483510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_EFFECTSEND, */ IEffectSend_init, NULL, NULL }, 484510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_ENGINE, */ IEngine_init, NULL, NULL }, 485510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_ENGINECAPABILITIES, */ IEngineCapabilities_init, NULL, NULL }, 486510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_ENVIRONMENTALREVERB, */ IEnvironmentalReverb_init, NULL, NULL }, 487510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_EQUALIZER, */ IEqualizer_init, NULL, NULL }, 488510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_LED, */ ILEDArray_init, NULL, NULL }, 489510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_METADATAEXTRACTION, */ IMetadataExtraction_init, NULL, NULL }, 490510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_METADATATRAVERSAL, */ IMetadataTraversal_init, NULL, NULL }, 491510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MIDIMESSAGE, */ IMIDIMessage_init, NULL, NULL }, 492510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MIDITIME, */ IMIDITime_init, NULL, NULL }, 493510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MIDITEMPO, */ IMIDITempo_init, NULL, NULL }, 494510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MIDIMUTESOLO, */ IMIDIMuteSolo_init, NULL, NULL }, 495510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MUTESOLO, */ IMuteSolo_init, NULL, NULL }, 496510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_NULL, */ NULL, NULL, NULL }, 497510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_OBJECT, */ IObject_init, NULL, NULL }, 498510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_OUTPUTMIX, */ IOutputMix_init, NULL, NULL }, 499510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PITCH, */ IPitch_init, NULL, NULL }, 500510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PLAY, */ IPlay_init, NULL, NULL }, 501510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PLAYBACKRATE, */ IPlaybackRate_init, NULL, NULL }, 502510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL }, 503510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PRESETREVERB, */ IPresetReverb_init, NULL, NULL }, 504510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_RATEPITCH, */ IRatePitch_init, NULL, NULL }, 505510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_RECORD, */ IRecord_init, NULL, NULL }, 506510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_SEEK, */ ISeek_init, NULL, NULL }, 507510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_THREADSYNC, */ IThreadSync_init, NULL, NULL }, 508510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_VIBRA, */ IVibra_init, NULL, NULL }, 509510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_VIRTUALIZER, */ IVirtualizer_init, NULL, NULL }, 510510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_VISUALIZATION, */ IVisualization_init, NULL, NULL }, 511510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_VOLUME, */ IVolume_init, NULL, NULL }, 512bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten { /* MPH_OUTPUTMIXEXT, */ 513bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT 514510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten IOutputMixExt_init, NULL, NULL 515bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else 516510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten NULL, NULL, NULL 517bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif 518bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 519bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}; 520bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 521bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Construct a new instance of the specified class, exposing selected interfaces 522bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 523ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn KastenIObject *construct(const ClassTable *class__, unsigned exposedMask, SLEngineItf engine) 524bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 52572a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten IObject *this; 52672a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten this = (IObject *) calloc(1, class__->mSize); 527bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL != this) { 52872a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten unsigned lossOfControlMask = 0; 529ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // a NULL engine means we are constructing the engine 53072a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten IEngine *thisEngine = (IEngine *) engine; 531d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (NULL == thisEngine) { 53272a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten thisEngine = &((CEngine *) this)->mEngine; 533d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten } else { 534ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_lock_exclusive(thisEngine); 535d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (MAX_INSTANCE <= thisEngine->mInstanceCount) { 536ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // too many objects 537ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 538d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten free(this); 539ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten return NULL; 540ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 541d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // pre-allocate a pending slot, but don't assign bit from mInstanceMask yet 542ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten ++thisEngine->mInstanceCount; 543d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(((unsigned) ~0) != thisEngine->mInstanceMask); 544ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 545ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // const, no lock needed 546ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten if (thisEngine->mLossOfControlGlobal) 547ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten lossOfControlMask = ~0; 548ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 54972a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten this->mLossOfControlMask = lossOfControlMask; 550ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mClass = class__; 551ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mEngine = thisEngine; 552bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct iid_vtable *x = class__->mInterfaces; 553510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint8 *interfaceStateP = this->mInterfaceStates; 554510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint32 index; 555510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten for (index = 0; index < class__->mInterfaceCount; ++index, ++x, exposedMask >>= 1) { 556510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint32 state; 557bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (exposedMask & 1) { 55883f93b0afd3607b1570d8473c2f6e45276c133baGlenn Kasten void *self = (char *) this + x->mOffset; 559d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // IObject does not have an mThis, so [1] is not always defined 560d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (index) 561d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten ((IObject **) self)[1] = this; 56283f93b0afd3607b1570d8473c2f6e45276c133baGlenn Kasten VoidHook init = MPH_init_table[x->mMPH].mInit; 563bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL != init) 564bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten (*init)(self); 565510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = INTERFACE_EXPOSED; 566510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } else 567510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = INTERFACE_UNINITIALIZED; 568510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten *interfaceStateP++ = state; 569bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 570ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // only expose new object to sync thread after it is fully initialized 571ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_lock_exclusive(thisEngine); 572d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten unsigned availMask = ~thisEngine->mInstanceMask; 573d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(availMask); 574d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten unsigned i = ctz(availMask); 575d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(MAX_INSTANCE > i); 576d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(NULL == thisEngine->mInstances[i]); 577d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten thisEngine->mInstances[i] = this; 578d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten thisEngine->mInstanceMask |= 1 << i; 579d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // avoid zero as a valid instance ID 580d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten this->mInstanceID = i + 1; 58100d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#ifdef USE_SDL 58200d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten SLboolean unpause = SL_BOOLEAN_FALSE; 58300d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten if (SL_OBJECTID_OUTPUTMIX == class__->mObjectID && NULL == thisEngine->mOutputMix) { 58400d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten thisEngine->mOutputMix = (COutputMix *) this; 58500d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten unpause = SL_BOOLEAN_TRUE; 58600d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten } 58700d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#endif 588ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 58900d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#ifdef USE_SDL 59000d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten if (unpause) 59100d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten SDL_PauseAudio(0); 59200d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#endif 593bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 594bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return this; 595bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 596bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 5970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/* Initial entry points */ 598d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 5990b167267bda99b68346045ccab14e810121d5de4Glenn KastenSLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions, 6000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLEngineOption *pEngineOptions, SLuint32 numInterfaces, 6010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 602d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 6036fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi#ifdef USE_ANDROID 6046fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi android::ProcessState::self()->startThreadPool(); 6056fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi#endif 6060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pEngine) 607d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 6080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pEngine = NULL; 6090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // default values 6100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLboolean threadSafe = SL_BOOLEAN_TRUE; 6110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLboolean lossOfControlGlobal = SL_BOOLEAN_FALSE; 6120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL != pEngineOptions) { 6130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 i; 6140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLEngineOption *option = pEngineOptions; 6150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten for (i = 0; i < numOptions; ++i, ++option) { 6160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (option->feature) { 6170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_ENGINEOPTION_THREADSAFE: 6180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten threadSafe = (SLboolean) option->data; 6190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 6200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_ENGINEOPTION_LOSSOFCONTROL: 6210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten lossOfControlGlobal = (SLboolean) option->data; 6220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 6230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 6240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 6250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 6260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 62729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten } 6280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 629b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE); 630b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten SLresult result = checkInterfaces(pCEngine_class, numInterfaces, 6310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 6320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 6330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 634b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten CEngine *this = (CEngine *) construct(pCEngine_class, exposedMask, NULL); 6350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == this) 6360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 6370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0; 6380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mEngine.mLossOfControlGlobal = lossOfControlGlobal; 6390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mEngineCapabilities.mThreadSafe = threadSafe; 6400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pEngine = &this->mObject.mItf; 641d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 642d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 643d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 6440b167267bda99b68346045ccab14e810121d5de4Glenn KastenSLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces( 6450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 *pNumSupportedInterfaces) 646d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 6470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pNumSupportedInterfaces) 6482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 649b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE); 650b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten *pNumSupportedInterfaces = pCEngine_class->mInterfaceCount; 651d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 652d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 653d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 6540b167267bda99b68346045ccab14e810121d5de4Glenn KastenSLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, 6550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLInterfaceID *pInterfaceId) 656d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 6570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pInterfaceId) 6582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 659b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE); 660b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (pCEngine_class->mInterfaceCount <= index) 661b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 662b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten *pInterfaceId = &SL_IID_array[pCEngine_class->mInterfaces[index].mMPH]; 663d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 664d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 665d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 666d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* End */ 667