sles.cpp revision 28bc6b725c207fb8fbd618caea4aa127f35ce1e1
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; 37928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (0 > (index = class__->mMPH_to_index[MPH])) { 38e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten return false; 39928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 40e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten assert(MAX_INDEX >= class__->mInterfaceCount); 41e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten assert(class__->mInterfaceCount > (unsigned) index); 42e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten switch (this->mInterfaceStates[index]) { 43e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten case INTERFACE_EXPOSED: 44e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten case INTERFACE_ADDED: 45e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten return true; 46e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten default: 47e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten return false; 48e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten } 49e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten} 50e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten 51e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten 52e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Map an IObject to it's "object ID" (which is really a class ID) */ 53b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 54b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn KastenSLuint32 IObjectToObjectID(IObject *this) 55b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 56b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(NULL != this); 57b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return this->mClass->mObjectID; 58b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 59b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 600b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 61928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Acquire a strong reference to an object. 62928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Check that object has the specified "object ID" (which is really a class ID) and is in the 63928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * realized state. If so, then acquire a strong reference to it and return true. 64928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Otherwise return false. 65928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */ 66928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 67928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn KastenSLresult AcquireStrongRef(IObject *object, SLuint32 expectedObjectID) 68928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten{ 69928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL == object) { 70928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 71928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 72928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // NTH additional validity checks on address here 73928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SLresult result; 74928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten object_lock_exclusive(object); 75928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SLuint32 actualObjectID = IObjectToObjectID(object); 76928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (expectedObjectID != actualObjectID) { 77928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("object %p has object ID %lu but expected %lu", object, actualObjectID, 78928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten expectedObjectID); 79928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 80928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } else if (SL_OBJECT_STATE_REALIZED != object->mState) { 81928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("object %p with object ID %lu is not realized", object, actualObjectID); 82928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 83928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } else { 84928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten ++object->mStrongRefCount; 85928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten result = SL_RESULT_SUCCESS; 86928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 87928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten object_unlock_exclusive(object); 88928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten return result; 89928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten} 90928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 91928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 92928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Release a strong reference to an object. 93928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Entry condition: the object is locked. 94928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Exit condition: the object is unlocked. 95928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Finishes the destroy if needed. 96928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */ 97928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 98928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kastenvoid ReleaseStrongRefAndUnlockExclusive(IObject *object) 99928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten{ 100a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#ifdef USE_DEBUG 101928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten assert(pthread_equal(pthread_self(), object->mOwner)); 102a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 103928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten assert(0 < object->mStrongRefCount); 104928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if ((0 == --object->mStrongRefCount) && (SL_OBJECT_STATE_DESTROYING == object->mState)) { 105928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // FIXME do the destroy here - merge with IDestroy 106928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // but can't do this until we move Destroy to the sync thread 107928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // as Destroy is now a blocking operation, and to avoid a race 108928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } else { 109928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten object_unlock_exclusive(object); 110928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 111928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten} 112928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 113928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 114928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Release a strong reference to an object. 115928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Entry condition: the object is unlocked. 116928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Exit condition: the object is unlocked. 117928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Finishes the destroy if needed. 118928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */ 119928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 120928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kastenvoid ReleaseStrongRef(IObject *object) 121928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten{ 122928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten assert(NULL != object); 123928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten object_lock_exclusive(object); 124928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten ReleaseStrongRefAndUnlockExclusive(object); 125928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten} 126928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 127928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 128e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Convert POSIX pthread error code to OpenSL ES result code */ 129d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 130d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn KastenSLresult err_to_result(int err) 131d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten{ 132f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (EAGAIN == err || ENOMEM == err) { 133d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_RESOURCE_ERROR; 134f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 135f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (0 != err) { 136d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_INTERNAL_ERROR; 137f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 138d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_SUCCESS; 139d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} 140d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 1410b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 142e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check the interface IDs passed into a Create operation */ 14329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten 144ed46c29d6a09112dbbf584c82953f63289596fd6Glenn KastenSLresult checkInterfaces(const ClassTable *class__, SLuint32 numInterfaces, 145ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired, unsigned *pExposedMask) 146bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 147bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten assert(NULL != class__ && NULL != pExposedMask); 14801e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Initially no interfaces are exposed 149bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten unsigned exposedMask = 0; 150bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct iid_vtable *interfaces = class__->mInterfaces; 151bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 interfaceCount = class__->mInterfaceCount; 152bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 i; 15301e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Expose all implicit interfaces 154bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten for (i = 0; i < interfaceCount; ++i) { 155bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten switch (interfaces[i].mInterface) { 156bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten case INTERFACE_IMPLICIT: 157104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten case INTERFACE_IMPLICIT_PREREALIZE: 158a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten // there must be an initialization hook present 159a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten if (NULL != MPH_init_table[interfaces[i].mMPH].mInit) { 160a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten exposedMask |= 1 << i; 161a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten } 162bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 1635e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_EXPLICIT: 1645e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_DYNAMIC: 1655e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_UNAVAILABLE: 1665e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_EXPLICIT_PREREALIZE: 1675e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten break; 168bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten default: 1695e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten assert(false); 170bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 171bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 172bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 173d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten if (0 < numInterfaces) { 174f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (NULL == pInterfaceIds || NULL == pInterfaceRequired) { 175d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 176f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 177104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten bool anyRequiredButUnsupported = false; 17801e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Loop for each requested interface 179d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten for (i = 0; i < numInterfaces; ++i) { 180bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLInterfaceID iid = pInterfaceIds[i]; 181f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (NULL == iid) { 182bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 183f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 18429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten int MPH, index; 18529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten if ((0 > (MPH = IID_to_MPH(iid))) || 186a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten // there must be an initialization hook present 187a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten (NULL == MPH_init_table[MPH].mInit) || 188104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten (0 > (index = class__->mMPH_to_index[MPH])) || 189104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten (INTERFACE_UNAVAILABLE == interfaces[index].mInterface)) { 19001e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Here if interface was not found, or is not available for this object type 191f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (pInterfaceRequired[i]) { 19201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Application said it required the interface, so give up 19301e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten SL_LOGE("class %s interface %lu required but unavailable MPH=%d", 19401e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten class__->mName, i, MPH); 195104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten anyRequiredButUnsupported = true; 196f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 197a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // Application said it didn't really need the interface, so ignore with warning 198a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten SL_LOGW("class %s interface %lu requested but unavailable MPH=%d", 199a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten class__->mName, i, MPH); 200bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten continue; 201bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 20201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // The requested interface was both found and available, so expose it 20329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten exposedMask |= (1 << index); 20401e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Note that we ignore duplicate requests, including equal and aliased IDs 205d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 206104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten if (anyRequiredButUnsupported) { 207104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 208104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten } 209d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 210bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten *pExposedMask = exposedMask; 211d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 212d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 213d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 2140b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 215e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Helper shared by decoder and encoder */ 2160b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 217a438eb1cf1ae602afab00336528dd230bd929206Glenn KastenSLresult GetCodecCapabilities(SLuint32 codecId, SLuint32 *pIndex, 218369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten SLAudioCodecDescriptor *pDescriptor, const CodecDescriptor *codecDescriptors) 219bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 220f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (NULL == pIndex) { 22161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 222f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 223369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten const CodecDescriptor *cd = codecDescriptors; 22461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten SLuint32 index; 22561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (NULL == pDescriptor) { 226f51dba65751107c930759938775b75531ec1f330Glenn Kasten for (index = 0 ; NULL != cd->mDescriptor; ++cd) { 227f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (cd->mCodecID == codecId) { 22861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ++index; 229f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 230f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 23161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten *pIndex = index; 23261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_SUCCESS; 23361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 23461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten index = *pIndex; 23561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten for ( ; NULL != cd->mDescriptor; ++cd) { 236a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten if (cd->mCodecID == codecId) { 23761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (0 == index) { 23861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten *pDescriptor = *cd->mDescriptor; 2397a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#if 0 // Temporary workaround for Khronos bug 6331 240a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten if (0 < pDescriptor->numSampleRatesSupported) { 2417a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // The malloc is not in the 1.0.1 specification 242a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten SLmilliHertz *temp = (SLmilliHertz *) malloc(sizeof(SLmilliHertz) * 243a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDescriptor->numSampleRatesSupported); 244a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten assert(NULL != temp); 245a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten memcpy(temp, pDescriptor->pSampleRatesSupported, sizeof(SLmilliHertz) * 246a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDescriptor->numSampleRatesSupported); 247a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDescriptor->pSampleRatesSupported = temp; 248a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } else { 249a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDescriptor->pSampleRatesSupported = NULL; 250a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } 251a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten#endif 25261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_SUCCESS; 25361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 25461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten --index; 25561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 25661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 25761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 258bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 2592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten 260e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten 261e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check a data locator and make local deep copy */ 2620b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 263daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult checkDataLocator(void *pLocator, DataLocator *pDataLocator) 264daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 265daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pLocator) { 266a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDataLocator->mLocatorType = SL_DATALOCATOR_NULL; 267daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 268daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 269928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SLresult result; 270daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 locatorType = *(SLuint32 *)pLocator; 271daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (locatorType) { 272928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 273daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_ADDRESS: 274daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator; 275928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // if length is greater than zero, then the address must be non-NULL 276f51dba65751107c930759938775b75531ec1f330Glenn Kasten if ((0 < pDataLocator->mAddress.length) && (NULL == pDataLocator->mAddress.pAddress)) { 277928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("pAddress is NULL"); 278daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 279928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 280daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 281928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 282daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 28301e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten#ifdef ANDROID 28401e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // This is an alias that is _not_ converted; the rest of the code must check for both locator 28501e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // types. That's because it is only an alias for audio players, not audio recorder objects 28601e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // so we have to remember the distinction. 28701e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 28801e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten#endif 289daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator; 2904b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // number of buffers must be specified, there is no default value, and must not be excessive 2914b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (!((1 <= pDataLocator->mBufferQueue.numBuffers) && 2924b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten (pDataLocator->mBufferQueue.numBuffers <= 255))) { 2934b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten SL_LOGE("numBuffers=%u", (unsigned) pDataLocator->mBufferQueue.numBuffers); 294daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 2954b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 296daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 297928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 298daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_IODEVICE: 299daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 300daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator; 301daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 deviceType = pDataLocator->mIODevice.deviceType; 302928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SLObjectItf device = pDataLocator->mIODevice.device; 303928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL != device) { 304928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mIODevice.deviceID = 0; 305928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SLuint32 expectedObjectID; 306928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten switch (deviceType) { 307928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten case SL_IODEVICE_LEDARRAY: 308928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten expectedObjectID = SL_OBJECTID_LEDDEVICE; 309daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 310928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten case SL_IODEVICE_VIBRA: 311928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten expectedObjectID = SL_OBJECTID_VIBRADEVICE; 312daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 313928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // audio input and audio output cannot be specified via objects 314928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten case SL_IODEVICE_AUDIOINPUT: 315928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // worse yet, an SL_IODEVICE enum constant for audio output does not exist yet 316928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // case SL_IODEVICE_AUDIOOUTPUT: 317daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 318928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("invalid deviceType %lu", deviceType); 319928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mIODevice.device = NULL; 320daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 321daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 322928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // check that device has the correct object ID and is realized, 323928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // and acquire a strong reference to it 324928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten result = AcquireStrongRef((IObject *) device, expectedObjectID); 325928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 326928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("locator type is IODEVICE, but device field %p has wrong object ID or is " \ 327928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten "not realized", device); 328928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mIODevice.device = NULL; 329928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten return result; 330928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 331daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } else { 332928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SLuint32 deviceID = pDataLocator->mIODevice.deviceID; 333928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten switch (deviceType) { 334928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten case SL_IODEVICE_LEDARRAY: 335928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_DEFAULTDEVICEID_LED != deviceID) { 336928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("invalid LED deviceID %lu", deviceID); 337daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 338928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 339daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 340928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten case SL_IODEVICE_VIBRA: 341928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_DEFAULTDEVICEID_VIBRA != deviceID) { 342928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("invalid vibra deviceID %lu", deviceID); 343daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 344928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 345daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 346928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten case SL_IODEVICE_AUDIOINPUT: 347928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_DEFAULTDEVICEID_AUDIOINPUT != deviceID) { 348928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("invalid audio input deviceID %lu", deviceID); 349daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 350928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 351daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 352daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 353928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("invalid deviceType %lu", deviceType); 354daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 355daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 356daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 357daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 358daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 359928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 360daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 361daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator; 362f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (0 == pDataLocator->mMIDIBufferQueue.tpqn) { 363daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue.tpqn = 192; 364f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 3654b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // number of buffers must be specified, there is no default value, and must not be excessive 3664b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) && 367928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) { 368928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("invalid MIDI buffer queue"); 3694b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 370928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 371daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 372928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 373daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 374daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator; 375928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // check that output mix object has the correct object ID and is realized, 376928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // and acquire a strong reference to it 377928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten result = AcquireStrongRef((IObject *) pDataLocator->mOutputMix.outputMix, 378928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_OBJECTID_OUTPUTMIX); 379928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 380928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("locatorType is SL_DATALOCATOR_OUTPUTMIX, but outputMix field %p does not " \ 381a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten "refer to an SL_OBJECTID_OUTPUTMIX or the output mix is not realized", \ 382928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mOutputMix.outputMix); 383928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mOutputMix.outputMix = NULL; 384928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten return result; 3853d86d84fe89faa0efaf09bcbe4b841dfd3c7b5d8Glenn Kasten } 386daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 387928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 388daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 389daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 390daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mURI = *(SLDataLocator_URI *)pLocator; 391928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL == pDataLocator->mURI.URI) { 392928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("invalid URI"); 393daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 394928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 395928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // NTH verify URI address for validity 396daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten size_t len = strlen((const char *) pDataLocator->mURI.URI); 397daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLchar *myURI = (SLchar *) malloc(len + 1); 398928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL == myURI) { 399928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mURI.URI = NULL; 400daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_MEMORY_FAILURE; 401928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 402daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten memcpy(myURI, pDataLocator->mURI.URI, len + 1); 403daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // Verify that another thread didn't change the NUL-terminator after we used it 404daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // to determine length of string to copy. It's OK if the string became shorter. 405daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if ('\0' != myURI[len]) { 406daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(myURI); 407928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mURI.URI = NULL; 408daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 409daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 410daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mURI.URI = myURI; 411daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 412daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 413928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 414989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi#ifdef ANDROID 415989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi case SL_DATALOCATOR_ANDROIDFD: 416989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi { 417989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator; 4180b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGV("Data locator FD: fd=%ld offset=%lld length=%lld", pDataLocator->mFD.fd, 419989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi pDataLocator->mFD.offset, pDataLocator->mFD.length); 420928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // NTH check against process fd limit 421928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (0 > pDataLocator->mFD.fd) { 422989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi return SL_RESULT_PARAMETER_INVALID; 423989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi } 424989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi } 425989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi break; 426989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi#endif 427928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 428daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 429928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("invalid locatorType %lu", locatorType); 430daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 431daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 432928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 433daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // Verify that another thread didn't change the locatorType field after we used it 434daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // to determine sizeof struct to copy. 435989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi if (locatorType != pDataLocator->mLocatorType) { 436daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 437989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi } 438daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 439daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 440daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 4410b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 442e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Free the local deep copy of a data locator */ 4430b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 444daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic void freeDataLocator(DataLocator *pDataLocator) 445daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 446daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataLocator->mLocatorType) { 447daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 448928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL != pDataLocator->mURI.URI) { 449928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten free(pDataLocator->mURI.URI); 450928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mURI.URI = NULL; 451928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 45200d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten pDataLocator->mURI.URI = NULL; 453daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 454928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten case SL_DATALOCATOR_IODEVICE: 455928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL != pDataLocator->mIODevice.device) { 456928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device); 457928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mIODevice.device = NULL; 458928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 459928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten break; 460928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 461928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL != pDataLocator->mOutputMix.outputMix) { 462928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix); 463928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataLocator->mOutputMix.outputMix = NULL; 464928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 465928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten break; 466daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 467daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 468daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 469daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 470daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 4710b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 472e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check a data format and make local deep copy */ 4730b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 474daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult checkDataFormat(void *pFormat, DataFormat *pDataFormat) 475daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 4760b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SLresult result = SL_RESULT_SUCCESS; 4770b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 478daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pFormat) { 479a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDataFormat->mFormatType = SL_DATAFORMAT_NULL; 4800b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } else { 4810b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SLuint32 formatType = *(SLuint32 *)pFormat; 4820b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (formatType) { 4830b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4840b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_DATAFORMAT_PCM: 4850b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat; 4860b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten do { 4870b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 4880b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the channel count 4890b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.numChannels) { 4900b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 1: // mono 4910b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 2: // stereo 4920b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4930b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 0: // unknown 4940b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4950b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4960b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: // multi-channel 4970b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 4980b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 4990b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5000b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 5010b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("numChannels=%u", (unsigned) pDataFormat->mPCM.numChannels); 5020b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5030b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5040b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 5050b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the sampling rate 5060b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.samplesPerSec) { 5070b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_8: 5080b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_11_025: 5090b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_12: 5100b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_16: 5110b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_22_05: 5120b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_24: 5130b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_32: 5140b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_44_1: 5150b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_48: 5160b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_64: 5170b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_88_2: 5180b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_96: 5190b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SAMPLINGRATE_192: 5200b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5210b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 0: 5220b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 5230b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5240b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: 5250b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 5260b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5270b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5280b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 5290b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("samplesPerSec=%u", (unsigned) pDataFormat->mPCM.samplesPerSec); 5300b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5310b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5320b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 5330b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the sample bit depth 5340b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.bitsPerSample) { 5350b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_8: 5360b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_16: 5370b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5380b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_20: 5390b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_24: 5400b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_28: 5410b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_32: 5420b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 5430b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5440b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: 5450b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 5460b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5470b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5480b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 5490b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("bitsPerSample=%u", (unsigned) pDataFormat->mPCM.bitsPerSample); 5500b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5510b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5520b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 5530b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the container bit depth 554dfbd7627912e9598b92e71346e47d91f9d14f44fGlenn Kasten if (pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) { 555dfbd7627912e9598b92e71346e47d91f9d14f44fGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 556dfbd7627912e9598b92e71346e47d91f9d14f44fGlenn Kasten } else if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) { 5570b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 5580b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5590b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 560dfbd7627912e9598b92e71346e47d91f9d14f44fGlenn Kasten SL_LOGE("containerSize=%u, bitsPerSample=%u", 561dfbd7627912e9598b92e71346e47d91f9d14f44fGlenn Kasten (unsigned) pDataFormat->mPCM.containerSize, 562dfbd7627912e9598b92e71346e47d91f9d14f44fGlenn Kasten (unsigned) pDataFormat->mPCM.bitsPerSample); 5630b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5640b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5650b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 5660b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the channel mask 5670b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.channelMask) { 5680b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT: 569f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (2 != pDataFormat->mPCM.numChannels) { 5700b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 571f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 5720b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5730b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SPEAKER_FRONT_LEFT: 5740b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SPEAKER_FRONT_RIGHT: 5750b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_SPEAKER_FRONT_CENTER: 576f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (1 != pDataFormat->mPCM.numChannels) { 5770b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 578f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 5790b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5800b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case 0: 5810b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ? 5820b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER; 5830b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5840b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: 5850b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 5860b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5870b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5880b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 589f51dba65751107c930759938775b75531ec1f330Glenn Kasten SL_LOGE("channelMask=0x%lx numChannels=%lu", pDataFormat->mPCM.channelMask, 590f51dba65751107c930759938775b75531ec1f330Glenn Kasten pDataFormat->mPCM.numChannels); 5910b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5920b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 5930b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 5940b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // check the endianness / byte order 5950b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten switch (pDataFormat->mPCM.endianness) { 5960b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_BYTEORDER_LITTLEENDIAN: 5970b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_BYTEORDER_BIGENDIAN: 5980b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 5994b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // native is proposed but not yet in spec 6000b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten default: 6010b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 6020b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 6030b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 6040b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (SL_RESULT_SUCCESS != result) { 6050b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("endianness=%u", (unsigned) pDataFormat->mPCM.endianness); 6060b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten break; 6070b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 6080b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 6090b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // here if all checks passed successfully 6100b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 6110b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } while(0); 612daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 6130b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 6140b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten case SL_DATAFORMAT_MIME: 6150b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat; 6160b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (NULL != pDataFormat->mMIME.mimeType) { 617928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // NTH check address for validity 6180b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten size_t len = strlen((const char *) pDataFormat->mMIME.mimeType); 6190b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SLchar *myMIME = (SLchar *) malloc(len + 1); 6200b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if (NULL == myMIME) { 6210b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 6220b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } else { 6230b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1); 6240b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // make sure MIME string was not modified asynchronously 6250b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten if ('\0' != myMIME[len]) { 6260b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten free(myMIME); 627928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten myMIME = NULL; 6280b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 6290b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 6300b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 631928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataFormat->mMIME.mimeType = myMIME; 6320b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten } 633daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 6340b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 635daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 6360b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 6370b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("formatType=%u", (unsigned) formatType); 638daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 6390b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 640daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 6410b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 6420b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // make sure format type was not modified asynchronously 643f51dba65751107c930759938775b75531ec1f330Glenn Kasten if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) { 6440b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 645f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 6460b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 647daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 6480b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 6490b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten return result; 650daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 651daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 6520b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 653e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check interface ID compatibility with respect to a particular data locator format */ 6540b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 6553c170255cc71942f310b676d968cf73328aa5d70Jean-Michel TriviSLresult checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat *pDataLocatorFormat, 656104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten const ClassTable *class__, unsigned exposedMask) { 657711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten int index; 65801e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten switch (pDataLocatorFormat->mLocator.mLocatorType) { 65901e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 66001e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten#ifdef ANDROID 66101e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 66201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten#endif 663104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten // can't request SLSeekItf if data source is a buffer queue 664711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten index = class__->mMPH_to_index[MPH_SEEK]; 665104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten if (0 <= index) { 666104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten if (exposedMask & (1 << index)) { 6670b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("can't request SL_IID_SEEK with a buffer queue data source"); 6683c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi return SL_RESULT_FEATURE_UNSUPPORTED; 6693c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 670104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten } 671104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten // can't request SLMuteSoloItf if data source is a mono buffer queue 672104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten index = class__->mMPH_to_index[MPH_MUTESOLO]; 673104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten if (0 <= index) { 674104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten if ((exposedMask & (1 << index)) && 675f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten (SL_DATAFORMAT_PCM == pDataLocatorFormat->mFormat.mFormatType) && 676f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten (1 == pDataLocatorFormat->mFormat.mPCM.numChannels)) { 677f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten SL_LOGE("can't request SL_IID_MUTESOLO with a mono buffer queue data source"); 678f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 679f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten } 6803c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 68101e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten break; 68201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten default: 683711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // can't request SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf 684711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // if the data source is not a buffer queue 685711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten index = class__->mMPH_to_index[MPH_BUFFERQUEUE]; 686711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#ifdef ANDROID 687711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(index == class__->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]); 688711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#endif 689711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (0 <= index) { 690711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (exposedMask & (1 << index)) { 691711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SL_LOGE("can't request SL_IID_BUFFERQUEUE " 692711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#ifdef ANDROID 693711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE " 694711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#endif 695711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten "with a non-buffer queue data source"); 696711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 697711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten } 698711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten } 69901e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten break; 7003c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 7013c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi return SL_RESULT_SUCCESS; 7023c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi} 7033c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 7040b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 705e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Free the local deep copy of a data format */ 7060b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 707daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic void freeDataFormat(DataFormat *pDataFormat) 708daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 709daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mFormatType) { 710daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_MIME: 711928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL != pDataFormat->mMIME.mimeType) { 712928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten free(pDataFormat->mMIME.mimeType); 713928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten pDataFormat->mMIME.mimeType = NULL; 714928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 715daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 716daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 717daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 718daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 719daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 720daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 7210b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 722e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check a data source and make local deep copy */ 7230b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 724daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn KastenSLresult checkDataSource(const SLDataSource *pDataSrc, DataLocatorFormat *pDataLocatorFormat) 725daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 726928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL == pDataSrc) { 727928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("pDataSrc NULL"); 728daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 729928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 730daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataSource myDataSrc = *pDataSrc; 731daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLresult result; 732daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataLocator(myDataSrc.pLocator, &pDataLocatorFormat->mLocator); 733928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 734daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 735928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 736a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten switch (pDataLocatorFormat->mLocator.mLocatorType) { 737928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 738a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_URI: 739a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_ADDRESS: 740a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 741a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 742928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten#ifdef ANDROID 743928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten case SL_DATALOCATOR_ANDROIDFD: 74401e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 745928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten#endif 746a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten result = checkDataFormat(myDataSrc.pFormat, &pDataLocatorFormat->mFormat); 747a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten if (SL_RESULT_SUCCESS != result) { 748a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 749a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten return result; 750a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } 751a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten break; 752928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 753a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_NULL: 754a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 755a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten default: 756a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // invalid but fall through; the invalid locator will be caught later 7570b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType); 7580b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // keep going 759928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 760a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_IODEVICE: 761a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // for these data locator types, ignore the pFormat as it might be uninitialized 762a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 763a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten break; 764daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 765928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 766acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 767acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 768daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 769daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 770daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 7710b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 772e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check a data sink and make local deep copy */ 7730b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 774712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel TriviSLresult checkDataSink(const SLDataSink *pDataSink, DataLocatorFormat *pDataLocatorFormat, 775712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi SLuint32 objType) 776daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 777928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL == pDataSink) { 778928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("pDataSink NULL"); 779daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 780928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 781daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataSink myDataSink = *pDataSink; 782daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLresult result; 783daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataLocator(myDataSink.pLocator, &pDataLocatorFormat->mLocator); 784712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 785daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 786712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi } 787a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten switch (pDataLocatorFormat->mLocator.mLocatorType) { 788712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi 789a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_URI: 790a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_ADDRESS: 791a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat); 792a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten if (SL_RESULT_SUCCESS != result) { 793a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 794a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten return result; 795a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } 796a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten break; 797712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi 798a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 79901e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten#ifdef ANDROID 80001e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 80101e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten#endif 802712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi if (SL_OBJECTID_AUDIOPLAYER == objType) { 803928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("buffer queue can't be used as data sink for audio player"); 80401e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 805712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi } else if (SL_OBJECTID_AUDIORECORDER == objType) { 806712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi#ifdef ANDROID 80701e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten if (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE != 80801e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten pDataLocatorFormat->mLocator.mLocatorType) { 80901e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten SL_LOGE("audio recorder source locator must be SL_DATALOCATOR_ANDROIDBUFFERQUEUE"); 81001e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 81101e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten } else { 81201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat); 813712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi } 814712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi#else 815712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType); 81601e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 817712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi#endif 818712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi } 81901e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten if (SL_RESULT_SUCCESS != result) { 82001e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 82101e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten return result; 82201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten } 823712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi break; 824712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi 825712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi case SL_DATALOCATOR_NULL: 826a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 827a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten default: 828a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // invalid but fall through; the invalid locator will be caught later 8290b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType); 8300b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten // keep going 831928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 832a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_IODEVICE: 833a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 834a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten // for these data locator types, ignore the pFormat as it might be uninitialized 835a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 836a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten break; 837daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 838928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 839acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 840acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 841daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 842daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 843daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 8440b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 845e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Free the local deep copy of a data locator format */ 8460b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 847daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenvoid freeDataLocatorFormat(DataLocatorFormat *dlf) 848daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 849daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataLocator(&dlf->mLocator); 850daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataFormat(&dlf->mFormat); 851daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 852daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 8530b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 85461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/* Interface initialization hooks */ 8552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten 856a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenextern void 857a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DCommit_init(void *), 858a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DDoppler_init(void *), 859a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DGrouping_init(void *), 860a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_init(void *), 861a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DMacroscopic_init(void *), 862a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DSource_init(void *), 863a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten IAndroidConfiguration_init(void *), 864a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAndroidEffect_init(void *), 865a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten IAndroidEffectCapabilities_init(void *), 866a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten IAndroidEffectSend_init(void *), 86728bc6b725c207fb8fbd618caea4aa127f35ce1e1Jean-Michel Trivi IAndroidStreamSource_init(void *), 86861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioDecoderCapabilities_init(void *), 86961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioEncoder_init(void *), 870a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAudioEncoderCapabilities_init(void *), 87161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioIODeviceCapabilities_init(void *), 872a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IBassBoost_init(void *), 8730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IBufferQueue_init(void *), 87461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDeviceVolume_init(void *), 87561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicInterfaceManagement_init(void *), 87661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicSource_init(void *), 87761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_init(void *), 8780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_init(void *), 879a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEngineCapabilities_init(void *), 880a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEnvironmentalReverb_init(void *), 881a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEqualizer_init(void *), 88261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ILEDArray_init(void *), 8830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMessage_init(void *), 8840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMuteSolo_init(void *), 8850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITempo_init(void *), 8860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITime_init(void *), 88761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataExtraction_init(void *), 88861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataTraversal_init(void *), 88961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMuteSolo_init(void *), 89061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_init(void *), 8910b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IOutputMix_init(void *), 892a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IOutputMixExt_init(void *), 89361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPitch_init(void *), 8940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_init(void *), 89561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPlaybackRate_init(void *), 89661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPrefetchStatus_init(void *), 897a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IPresetReverb_init(void *), 89861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRatePitch_init(void *), 89961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRecord_init(void *), 9000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten ISeek_init(void *), 90161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IThreadSync_init(void *), 90261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IVibra_init(void *), 903a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IVirtualizer_init(void *), 9040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IVisualization_init(void *), 9050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IVolume_init(void *); 906a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 9074597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kastenextern void 908a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten I3DGrouping_deinit(void *), 909a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAndroidEffect_deinit(void *), 910a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAndroidEffectCapabilities_deinit(void *), 911a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IBassBoost_deinit(void *), 912a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IBufferQueue_deinit(void *), 913a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEngine_deinit(void *), 914a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEnvironmentalReverb_deinit(void *), 915a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEqualizer_deinit(void *), 916a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IObject_deinit(void *), 917a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IPresetReverb_deinit(void *), 918a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IThreadSync_deinit(void *), 919a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IVirtualizer_deinit(void *); 920a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 921a9a70a4451545034c9263dd55b181f2912534c37Glenn Kastenextern bool 922a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAndroidEffectCapabilities_Expose(void *), 923a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IBassBoost_Expose(void *), 924a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEnvironmentalReverb_Expose(void *), 925a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEqualizer_Expose(void *), 926a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IPresetReverb_Expose(void *), 927a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IVirtualizer_Expose(void *); 928b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 929a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if !(USE_PROFILES & USE_PROFILES_MUSIC) 930a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IDynamicSource_init NULL 931a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMetadataExtraction_init NULL 932a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMetadataTraversal_init NULL 933a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IVisualization_init NULL 934a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 935a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 936a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if !(USE_PROFILES & USE_PROFILES_GAME) 937a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DCommit_init NULL 938a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DDoppler_init NULL 939a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DGrouping_init NULL 940a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DLocation_init NULL 941a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DMacroscopic_init NULL 942a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DSource_init NULL 943a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMIDIMessage_init NULL 944a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMIDIMuteSolo_init NULL 945a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMIDITempo_init NULL 946a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMIDITime_init NULL 947a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IPitch_init NULL 948a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IRatePitch_init NULL 949a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DGrouping_deinit NULL 950a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 951a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 952a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if !(USE_PROFILES & USE_PROFILES_BASE) 953a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IAudioDecoderCapabilities_init NULL 954a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IAudioEncoderCapabilities_init NULL 955a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IAudioEncoder_init NULL 956a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IAudioIODeviceCapabilities_init NULL 957a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IDeviceVolume_init NULL 958a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IEngineCapabilities_init NULL 959a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IThreadSync_init NULL 960a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IThreadSync_deinit NULL 961a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 962a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 963a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if !(USE_PROFILES & USE_PROFILES_OPTIONAL) 964a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define ILEDArray_init NULL 965a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IVibra_init NULL 966a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 967a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 968a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#ifndef ANDROID 969a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidConfiguration_init NULL 970a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffect_init NULL 971a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffectCapabilities_init NULL 972a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffectSend_init NULL 973a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffect_deinit NULL 974a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffectCapabilities_deinit NULL 975a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffectCapabilities_Expose NULL 976a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 977a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 978a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#ifndef USE_OUTPUTMIXEXT 979a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IOutputMixExt_init NULL 980a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 981a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 982e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten 98361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/*static*/ const struct MPH_init MPH_init_table[MPH_MAX] = { 984711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DCOMMIT, */ I3DCommit_init, NULL, NULL, NULL, NULL }, 985711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DDOPPLER, */ I3DDoppler_init, NULL, NULL, NULL, NULL }, 986711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DGROUPING, */ I3DGrouping_init, NULL, I3DGrouping_deinit, NULL, NULL }, 987711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DLOCATION, */ I3DLocation_init, NULL, NULL, NULL, NULL }, 988711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DMACROSCOPIC, */ I3DMacroscopic_init, NULL, NULL, NULL, NULL }, 989711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DSOURCE, */ I3DSource_init, NULL, NULL, NULL, NULL }, 990711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_AUDIODECODERCAPABILITIES, */ IAudioDecoderCapabilities_init, NULL, NULL, NULL, NULL }, 991711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_AUDIOENCODER, */ IAudioEncoder_init, NULL, NULL, NULL, NULL }, 992711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_AUDIOENCODERCAPABILITIES, */ IAudioEncoderCapabilities_init, NULL, NULL, NULL, NULL }, 993711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_AUDIOIODEVICECAPABILITIES, */ IAudioIODeviceCapabilities_init, NULL, NULL, NULL, 994711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten NULL }, 995711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_BASSBOOST, */ IBassBoost_init, NULL, IBassBoost_deinit, IBassBoost_Expose, NULL }, 996711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_BUFFERQUEUE, */ IBufferQueue_init, NULL, IBufferQueue_deinit, NULL, NULL }, 997711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_DEVICEVOLUME, */ IDeviceVolume_init, NULL, NULL, NULL, NULL }, 998711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ IDynamicInterfaceManagement_init, NULL, NULL, NULL, 999711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten NULL }, 1000711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_DYNAMICSOURCE, */ IDynamicSource_init, NULL, NULL, NULL, NULL }, 1001711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_EFFECTSEND, */ IEffectSend_init, NULL, NULL, NULL, NULL }, 1002711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ENGINE, */ IEngine_init, NULL, IEngine_deinit, NULL, NULL }, 1003711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ENGINECAPABILITIES, */ IEngineCapabilities_init, NULL, NULL, NULL, NULL }, 1004a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten { /* MPH_ENVIRONMENTALREVERB, */ IEnvironmentalReverb_init, NULL, IEnvironmentalReverb_deinit, 1005711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten IEnvironmentalReverb_Expose, NULL }, 1006711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_EQUALIZER, */ IEqualizer_init, NULL, IEqualizer_deinit, IEqualizer_Expose, NULL }, 1007711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_LED, */ ILEDArray_init, NULL, NULL, NULL, NULL }, 1008711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_METADATAEXTRACTION, */ IMetadataExtraction_init, NULL, NULL, NULL, NULL }, 1009711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_METADATATRAVERSAL, */ IMetadataTraversal_init, NULL, NULL, NULL, NULL }, 1010711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MIDIMESSAGE, */ IMIDIMessage_init, NULL, NULL, NULL, NULL }, 1011711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MIDITIME, */ IMIDITime_init, NULL, NULL, NULL, NULL }, 1012711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MIDITEMPO, */ IMIDITempo_init, NULL, NULL, NULL, NULL }, 1013711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MIDIMUTESOLO, */ IMIDIMuteSolo_init, NULL, NULL, NULL, NULL }, 1014711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MUTESOLO, */ IMuteSolo_init, NULL, NULL, NULL, NULL }, 1015711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_NULL, */ NULL, NULL, NULL, NULL, NULL }, 1016711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_OBJECT, */ IObject_init, NULL, IObject_deinit, NULL, NULL }, 1017711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_OUTPUTMIX, */ IOutputMix_init, NULL, NULL, NULL, NULL }, 1018711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_PITCH, */ IPitch_init, NULL, NULL, NULL, NULL }, 1019711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_PLAY, */ IPlay_init, NULL, NULL, NULL, NULL }, 1020711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_PLAYBACKRATE, */ IPlaybackRate_init, NULL, NULL, NULL, NULL }, 1021711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_PREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL, NULL, NULL }, 1022a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten { /* MPH_PRESETREVERB, */ IPresetReverb_init, NULL, IPresetReverb_deinit, 1023711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten IPresetReverb_Expose, NULL }, 1024711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_RATEPITCH, */ IRatePitch_init, NULL, NULL, NULL, NULL }, 1025711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_RECORD, */ IRecord_init, NULL, NULL, NULL, NULL }, 1026711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_SEEK, */ ISeek_init, NULL, NULL, NULL, NULL }, 1027711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_THREADSYNC, */ IThreadSync_init, NULL, IThreadSync_deinit, NULL, NULL }, 1028711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_VIBRA, */ IVibra_init, NULL, NULL, NULL, NULL }, 1029711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_VIRTUALIZER, */ IVirtualizer_init, NULL, IVirtualizer_deinit, IVirtualizer_Expose, 1030711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten NULL }, 1031711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_VISUALIZATION, */ IVisualization_init, NULL, NULL, NULL, NULL }, 1032711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_VOLUME, */ IVolume_init, NULL, NULL, NULL, NULL }, 1033711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_OUTPUTMIXEXT, */ IOutputMixExt_init, NULL, NULL, NULL, NULL }, 1034711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ANDROIDEFFECT */ IAndroidEffect_init, NULL, IAndroidEffect_deinit, NULL, NULL }, 1035a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten { /* MPH_ANDROIDEFFECTCAPABILITIES */ IAndroidEffectCapabilities_init, NULL, 1036711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten IAndroidEffectCapabilities_deinit, IAndroidEffectCapabilities_Expose, NULL }, 1037711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ANDROIDEFFECTSEND */ IAndroidEffectSend_init, NULL, NULL, NULL, NULL }, 1038711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ANDROIDCONFIGURATION */ IAndroidConfiguration_init, NULL, NULL, NULL, NULL }, 103928bc6b725c207fb8fbd618caea4aa127f35ce1e1Jean-Michel Trivi { /* MPH_ANDROIDSIMPLEBUFFERQUEUE */ IBufferQueue_init /* alias */, NULL, NULL, NULL, NULL }, 104028bc6b725c207fb8fbd618caea4aa127f35ce1e1Jean-Michel Trivi { /* MPH_ANDROIDSTREAMSOURCE */ IAndroidStreamSource_init, NULL, NULL, NULL, NULL } 1041bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}; 1042bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 10430b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 1044e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Construct a new instance of the specified class, exposing selected interfaces */ 1045bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 1046ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn KastenIObject *construct(const ClassTable *class__, unsigned exposedMask, SLEngineItf engine) 1047bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 104872a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten IObject *this; 1049f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // Do not change this to malloc; we depend on the object being memset to zero 105072a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten this = (IObject *) calloc(1, class__->mSize); 1051bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL != this) { 1052a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten SL_LOGV("construct %s at %p", class__->mName, this); 105372a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten unsigned lossOfControlMask = 0; 1054ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // a NULL engine means we are constructing the engine 105572a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten IEngine *thisEngine = (IEngine *) engine; 1056d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (NULL == thisEngine) { 105772a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten thisEngine = &((CEngine *) this)->mEngine; 1058d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten } else { 1059ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_lock_exclusive(thisEngine); 1060d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (MAX_INSTANCE <= thisEngine->mInstanceCount) { 1061f51dba65751107c930759938775b75531ec1f330Glenn Kasten SL_LOGE("Too many objects"); 1062ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 1063d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten free(this); 1064ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten return NULL; 1065ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 1066d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // pre-allocate a pending slot, but don't assign bit from mInstanceMask yet 1067ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten ++thisEngine->mInstanceCount; 1068d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(((unsigned) ~0) != thisEngine->mInstanceMask); 1069ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 1070ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // const, no lock needed 1071f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (thisEngine->mLossOfControlGlobal) { 1072ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten lossOfControlMask = ~0; 1073f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 1074ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 107572a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten this->mLossOfControlMask = lossOfControlMask; 1076ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mClass = class__; 1077ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mEngine = thisEngine; 1078bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct iid_vtable *x = class__->mInterfaces; 1079510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint8 *interfaceStateP = this->mInterfaceStates; 1080510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint32 index; 1081510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten for (index = 0; index < class__->mInterfaceCount; ++index, ++x, exposedMask >>= 1) { 1082276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten SLuint8 state; 1083a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // initialize all interfaces with init hooks, even if not exposed 1084a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten const struct MPH_init *mi = &MPH_init_table[x->mMPH]; 1085a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten VoidHook init = mi->mInit; 1086a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten if (NULL != init) { 108783f93b0afd3607b1570d8473c2f6e45276c133baGlenn Kasten void *self = (char *) this + x->mOffset; 1088d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // IObject does not have an mThis, so [1] is not always defined 1089f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (index) { 1090d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten ((IObject **) self)[1] = this; 1091f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 1092a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // call the initialization hook 1093a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten (*init)(self); 1094e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten // IObject does not require a call to GetInterface 1095f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (index) { 1096711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // This trickery invalidates the v-table until GetInterface 1097e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten ((size_t *) self)[0] ^= ~0; 1098f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 1099a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // if interface is exposed, also call the optional expose hook 1100a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten BoolHook expose; 1101a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten state = (exposedMask & 1) && ((NULL == (expose = mi->mExpose)) || (*expose)(self)) ? 1102a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten INTERFACE_EXPOSED : INTERFACE_INITIALIZED; 1103a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // FIXME log or report to application if an expose hook on a 1104a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // required explicit interface fails at creation time 1105f51dba65751107c930759938775b75531ec1f330Glenn Kasten } else { 1106510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = INTERFACE_UNINITIALIZED; 1107f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 1108510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten *interfaceStateP++ = state; 1109bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 1110f51dba65751107c930759938775b75531ec1f330Glenn Kasten // note that the new object is not yet published; creator must call IObject_Publish 1111bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 1112bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return this; 1113bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 1114bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 1115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1116711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten/* This implementation supports at most one engine */ 1117711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1118711332800108ad6e0e594796e5f8db0da3eff402Glenn Kastenstatic CEngine *theOneTrueEngine = NULL; 1119711332800108ad6e0e594796e5f8db0da3eff402Glenn Kastenstatic pthread_mutex_t theOneTrueMutex = PTHREAD_MUTEX_INITIALIZER; 1120711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1121711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1122711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten/** \brief Called by dlopen when .so is loaded */ 1123711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1124711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten__attribute__((constructor)) static void onDlOpen(void) 1125711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten{ 1126711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten} 1127711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1128711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1129711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten/** \brief Called by dlclose when .so is unloaded */ 1130711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1131711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten__attribute__((destructor)) static void onDlClose(void) 1132711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten{ 1133711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (NULL != theOneTrueEngine) { 1134711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SL_LOGE("Object::Destroy omitted for engine %p", theOneTrueEngine); 1135711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten } 1136711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten} 1137711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1138711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten/** \brief Called by IObject::Destroy after engine is destroyed. The parameter refers to the 1139711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * previous engine, which is now undefined memory. 1140711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten */ 1141711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1142711332800108ad6e0e594796e5f8db0da3eff402Glenn Kastenvoid CEngine_Destroyed(CEngine *self) 1143711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten{ 1144711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten int ok; 1145711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten ok = pthread_mutex_lock(&theOneTrueMutex); 1146711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(0 == ok); 1147711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(self == theOneTrueEngine); 1148711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten theOneTrueEngine = NULL; 1149711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten ok = pthread_mutex_unlock(&theOneTrueMutex); 1150711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(0 == ok); 1151711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten} 1152711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1153711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1154ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten/* Initial global entry points */ 1155d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 11560b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 1157e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief slCreateEngine Function */ 11580b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 11590b167267bda99b68346045ccab14e810121d5de4Glenn KastenSLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions, 11600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLEngineOption *pEngineOptions, SLuint32 numInterfaces, 11610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 1162d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 1163ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_GLOBAL 1164ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1165711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten int ok; 1166711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten ok = pthread_mutex_lock(&theOneTrueMutex); 1167711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(0 == ok); 1168711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1169ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten do { 1170ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1171ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi#ifdef ANDROID 1172ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten android::ProcessState::self()->startThreadPool(); 117314e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT 1174ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten android::DataSource::RegisterDefaultSniffers(); 11756fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi#endif 117614e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif 1177ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1178ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pEngine) { 1179ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 1180ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 1181ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 1182ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pEngine = NULL; 1183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1184b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (NULL != theOneTrueEngine) { 1185b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten SL_LOGE("slCreateEngine while another engine %p is active", theOneTrueEngine); 1186b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten result = SL_RESULT_RESOURCE_ERROR; 1187b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten break; 1188b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 1189b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten 1190ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if ((0 < numOptions) && (NULL == pEngineOptions)) { 1191928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("numOptions=%lu and pEngineOptions=NULL", numOptions); 1192ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 1193ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 1194ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 1195ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1196ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // default values 1197ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLboolean threadSafe = SL_BOOLEAN_TRUE; 1198ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLboolean lossOfControlGlobal = SL_BOOLEAN_FALSE; 1199ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1200ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // process engine options 12010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 i; 12020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLEngineOption *option = pEngineOptions; 1203ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 12040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten for (i = 0; i < numOptions; ++i, ++option) { 12050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (option->feature) { 12060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_ENGINEOPTION_THREADSAFE: 12074b2f97bb1df6b3a65d2c3a158fba3a604c8f543cGlenn Kasten threadSafe = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize 12080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 12090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_ENGINEOPTION_LOSSOFCONTROL: 12104b2f97bb1df6b3a65d2c3a158fba3a604c8f543cGlenn Kasten lossOfControlGlobal = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize 12110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 12120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 1213928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SL_LOGE("unknown engine option: feature=%lu data=%lu", 1214928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten option->feature, option->data); 1215ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 1216ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 12170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 12180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1219928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 1220ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 1221928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 1222ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1223ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 1224ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE); 1225c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten assert(NULL != pCEngine_class); 1226ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = checkInterfaces(pCEngine_class, numInterfaces, 1227ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 1228928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 1229ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 1230928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 1231ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1232ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten CEngine *this = (CEngine *) construct(pCEngine_class, exposedMask, NULL); 1233ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == this) { 1234ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 1235ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 1236ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 1237ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1238a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // initialize fields not associated with an interface 1239a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten memset(&this->mSyncThread, 0, sizeof(pthread_t)); 1240a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // initialize fields related to an interface 1241ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0; 1242ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mEngine.mLossOfControlGlobal = lossOfControlGlobal; 1243ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mEngineCapabilities.mThreadSafe = threadSafe; 1244104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten IObject_Publish(&this->mObject); 1245711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten theOneTrueEngine = this; 1246104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten // return the new engine object 1247ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pEngine = &this->mObject.mItf; 1248ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1249ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } while(0); 1250ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1251711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten ok = pthread_mutex_unlock(&theOneTrueMutex); 1252711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(0 == ok); 1253711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 1254ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_GLOBAL 1255d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 1256d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 1257ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1258e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief slQueryNumSupportedEngineInterfaces Function */ 12590b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 1260ed46c29d6a09112dbbf584c82953f63289596fd6Glenn KastenSLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(SLuint32 *pNumSupportedInterfaces) 1261d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 1262ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_GLOBAL 1263ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1264ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pNumSupportedInterfaces) { 1265ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 1266ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 12677a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE); 12687a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten assert(NULL != class__); 12697a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten SLuint32 count = 0; 12707a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten SLuint32 i; 1271c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten for (i = 0; i < class__->mInterfaceCount; ++i) { 1272c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten switch (class__->mInterfaces[i].mInterface) { 1273c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_IMPLICIT: 1274104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten case INTERFACE_IMPLICIT_PREREALIZE: 1275c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_EXPLICIT: 12765e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_EXPLICIT_PREREALIZE: 1277c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_DYNAMIC: 12787a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten ++count; 1279c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 1280c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_UNAVAILABLE: 1281c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 1282c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten default: 1283c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten assert(false); 1284c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 1285c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten } 1286c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten } 12877a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten *pNumSupportedInterfaces = count; 1288ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 1289ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 1290ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1291ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_GLOBAL 1292d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 1293d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 1294ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1295e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief slQuerySupportedEngineInterfaces Function */ 12960b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 1297ed46c29d6a09112dbbf584c82953f63289596fd6Glenn KastenSLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId) 1298d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 1299ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_GLOBAL 1300ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1301ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pInterfaceId) { 1302ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 1303ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 13047a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten *pInterfaceId = NULL; 13057a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE); 13067a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten assert(NULL != class__); 13077a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; // will be reset later 13087a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten SLuint32 i; 13097a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten for (i = 0; i < class__->mInterfaceCount; ++i) { 1310c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten switch (class__->mInterfaces[i].mInterface) { 1311c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_IMPLICIT: 1312104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten case INTERFACE_IMPLICIT_PREREALIZE: 1313c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_EXPLICIT: 13145e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_EXPLICIT_PREREALIZE: 1315c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_DYNAMIC: 1316c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 1317c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_UNAVAILABLE: 13187a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten continue; 1319c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten default: 1320c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten assert(false); 1321c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 1322c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten } 13237a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten if (index == 0) { 132401e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // The engine has no aliases, but if it did, this would return only the primary 13257a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten *pInterfaceId = &SL_IID_array[class__->mInterfaces[i].mMPH]; 13267a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_SUCCESS; 13277a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten break; 13287a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten } 13297a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten --index; 1330ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 1331ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 1332ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1333ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_GLOBAL 1334d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 1335