sles.cpp revision 4597a7427b697df31d0bbf4c2040806d0c27b6e0
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 17e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/* OpenSL ES private and global functions not associated with an interface or class */ 18d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 19773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi#include "sles_allinclusive.h" 20d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 21bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 22e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Return true if the specified interface exists and has been initialized for this object. 23e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * Returns false if the class does not support this kind of interface, or the class supports the 24e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * interface but this particular object has not had the interface exposed at object creation time 25e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * or by DynamicInterface::AddInterface. Note that the return value is not affected by whether 26e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * the application has requested access to the interface with Object::GetInterface. Assumes on 27e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * entry that the object is locked for either shared or exclusive access. 28e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten */ 290b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 30e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kastenbool IsInterfaceInitialized(IObject *this, unsigned MPH) 31e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten{ 32e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten assert(NULL != this); 33e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten assert( /* (MPH_MIN <= MPH) && */ (MPH < (unsigned) MPH_MAX)); 34e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten const ClassTable *class__ = this->mClass; 35e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten assert(NULL != class__); 36e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten int index; 37e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten if (0 > (index = class__->mMPH_to_index[MPH])) 38e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten return false; 39e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten assert(MAX_INDEX >= class__->mInterfaceCount); 40e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten assert(class__->mInterfaceCount > (unsigned) index); 41e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten switch (this->mInterfaceStates[index]) { 42e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten case INTERFACE_EXPOSED: 43e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten case INTERFACE_ADDED: 44e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten return true; 45e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten default: 46e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten return false; 47e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten } 48e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten} 49e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten 50e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten 51e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Map an IObject to it's "object ID" (which is really a class ID) */ 52b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 53b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn KastenSLuint32 IObjectToObjectID(IObject *this) 54b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 55b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(NULL != this); 56b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return this->mClass->mObjectID; 57b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 58b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 590b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 60e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Convert POSIX pthread error code to OpenSL ES result code */ 61d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 62d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn KastenSLresult err_to_result(int err) 63d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten{ 64d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten if (EAGAIN == err || ENOMEM == err) 65d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_RESOURCE_ERROR; 66d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten if (0 != err) 67d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_INTERNAL_ERROR; 68d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_SUCCESS; 69d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} 70d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 710b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 72e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check the interface IDs passed into a Create operation */ 7329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten 74ed46c29d6a09112dbbf584c82953f63289596fd6Glenn KastenSLresult checkInterfaces(const ClassTable *class__, SLuint32 numInterfaces, 75ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired, unsigned *pExposedMask) 76bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 77bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten assert(NULL != class__ && NULL != pExposedMask); 78bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten unsigned exposedMask = 0; 79bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct iid_vtable *interfaces = class__->mInterfaces; 80bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 interfaceCount = class__->mInterfaceCount; 81bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 i; 82bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten for (i = 0; i < interfaceCount; ++i) { 83bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten switch (interfaces[i].mInterface) { 84bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten case INTERFACE_IMPLICIT: 85bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten exposedMask |= 1 << i; 86bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 87bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten default: 88bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 89bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 90bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 91d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten if (0 < numInterfaces) { 92d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten if (NULL == pInterfaceIds || NULL == pInterfaceRequired) 93d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 94d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten for (i = 0; i < numInterfaces; ++i) { 95bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLInterfaceID iid = pInterfaceIds[i]; 96bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL == iid) 97bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 9829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten int MPH, index; 9929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten if ((0 > (MPH = IID_to_MPH(iid))) || 10029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten (0 > (index = class__->mMPH_to_index[MPH]))) { 101bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (pInterfaceRequired[i]) 102bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 103bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten continue; 104bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 10529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten exposedMask |= (1 << index); 106d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 107d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 108bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten *pExposedMask = exposedMask; 109d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 110d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 111d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 1120b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 113e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Helper shared by decoder and encoder */ 1140b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 115a438eb1cf1ae602afab00336528dd230bd929206Glenn KastenSLresult GetCodecCapabilities(SLuint32 codecId, SLuint32 *pIndex, 116369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten SLAudioCodecDescriptor *pDescriptor, const CodecDescriptor *codecDescriptors) 117bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 11861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (NULL == pIndex) 11961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 120369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten const CodecDescriptor *cd = codecDescriptors; 12161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten SLuint32 index; 12261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (NULL == pDescriptor) { 12361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten for (index = 0 ; NULL != cd->mDescriptor; ++cd) 124a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten if (cd->mCodecID == codecId) 12561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ++index; 12661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten *pIndex = index; 12761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_SUCCESS; 12861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 12961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten index = *pIndex; 13061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten for ( ; NULL != cd->mDescriptor; ++cd) { 131a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten if (cd->mCodecID == codecId) { 13261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (0 == index) { 13361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten *pDescriptor = *cd->mDescriptor; 1347a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#if 0 // Temporary workaround for Khronos bug 6331 135a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten if (0 < pDescriptor->numSampleRatesSupported) { 1367a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // The malloc is not in the 1.0.1 specification 137a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten SLmilliHertz *temp = (SLmilliHertz *) malloc(sizeof(SLmilliHertz) * 138a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDescriptor->numSampleRatesSupported); 139a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten assert(NULL != temp); 140a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten memcpy(temp, pDescriptor->pSampleRatesSupported, sizeof(SLmilliHertz) * 141a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDescriptor->numSampleRatesSupported); 142a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDescriptor->pSampleRatesSupported = temp; 143a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } else { 144a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDescriptor->pSampleRatesSupported = NULL; 145a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } 146a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten#endif 14761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_SUCCESS; 14861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 14961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten --index; 15061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 15161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 15261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 153bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 1542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten 155e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten 156e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check a data locator and make local deep copy */ 1570b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 158daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult checkDataLocator(void *pLocator, DataLocator *pDataLocator) 159daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 160daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pLocator) { 161a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDataLocator->mLocatorType = SL_DATALOCATOR_NULL; 162daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 163daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 164daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 locatorType = *(SLuint32 *)pLocator; 165daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (locatorType) { 166daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_ADDRESS: 167daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator; 168daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 < pDataLocator->mAddress.length && NULL == pDataLocator->mAddress.pAddress) 169daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 170daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 171daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 172daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator; 1734b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // number of buffers must be specified, there is no default value, and must not be excessive 1744b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (!((1 <= pDataLocator->mBufferQueue.numBuffers) && 1754b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten (pDataLocator->mBufferQueue.numBuffers <= 255))) { 1764b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten SL_LOGE("numBuffers=%u", (unsigned) pDataLocator->mBufferQueue.numBuffers); 177daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 1784b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 179daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 180daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_IODEVICE: 181daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 182daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator; 183daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 deviceType = pDataLocator->mIODevice.deviceType; 184daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL != pDataLocator->mIODevice.device) { 185daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (IObjectToObjectID((IObject *) pDataLocator->mIODevice.device)) { 186daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_OBJECTID_LEDDEVICE: 187daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_LEDARRAY != deviceType) 188daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 189daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 190daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_OBJECTID_VIBRADEVICE: 191daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_VIBRA != deviceType) 192daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 193daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 194daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 195daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 196daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 197daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mIODevice.deviceID = 0; 198daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } else { 199daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataLocator->mIODevice.deviceID) { 200daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DEFAULTDEVICEID_LED: 201daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_LEDARRAY != deviceType) 202daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 203daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 204daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DEFAULTDEVICEID_VIBRA: 205daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_VIBRA != deviceType) 206daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 207daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 208daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DEFAULTDEVICEID_AUDIOINPUT: 209daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_AUDIOINPUT != deviceType) 210daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 211daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 212daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 213daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 214daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 215daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 216daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 217daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 218daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 219daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator; 220daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 == pDataLocator->mMIDIBufferQueue.tpqn) 221daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue.tpqn = 192; 2224b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // number of buffers must be specified, there is no default value, and must not be excessive 2234b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) && 2244b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) 2254b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 226daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 227daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 2283d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten { 229daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator; 2303d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten if (NULL == pDataLocator->mOutputMix.outputMix) { 2313d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten SL_LOGE("locatorType is SL_DATALOCATOR_OUTPUTMIX, but outputMix field is NULL"); 2323d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 2333d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten } 2343d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten IObject *outputMixObject = (IObject *) pDataLocator->mOutputMix.outputMix; 2353d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten if (SL_OBJECTID_OUTPUTMIX != IObjectToObjectID(outputMixObject)) { 2363d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten SL_LOGE("locatorType is SL_DATALOCATOR_OUTPUTMIX, but outputMix field does not refer " \ 2373d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten "to an SL_OBJECTID_OUTPUTMIX"); 238daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 2393d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten } 2403d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten if (outputMixObject->mState != SL_OBJECT_STATE_REALIZED) { 2413d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten SL_LOGE("locatorType is SL_DATALOCATOR_OUTPUTMIX, but outputMix field refers to an " \ 2423d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten "unrealized SL_OBJECTID_OUTPUTMIX"); 2433d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten return SL_RESULT_PRECONDITIONS_VIOLATED; 2443d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten } 2453d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten // FIXME race condition as output mix could disappear, should atomically establish a link 2463d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten } 247daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 248daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 249daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 250daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mURI = *(SLDataLocator_URI *)pLocator; 251daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataLocator->mURI.URI) 252daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 253daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten size_t len = strlen((const char *) pDataLocator->mURI.URI); 254daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLchar *myURI = (SLchar *) malloc(len + 1); 255daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == myURI) 256daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_MEMORY_FAILURE; 257daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten memcpy(myURI, pDataLocator->mURI.URI, len + 1); 258daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // Verify that another thread didn't change the NUL-terminator after we used it 259daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // to determine length of string to copy. It's OK if the string became shorter. 260daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if ('\0' != myURI[len]) { 261daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(myURI); 262daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 263daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 264daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mURI.URI = myURI; 265daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 266daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 267989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi#ifdef ANDROID 268989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi case SL_DATALOCATOR_ANDROIDFD: 269989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi { 270989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator; 2710b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGV("Data locator FD: fd=%ld offset=%lld length=%lld", pDataLocator->mFD.fd, 272989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi pDataLocator->mFD.offset, pDataLocator->mFD.length); 273989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi if (-1 == pDataLocator->mFD.fd) { 274989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi return SL_RESULT_PARAMETER_INVALID; 275989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi } 276989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi } 277989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi break; 278989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi#endif 279daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 280daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 281daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 282daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // Verify that another thread didn't change the locatorType field after we used it 283daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // to determine sizeof struct to copy. 284989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi if (locatorType != pDataLocator->mLocatorType) { 285daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 286989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi } 287daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 288daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 289daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 2900b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 291e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Free the local deep copy of a data locator */ 2920b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 293daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic void freeDataLocator(DataLocator *pDataLocator) 294daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 295daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataLocator->mLocatorType) { 296daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 297daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(pDataLocator->mURI.URI); 29800d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten pDataLocator->mURI.URI = NULL; 299daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 300daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 301daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 302daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 303daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 304daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 3050b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 306e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check a data format and make local deep copy */ 3070b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 308daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult checkDataFormat(void *pFormat, DataFormat *pDataFormat) 309daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 3100b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SLresult result = SL_RESULT_SUCCESS; 3110b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 312daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pFormat) { 313a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDataFormat->mFormatType = SL_DATAFORMAT_NULL; 3140b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } else { 3150b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SLuint32 formatType = *(SLuint32 *)pFormat; 3160b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (formatType) { 3170b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 3180b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_DATAFORMAT_PCM: 3190b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat; 3200b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten do { 3210b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 3220b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the channel count 3230b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.numChannels) { 3240b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 1: // mono 3250b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 2: // stereo 3260b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3270b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 0: // unknown 3280b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 3290b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3300b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: // multi-channel 3310b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 3320b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3330b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 3340b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 3350b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("numChannels=%u", (unsigned) pDataFormat->mPCM.numChannels); 3360b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3370b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 3380b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 3390b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the sampling rate 3400b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.samplesPerSec) { 3410b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_8: 3420b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_11_025: 3430b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_12: 3440b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_16: 3450b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_22_05: 3460b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_24: 3470b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_32: 3480b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_44_1: 3490b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_48: 3500b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_64: 3510b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_88_2: 3520b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_96: 3530b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_192: 3540b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3550b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 0: 3560b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 3570b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3580b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: 3590b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 3600b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3610b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 3620b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 3630b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("samplesPerSec=%u", (unsigned) pDataFormat->mPCM.samplesPerSec); 3640b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3650b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 3660b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 3670b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the sample bit depth 3680b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.bitsPerSample) { 3690b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_8: 3700b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_16: 3710b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3720b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_20: 3730b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_24: 3740b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_28: 3750b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_32: 3760b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 3770b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3780b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: 3790b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 3800b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3810b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 3820b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 3830b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("bitsPerSample=%u", (unsigned) pDataFormat->mPCM.bitsPerSample); 3840b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3850b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 3860b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 3870b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the container bit depth 3880b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.containerSize) { 3890b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_8: 3900b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_16: 3910b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) 3920b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 3930b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3940b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: 3950b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 3960b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 3970b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 3980b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 3990b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("containerSize=%u", (unsigned) pDataFormat->mPCM.containerSize); 4000b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4010b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 4020b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4030b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the channel mask 4040b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.channelMask) { 4050b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT: 4060b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (2 != pDataFormat->mPCM.numChannels) 4070b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4080b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4090b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SPEAKER_FRONT_LEFT: 4100b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SPEAKER_FRONT_RIGHT: 4110b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SPEAKER_FRONT_CENTER: 4120b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (1 != pDataFormat->mPCM.numChannels) 4130b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4140b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4150b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 0: 4160b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ? 4170b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER; 4180b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4190b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: 4200b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4210b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4220b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 4230b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 4240b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("channelMask=%u", (unsigned) pDataFormat->mPCM.channelMask); 4250b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4260b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 4270b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4280b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the endianness / byte order 4290b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.endianness) { 4300b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_BYTEORDER_LITTLEENDIAN: 4310b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_BYTEORDER_BIGENDIAN: 4320b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4334b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // native is proposed but not yet in spec 4340b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: 4350b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4360b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4370b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 4380b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 4390b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("endianness=%u", (unsigned) pDataFormat->mPCM.endianness); 4400b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4410b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 4420b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4430b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // here if all checks passed successfully 4440b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4450b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } while(0); 446daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 4470b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4480b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_DATAFORMAT_MIME: 4490b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat; 4500b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (NULL != pDataFormat->mMIME.mimeType) { 4510b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten size_t len = strlen((const char *) pDataFormat->mMIME.mimeType); 4520b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SLchar *myMIME = (SLchar *) malloc(len + 1); 4530b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (NULL == myMIME) { 4540b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 4550b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } else { 4560b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1); 4570b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // make sure MIME string was not modified asynchronously 4580b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if ('\0' != myMIME[len]) { 4590b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten free(myMIME); 4600b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 4610b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 4620b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten pDataFormat->mMIME.mimeType = myMIME; 4630b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 4640b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 465daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 4660b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 467daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 4680b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4690b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("formatType=%u", (unsigned) formatType); 470daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 4710b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 472daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 4730b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4740b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // make sure format type was not modified asynchronously 4750b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS == result && formatType != pDataFormat->mFormatType) 4760b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 4770b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 478daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 4790b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4800b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten return result; 481daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 482daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 4830b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 484e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check interface ID compatibility with respect to a particular data locator format */ 4850b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4863c170255cc71942f310b676d968cf73328aa5d70Jean-Michel TriviSLresult checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat *pDataLocatorFormat, 4873c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 4883c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi const SLboolean *pInterfaceRequired) { 4893c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi // can't request SLSeekItf if data source is a buffer queue 4903c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi if (SL_DATALOCATOR_BUFFERQUEUE == pDataLocatorFormat->mLocator.mLocatorType) { 491a6b2d444f86f7bca8da33cb9904b225220b675a0Glenn Kasten SLuint32 i; 492a6b2d444f86f7bca8da33cb9904b225220b675a0Glenn Kasten for (i = 0; i < numInterfaces; i++) { 4933c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi if (pInterfaceRequired[i] && (SL_IID_SEEK == pInterfaceIds[i])) { 4940b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("can't request SL_IID_SEEK with a buffer queue data source"); 4953c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi return SL_RESULT_FEATURE_UNSUPPORTED; 4963c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 4973c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 4983c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 4993c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi return SL_RESULT_SUCCESS; 5003c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi} 5013c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 5020b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 503e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Free the local deep copy of a data format */ 5040b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 505daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic void freeDataFormat(DataFormat *pDataFormat) 506daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 507daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mFormatType) { 508daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_MIME: 509daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(pDataFormat->mMIME.mimeType); 51000d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten pDataFormat->mMIME.mimeType = NULL; 511daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 512daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 513daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 514daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 515daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 516daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 5170b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 518e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check a data source and make local deep copy */ 5190b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 520daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn KastenSLresult checkDataSource(const SLDataSource *pDataSrc, DataLocatorFormat *pDataLocatorFormat) 521daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 522daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataSrc) 523daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 524daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataSource myDataSrc = *pDataSrc; 525daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLresult result; 526daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataLocator(myDataSrc.pLocator, &pDataLocatorFormat->mLocator); 527daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_RESULT_SUCCESS != result) 528daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 529a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten switch (pDataLocatorFormat->mLocator.mLocatorType) { 530a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_URI: 531a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_ADDRESS: 532a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 533a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 534a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten result = checkDataFormat(myDataSrc.pFormat, &pDataLocatorFormat->mFormat); 535a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten if (SL_RESULT_SUCCESS != result) { 536a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 537a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten return result; 538a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } 539a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten break; 540a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_NULL: 541a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 542a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten default: 543a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // invalid but fall through; the invalid locator will be caught later 5440b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType); 5450b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // keep going 546a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_IODEVICE: 547a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // for these data locator types, ignore the pFormat as it might be uninitialized 548a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 549a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten break; 550daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 551acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 552acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 553daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 554daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 555daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 5560b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 557e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check a data sink and make local deep copy */ 5580b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 559712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel TriviSLresult checkDataSink(const SLDataSink *pDataSink, DataLocatorFormat *pDataLocatorFormat, 560712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi SLuint32 objType) 561daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 562daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataSink) 563daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 564daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataSink myDataSink = *pDataSink; 565daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLresult result; 566daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataLocator(myDataSink.pLocator, &pDataLocatorFormat->mLocator); 567712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 568daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 569712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi } 570a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten switch (pDataLocatorFormat->mLocator.mLocatorType) { 571712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi 572a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_URI: 573a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_ADDRESS: 574a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat); 575a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten if (SL_RESULT_SUCCESS != result) { 576a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 577a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten return result; 578a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } 579a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten break; 580712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi 581a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 582712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi if (SL_OBJECTID_AUDIOPLAYER == objType) { 583712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi return SL_RESULT_PARAMETER_INVALID; 584712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi } else if (SL_OBJECTID_AUDIORECORDER == objType) { 585712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi#ifdef ANDROID 586712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat); 587712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 588712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi return result; 589712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi } 590712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi break; 591712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi#else 592712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType); 593712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi freeDataLocator(&pDataLocatorFormat->mLocator); 594712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi return SL_RESULT_PARAMETER_INVALID; 595712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi#endif 596712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi } 597712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi break; 598712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi 599712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi case SL_DATALOCATOR_NULL: 600a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 601a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten default: 602a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // invalid but fall through; the invalid locator will be caught later 6030b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType); 6040b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // keep going 605a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_IODEVICE: 606a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 607a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // for these data locator types, ignore the pFormat as it might be uninitialized 608a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 609a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten break; 610daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 611acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 612acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 613daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 614daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 615daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 6160b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 617e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Free the local deep copy of a data locator format */ 6180b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 619daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenvoid freeDataLocatorFormat(DataLocatorFormat *dlf) 620daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 621daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataLocator(&dlf->mLocator); 622daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataFormat(&dlf->mFormat); 623daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 624daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 6250b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 62661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/* Interface initialization hooks */ 6272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten 628a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenextern void 629a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DCommit_init(void *), 630a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DDoppler_init(void *), 631a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DGrouping_init(void *), 632a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_init(void *), 633a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DMacroscopic_init(void *), 634a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DSource_init(void *), 63561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioDecoderCapabilities_init(void *), 63661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioEncoderCapabilities_init(void *), 63761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioEncoder_init(void *), 63861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioIODeviceCapabilities_init(void *), 639a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IBassBoost_init(void *), 6400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IBufferQueue_init(void *), 64161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDeviceVolume_init(void *), 64261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicInterfaceManagement_init(void *), 64361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicSource_init(void *), 64461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_init(void *), 6450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngineCapabilities_init(void *), 6460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_init(void *), 647a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEnvironmentalReverb_init(void *), 648a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEqualizer_init(void *), 64961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ILEDArray_init(void *), 6500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMessage_init(void *), 6510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMuteSolo_init(void *), 6520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITempo_init(void *), 6530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITime_init(void *), 65461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataExtraction_init(void *), 65561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataTraversal_init(void *), 65661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMuteSolo_init(void *), 65761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_init(void *), 6580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IOutputMix_init(void *), 65961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPitch_init(void *), 6600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_init(void *), 66161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPlaybackRate_init(void *), 66261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPrefetchStatus_init(void *), 663a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IPresetReverb_init(void *), 66461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRatePitch_init(void *), 66561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRecord_init(void *), 6660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten ISeek_init(void *), 66761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IThreadSync_init(void *), 66861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IVibra_init(void *), 669a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IVirtualizer_init(void *), 6700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IVisualization_init(void *), 6710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IVolume_init(void *); 67205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#ifdef ANDROID 67367bdf8a2fbd1024ab50c4513e1504325475368e0Jean-Michel Triviextern void IAndroidStreamType_init(void *); 67467bdf8a2fbd1024ab50c4513e1504325475368e0Jean-Michel Triviextern void IAndroidAudioEffect_init(void *); 67505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#endif 676a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 677b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#ifdef USE_OUTPUTMIXEXT 678b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kastenextern void 679b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten IOutputMixExt_init(void *); 680b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#endif 6814597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kastenextern void 6824597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten IObject_deinit(void *); 683b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 684e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten 68561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/*static*/ const struct MPH_init MPH_init_table[MPH_MAX] = { 686510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DCOMMIT, */ I3DCommit_init, NULL, NULL }, 687510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DDOPPLER, */ I3DDoppler_init, NULL, NULL }, 688510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DGROUPING, */ I3DGrouping_init, NULL, NULL }, 689510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DLOCATION, */ I3DLocation_init, NULL, NULL }, 690510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DMACROSCOPIC, */ I3DMacroscopic_init, NULL, NULL }, 691510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_3DSOURCE, */ I3DSource_init, NULL, NULL }, 692510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_AUDIODECODERCAPABILITIES, */ IAudioDecoderCapabilities_init, NULL, NULL }, 693510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_AUDIOENCODER, */ IAudioEncoder_init, NULL, NULL }, 694510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_AUDIOENCODERCAPABILITIES, */ IAudioEncoderCapabilities_init, NULL, NULL }, 695510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_AUDIOIODEVICECAPABILITIES, */ IAudioIODeviceCapabilities_init, NULL, NULL }, 696510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_BASSBOOST, */ IBassBoost_init, NULL, NULL }, 697510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_BUFFERQUEUE, */ IBufferQueue_init, NULL, NULL }, 698510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_DEVICEVOLUME, */ IDeviceVolume_init, NULL, NULL }, 699510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ IDynamicInterfaceManagement_init, NULL, NULL }, 700510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_DYNAMICSOURCE, */ IDynamicSource_init, NULL, NULL }, 701510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_EFFECTSEND, */ IEffectSend_init, NULL, NULL }, 702510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_ENGINE, */ IEngine_init, NULL, NULL }, 703510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_ENGINECAPABILITIES, */ IEngineCapabilities_init, NULL, NULL }, 704510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_ENVIRONMENTALREVERB, */ IEnvironmentalReverb_init, NULL, NULL }, 705510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_EQUALIZER, */ IEqualizer_init, NULL, NULL }, 706510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_LED, */ ILEDArray_init, NULL, NULL }, 707510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_METADATAEXTRACTION, */ IMetadataExtraction_init, NULL, NULL }, 708510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_METADATATRAVERSAL, */ IMetadataTraversal_init, NULL, NULL }, 709510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MIDIMESSAGE, */ IMIDIMessage_init, NULL, NULL }, 710510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MIDITIME, */ IMIDITime_init, NULL, NULL }, 711510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MIDITEMPO, */ IMIDITempo_init, NULL, NULL }, 712510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MIDIMUTESOLO, */ IMIDIMuteSolo_init, NULL, NULL }, 713510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_MUTESOLO, */ IMuteSolo_init, NULL, NULL }, 714510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_NULL, */ NULL, NULL, NULL }, 7154597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten { /* MPH_OBJECT, */ IObject_init, NULL, IObject_deinit }, 716510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_OUTPUTMIX, */ IOutputMix_init, NULL, NULL }, 717510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PITCH, */ IPitch_init, NULL, NULL }, 718510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PLAY, */ IPlay_init, NULL, NULL }, 719510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PLAYBACKRATE, */ IPlaybackRate_init, NULL, NULL }, 720510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL }, 721510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_PRESETREVERB, */ IPresetReverb_init, NULL, NULL }, 722510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_RATEPITCH, */ IRatePitch_init, NULL, NULL }, 723510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_RECORD, */ IRecord_init, NULL, NULL }, 724510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_SEEK, */ ISeek_init, NULL, NULL }, 725510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_THREADSYNC, */ IThreadSync_init, NULL, NULL }, 726510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_VIBRA, */ IVibra_init, NULL, NULL }, 727510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_VIRTUALIZER, */ IVirtualizer_init, NULL, NULL }, 728510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_VISUALIZATION, */ IVisualization_init, NULL, NULL }, 729510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { /* MPH_VOLUME, */ IVolume_init, NULL, NULL }, 730bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT 731a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten { /* MPH_OUTPUTMIXEXT, */ IOutputMixExt_init, NULL, NULL }, 732bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else 733a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten { /* MPH_OUTPUTMIXEXT, */ NULL, NULL, NULL }, 734bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif 73505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#ifdef ANDROID 73667bdf8a2fbd1024ab50c4513e1504325475368e0Jean-Michel Trivi { /* MPH_ANDROIDSTREAMTYPE */ IAndroidStreamType_init, NULL, NULL }, 73767bdf8a2fbd1024ab50c4513e1504325475368e0Jean-Michel Trivi { /* MPH_ANDROIDAUDIOEFFECT */ IAndroidAudioEffect_init, NULL, NULL } 738a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten#else 73967bdf8a2fbd1024ab50c4513e1504325475368e0Jean-Michel Trivi { /* MPH_ANDROIDSTREAMTYPE */ NULL, NULL, NULL }, 74067bdf8a2fbd1024ab50c4513e1504325475368e0Jean-Michel Trivi { /* MPH_ANDROIDAUDIOEFFECT */ NULL, NULL, NULL } 74105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#endif 742bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}; 743bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 7440b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 745e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Construct a new instance of the specified class, exposing selected interfaces */ 746bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 747ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn KastenIObject *construct(const ClassTable *class__, unsigned exposedMask, SLEngineItf engine) 748bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 74972a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten IObject *this; 75072a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten this = (IObject *) calloc(1, class__->mSize); 751bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL != this) { 75272a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten unsigned lossOfControlMask = 0; 753ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // a NULL engine means we are constructing the engine 75472a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten IEngine *thisEngine = (IEngine *) engine; 755d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (NULL == thisEngine) { 75672a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten thisEngine = &((CEngine *) this)->mEngine; 757d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten } else { 758ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_lock_exclusive(thisEngine); 759d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (MAX_INSTANCE <= thisEngine->mInstanceCount) { 760ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // too many objects 761ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 762d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten free(this); 763ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten return NULL; 764ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 765d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // pre-allocate a pending slot, but don't assign bit from mInstanceMask yet 766ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten ++thisEngine->mInstanceCount; 767d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(((unsigned) ~0) != thisEngine->mInstanceMask); 768ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 769ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // const, no lock needed 770ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten if (thisEngine->mLossOfControlGlobal) 771ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten lossOfControlMask = ~0; 772ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 77372a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten this->mLossOfControlMask = lossOfControlMask; 774ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mClass = class__; 775ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mEngine = thisEngine; 776bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct iid_vtable *x = class__->mInterfaces; 777510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint8 *interfaceStateP = this->mInterfaceStates; 778510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint32 index; 779510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten for (index = 0; index < class__->mInterfaceCount; ++index, ++x, exposedMask >>= 1) { 780276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten SLuint8 state; 781bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (exposedMask & 1) { 78283f93b0afd3607b1570d8473c2f6e45276c133baGlenn Kasten void *self = (char *) this + x->mOffset; 783d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // IObject does not have an mThis, so [1] is not always defined 784d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (index) 785d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten ((IObject **) self)[1] = this; 78683f93b0afd3607b1570d8473c2f6e45276c133baGlenn Kasten VoidHook init = MPH_init_table[x->mMPH].mInit; 787bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL != init) 788bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten (*init)(self); 789e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten // IObject does not require a call to GetInterface 790e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten if (index) 791e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten ((size_t *) self)[0] ^= ~0; 792510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = INTERFACE_EXPOSED; 793510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } else 794510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = INTERFACE_UNINITIALIZED; 795510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten *interfaceStateP++ = state; 796bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 797ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // only expose new object to sync thread after it is fully initialized 798ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_lock_exclusive(thisEngine); 799d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten unsigned availMask = ~thisEngine->mInstanceMask; 800d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(availMask); 801d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten unsigned i = ctz(availMask); 802d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(MAX_INSTANCE > i); 803d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(NULL == thisEngine->mInstances[i]); 804d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten thisEngine->mInstances[i] = this; 805d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten thisEngine->mInstanceMask |= 1 << i; 806d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // avoid zero as a valid instance ID 807d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten this->mInstanceID = i + 1; 80800d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#ifdef USE_SDL 80900d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten SLboolean unpause = SL_BOOLEAN_FALSE; 81000d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten if (SL_OBJECTID_OUTPUTMIX == class__->mObjectID && NULL == thisEngine->mOutputMix) { 81100d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten thisEngine->mOutputMix = (COutputMix *) this; 81200d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten unpause = SL_BOOLEAN_TRUE; 81300d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten } 81400d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#endif 815ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 81600d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#ifdef USE_SDL 81700d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten if (unpause) 81800d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten SDL_PauseAudio(0); 81900d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#endif 820bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 821bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return this; 822bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 823bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 824ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 825ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten/* Initial global entry points */ 826d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 8270b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 828e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief slCreateEngine Function */ 8290b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 8300b167267bda99b68346045ccab14e810121d5de4Glenn KastenSLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions, 8310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLEngineOption *pEngineOptions, SLuint32 numInterfaces, 8320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 833d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 834ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_GLOBAL 835ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 836ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten do { 837ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 838ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi#ifdef ANDROID 839ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten android::ProcessState::self()->startThreadPool(); 84014e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT 841ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten android::DataSource::RegisterDefaultSniffers(); 8426fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi#endif 84314e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif 844ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 845ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pEngine) { 846ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 847ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 848ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 849ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pEngine = NULL; 850ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 851ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if ((0 < numOptions) && (NULL == pEngineOptions)) { 852ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 853ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 854ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 855ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 856ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // default values 857ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLboolean threadSafe = SL_BOOLEAN_TRUE; 858ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLboolean lossOfControlGlobal = SL_BOOLEAN_FALSE; 859ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 860ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // process engine options 8610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 i; 8620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLEngineOption *option = pEngineOptions; 863ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 8640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten for (i = 0; i < numOptions; ++i, ++option) { 8650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (option->feature) { 8660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_ENGINEOPTION_THREADSAFE: 8674b2f97bb1df6b3a65d2c3a158fba3a604c8f543cGlenn Kasten threadSafe = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize 8680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 8690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_ENGINEOPTION_LOSSOFCONTROL: 8704b2f97bb1df6b3a65d2c3a158fba3a604c8f543cGlenn Kasten lossOfControlGlobal = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize 8710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 8720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 873ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 874ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 8750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 8760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 877ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS != result) 878ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 879ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 880ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 881ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE); 882ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = checkInterfaces(pCEngine_class, numInterfaces, 883ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 884ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS != result) 885ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 886ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 887ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten CEngine *this = (CEngine *) construct(pCEngine_class, exposedMask, NULL); 888ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == this) { 889ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 890ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 891ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 892ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 893ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0; 894ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mEngine.mLossOfControlGlobal = lossOfControlGlobal; 895ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mEngineCapabilities.mThreadSafe = threadSafe; 896ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pEngine = &this->mObject.mItf; 897ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 898ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } while(0); 899ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 900ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_GLOBAL 901d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 902d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 903ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 904e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief slQueryNumSupportedEngineInterfaces Function */ 9050b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 906ed46c29d6a09112dbbf584c82953f63289596fd6Glenn KastenSLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(SLuint32 *pNumSupportedInterfaces) 907d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 908ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_GLOBAL 909ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 910ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pNumSupportedInterfaces) { 911ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 912ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 9137a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE); 9147a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten assert(NULL != class__); 9157a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten SLuint32 count = 0; 9167a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten SLuint32 i; 917c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten for (i = 0; i < class__->mInterfaceCount; ++i) { 918c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten switch (class__->mInterfaces[i].mInterface) { 919c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_IMPLICIT: 920c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_EXPLICIT: 921c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_DYNAMIC: 9227a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten ++count; 923c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 924c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_UNAVAILABLE: 925c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 926c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten default: 927c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten assert(false); 928c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 929c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten } 930c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten } 9317a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten *pNumSupportedInterfaces = count; 932ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 933ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 934ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 935ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_GLOBAL 936d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 937d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 938ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 939e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief slQuerySupportedEngineInterfaces Function */ 9400b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 941ed46c29d6a09112dbbf584c82953f63289596fd6Glenn KastenSLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId) 942d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 943ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_GLOBAL 944ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 945ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pInterfaceId) { 946ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 947ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 9487a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten *pInterfaceId = NULL; 9497a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE); 9507a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten assert(NULL != class__); 9517a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; // will be reset later 9527a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten SLuint32 i; 9537a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten for (i = 0; i < class__->mInterfaceCount; ++i) { 954c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten switch (class__->mInterfaces[i].mInterface) { 955c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_IMPLICIT: 956c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_EXPLICIT: 957c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_DYNAMIC: 958c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 959c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_UNAVAILABLE: 9607a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten continue; 961c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten default: 962c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten assert(false); 963c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 964c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten } 9657a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten if (index == 0) { 9667a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten *pInterfaceId = &SL_IID_array[class__->mInterfaces[i].mMPH]; 9677a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_SUCCESS; 9687a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten break; 9697a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten } 9707a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten --index; 971ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 972ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 973ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 974ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_GLOBAL 975d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 976d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 977ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 978d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* End */ 979