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 30bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenbool IsInterfaceInitialized(IObject *thiz, unsigned MPH) 31e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten{ 32bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(NULL != thiz); 33e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten assert( /* (MPH_MIN <= MPH) && */ (MPH < (unsigned) MPH_MAX)); 34bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten const ClassTable *clazz = thiz->mClass; 35bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(NULL != clazz); 36e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten int index; 37bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (0 > (index = clazz->mMPH_to_index[MPH])) { 38e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten return false; 39928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 40bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(MAX_INDEX >= clazz->mInterfaceCount); 41bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(clazz->mInterfaceCount > (unsigned) index); 42bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten switch (thiz->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 54bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn KastenSLuint32 IObjectToObjectID(IObject *thiz) 55b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 56bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(NULL != thiz); 579e0f457f2809f5f062ac052d4a304e8996b49a80Glenn Kasten // Note this returns the OpenSL ES object ID in preference to the OpenMAX AL if both available 58bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten const ClassTable *clazz = thiz->mClass; 59bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(NULL != clazz); 60bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLuint32 id = clazz->mSLObjectID; 61ab7724988c1ff39ad3fc95a7ae0e638357708f7cGlenn Kasten if (!id) { 62bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten id = clazz->mXAObjectID; 63ab7724988c1ff39ad3fc95a7ae0e638357708f7cGlenn Kasten } 6494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten return id; 65b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 66b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 670b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 68928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Acquire a strong reference to an object. 69928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Check that object has the specified "object ID" (which is really a class ID) and is in the 70928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * realized state. If so, then acquire a strong reference to it and return true. 71928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Otherwise return false. 72928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */ 73928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 74928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn KastenSLresult AcquireStrongRef(IObject *object, SLuint32 expectedObjectID) 75928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten{ 76928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (NULL == object) { 77928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 78928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 79928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // NTH additional validity checks on address here 80928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SLresult result; 81928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten object_lock_exclusive(object); 82928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten SLuint32 actualObjectID = IObjectToObjectID(object); 83928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (expectedObjectID != actualObjectID) { 84a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("object %p has object ID %u but expected %u", object, actualObjectID, 85928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten expectedObjectID); 86928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 87928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } else if (SL_OBJECT_STATE_REALIZED != object->mState) { 88a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("object %p with object ID %u is not realized", object, actualObjectID); 89928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 90928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } else { 91928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten ++object->mStrongRefCount; 92928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten result = SL_RESULT_SUCCESS; 93928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 94928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten object_unlock_exclusive(object); 95928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten return result; 96928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten} 97928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 98928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 99928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Release a strong reference to an object. 100928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Entry condition: the object is locked. 101928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Exit condition: the object is unlocked. 102928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Finishes the destroy if needed. 103928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */ 104928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 105928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kastenvoid ReleaseStrongRefAndUnlockExclusive(IObject *object) 106928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten{ 107a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#ifdef USE_DEBUG 108928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten assert(pthread_equal(pthread_self(), object->mOwner)); 109a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 110928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten assert(0 < object->mStrongRefCount); 111928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if ((0 == --object->mStrongRefCount) && (SL_OBJECT_STATE_DESTROYING == object->mState)) { 112928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // FIXME do the destroy here - merge with IDestroy 113928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // but can't do this until we move Destroy to the sync thread 114928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten // as Destroy is now a blocking operation, and to avoid a race 115928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } else { 116928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten object_unlock_exclusive(object); 117928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 118928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten} 119928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 120928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 121928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Release a strong reference to an object. 122928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Entry condition: the object is unlocked. 123928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Exit condition: the object is unlocked. 124928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * Finishes the destroy if needed. 125928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */ 126928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 127928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kastenvoid ReleaseStrongRef(IObject *object) 128928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten{ 129928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten assert(NULL != object); 130928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten object_lock_exclusive(object); 131928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten ReleaseStrongRefAndUnlockExclusive(object); 132928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten} 133928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 134928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 135e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Convert POSIX pthread error code to OpenSL ES result code */ 136d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 137d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn KastenSLresult err_to_result(int err) 138d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten{ 139f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (EAGAIN == err || ENOMEM == err) { 140d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_RESOURCE_ERROR; 141f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 142f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (0 != err) { 143d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_INTERNAL_ERROR; 144f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 145d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten return SL_RESULT_SUCCESS; 146d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} 147d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 1480b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 149e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Check the interface IDs passed into a Create operation */ 15029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten 151bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn KastenSLresult checkInterfaces(const ClassTable *clazz, SLuint32 numInterfaces, 15205c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired, 15305c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten unsigned *pExposedMask, unsigned *pRequiredMask) 154bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 155bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(NULL != clazz && NULL != pExposedMask); 15601e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Initially no interfaces are exposed 157bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten unsigned exposedMask = 0; 15805c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten unsigned requiredMask = 0; 159bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten const struct iid_vtable *interfaces = clazz->mInterfaces; 160bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLuint32 interfaceCount = clazz->mInterfaceCount; 161bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 i; 16201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Expose all implicit interfaces 163bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten for (i = 0; i < interfaceCount; ++i) { 164bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten switch (interfaces[i].mInterface) { 165bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten case INTERFACE_IMPLICIT: 166104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten case INTERFACE_IMPLICIT_PREREALIZE: 167a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten // there must be an initialization hook present 168a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten if (NULL != MPH_init_table[interfaces[i].mMPH].mInit) { 169a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten exposedMask |= 1 << i; 170a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten } 171bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 1725e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_EXPLICIT: 1735e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_DYNAMIC: 1745e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_UNAVAILABLE: 1755e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_EXPLICIT_PREREALIZE: 1765e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten break; 177bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten default: 1785e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten assert(false); 179bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 180bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 181bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 182d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten if (0 < numInterfaces) { 183f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (NULL == pInterfaceIds || NULL == pInterfaceRequired) { 184d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 185f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 186104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten bool anyRequiredButUnsupported = false; 18701e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Loop for each requested interface 188d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten for (i = 0; i < numInterfaces; ++i) { 189bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLInterfaceID iid = pInterfaceIds[i]; 190f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (NULL == iid) { 191bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 192f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 19305c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten SLboolean isRequired = pInterfaceRequired[i]; 19429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten int MPH, index; 19529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten if ((0 > (MPH = IID_to_MPH(iid))) || 196a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten // there must be an initialization hook present 197a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten (NULL == MPH_init_table[MPH].mInit) || 198bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten (0 > (index = clazz->mMPH_to_index[MPH])) || 199104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten (INTERFACE_UNAVAILABLE == interfaces[index].mInterface)) { 20001e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Here if interface was not found, or is not available for this object type 20105c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten if (isRequired) { 20201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Application said it required the interface, so give up 203a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("class %s interface %u required but unavailable MPH=%d", 204bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten clazz->mName, i, MPH); 205104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten anyRequiredButUnsupported = true; 206f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 207a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // Application said it didn't really need the interface, so ignore with warning 208a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGW("class %s interface %u requested but unavailable MPH=%d", 209bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten clazz->mName, i, MPH); 210bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten continue; 211bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 21205c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten if (isRequired) { 21305c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten requiredMask |= (1 << index); 21405c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten } 21501e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // The requested interface was both found and available, so expose it 21629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten exposedMask |= (1 << index); 21701e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten // Note that we ignore duplicate requests, including equal and aliased IDs 218d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 219104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten if (anyRequiredButUnsupported) { 220104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 221104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten } 222d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 223bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten *pExposedMask = exposedMask; 22405c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten if (NULL != pRequiredMask) { 22505c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten *pRequiredMask = requiredMask; 22605c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten } 227d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 228d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 229d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 2300b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 23161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/* Interface initialization hooks */ 2322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten 233a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenextern void 234a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DCommit_init(void *), 235a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DDoppler_init(void *), 236a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DGrouping_init(void *), 237a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_init(void *), 238a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DMacroscopic_init(void *), 239a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DSource_init(void *), 240a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten IAndroidConfiguration_init(void *), 241a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAndroidEffect_init(void *), 242a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten IAndroidEffectCapabilities_init(void *), 243a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten IAndroidEffectSend_init(void *), 244fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi IAndroidBufferQueue_init(void *), 24561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioDecoderCapabilities_init(void *), 24661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioEncoder_init(void *), 247a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAudioEncoderCapabilities_init(void *), 24861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioIODeviceCapabilities_init(void *), 249a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IBassBoost_init(void *), 2500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IBufferQueue_init(void *), 25161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDeviceVolume_init(void *), 25261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicInterfaceManagement_init(void *), 25361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicSource_init(void *), 25461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_init(void *), 2550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_init(void *), 256a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEngineCapabilities_init(void *), 257a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEnvironmentalReverb_init(void *), 258a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEqualizer_init(void *), 25961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ILEDArray_init(void *), 2600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMessage_init(void *), 2610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMuteSolo_init(void *), 2620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITempo_init(void *), 2630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITime_init(void *), 26461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataExtraction_init(void *), 26561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataTraversal_init(void *), 26661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMuteSolo_init(void *), 26761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_init(void *), 2680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IOutputMix_init(void *), 269a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IOutputMixExt_init(void *), 27061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPitch_init(void *), 2710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_init(void *), 27261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPlaybackRate_init(void *), 27361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPrefetchStatus_init(void *), 274a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IPresetReverb_init(void *), 27561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRatePitch_init(void *), 27661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRecord_init(void *), 2770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten ISeek_init(void *), 27861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IThreadSync_init(void *), 27961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IVibra_init(void *), 280a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IVirtualizer_init(void *), 2810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IVisualization_init(void *), 2826e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IVolume_init(void *); 283a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 2844597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kastenextern void 285a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten I3DGrouping_deinit(void *), 286a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAndroidEffect_deinit(void *), 287a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAndroidEffectCapabilities_deinit(void *), 288d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi IAndroidBufferQueue_deinit(void *), 289a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IBassBoost_deinit(void *), 290a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IBufferQueue_deinit(void *), 291a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEngine_deinit(void *), 292a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEnvironmentalReverb_deinit(void *), 293a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEqualizer_deinit(void *), 294a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IObject_deinit(void *), 295a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IPresetReverb_deinit(void *), 296a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IThreadSync_deinit(void *), 2976e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IVirtualizer_deinit(void *); 298a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 299a9a70a4451545034c9263dd55b181f2912534c37Glenn Kastenextern bool 300a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IAndroidEffectCapabilities_Expose(void *), 301a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IBassBoost_Expose(void *), 302a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEnvironmentalReverb_Expose(void *), 303a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IEqualizer_Expose(void *), 304a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IPresetReverb_Expose(void *), 305a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten IVirtualizer_Expose(void *); 306b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 3078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenextern void 3086e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IXAEngine_init(void *), 3096e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IStreamInformation_init(void*), 3106e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IVideoDecoderCapabilities_init(void *); 3118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 312faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kastenextern void 3136e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IXAEngine_deinit(void *), 3146e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IStreamInformation_deinit(void *), 3156e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IVideoDecoderCapabilities_deinit(void *); 3166e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi 3176e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Triviextern bool 3186e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IVideoDecoderCapabilities_expose(void *); 319faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten 320a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if !(USE_PROFILES & USE_PROFILES_MUSIC) 321a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IDynamicSource_init NULL 322a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMetadataTraversal_init NULL 323a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IVisualization_init NULL 324a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 325a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 326a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if !(USE_PROFILES & USE_PROFILES_GAME) 327a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DCommit_init NULL 328a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DDoppler_init NULL 329a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DGrouping_init NULL 330a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DLocation_init NULL 331a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DMacroscopic_init NULL 332a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DSource_init NULL 333a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMIDIMessage_init NULL 334a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMIDIMuteSolo_init NULL 335a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMIDITempo_init NULL 336a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IMIDITime_init NULL 337a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IPitch_init NULL 338a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IRatePitch_init NULL 339a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define I3DGrouping_deinit NULL 340a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 341a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 342a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if !(USE_PROFILES & USE_PROFILES_BASE) 343a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IAudioDecoderCapabilities_init NULL 344a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IAudioEncoderCapabilities_init NULL 345a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IAudioEncoder_init NULL 346a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IAudioIODeviceCapabilities_init NULL 347a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IDeviceVolume_init NULL 348a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IEngineCapabilities_init NULL 349a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IThreadSync_init NULL 350a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IThreadSync_deinit NULL 351a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 352a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 353a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if !(USE_PROFILES & USE_PROFILES_OPTIONAL) 354a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define ILEDArray_init NULL 355a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IVibra_init NULL 356a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 357a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 358a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#ifndef ANDROID 359a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidConfiguration_init NULL 360a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffect_init NULL 361a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffectCapabilities_init NULL 362a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffectSend_init NULL 363a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffect_deinit NULL 364a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffectCapabilities_deinit NULL 365a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#define IAndroidEffectCapabilities_Expose NULL 366fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi#define IAndroidBufferQueue_init NULL 36737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi#define IStreamInformation_init NULL 368f6c0c2346b2ca1ac01c2d68a2cd2a7f1d9ff3427Glenn Kasten#define IAndroidBufferQueue_deinit NULL 369f6c0c2346b2ca1ac01c2d68a2cd2a7f1d9ff3427Glenn Kasten#define IStreamInformation_deinit NULL 370a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 371a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 372a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#ifndef USE_OUTPUTMIXEXT 373a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#define IOutputMixExt_init NULL 374a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#endif 375a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten 376e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten 37761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/*static*/ const struct MPH_init MPH_init_table[MPH_MAX] = { 378711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DCOMMIT, */ I3DCommit_init, NULL, NULL, NULL, NULL }, 379711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DDOPPLER, */ I3DDoppler_init, NULL, NULL, NULL, NULL }, 380711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DGROUPING, */ I3DGrouping_init, NULL, I3DGrouping_deinit, NULL, NULL }, 381711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DLOCATION, */ I3DLocation_init, NULL, NULL, NULL, NULL }, 382711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DMACROSCOPIC, */ I3DMacroscopic_init, NULL, NULL, NULL, NULL }, 383711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_3DSOURCE, */ I3DSource_init, NULL, NULL, NULL, NULL }, 384711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_AUDIODECODERCAPABILITIES, */ IAudioDecoderCapabilities_init, NULL, NULL, NULL, NULL }, 385711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_AUDIOENCODER, */ IAudioEncoder_init, NULL, NULL, NULL, NULL }, 386711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_AUDIOENCODERCAPABILITIES, */ IAudioEncoderCapabilities_init, NULL, NULL, NULL, NULL }, 387711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_AUDIOIODEVICECAPABILITIES, */ IAudioIODeviceCapabilities_init, NULL, NULL, NULL, 388711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten NULL }, 389711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_BASSBOOST, */ IBassBoost_init, NULL, IBassBoost_deinit, IBassBoost_Expose, NULL }, 390711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_BUFFERQUEUE, */ IBufferQueue_init, NULL, IBufferQueue_deinit, NULL, NULL }, 391711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_DEVICEVOLUME, */ IDeviceVolume_init, NULL, NULL, NULL, NULL }, 392711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ IDynamicInterfaceManagement_init, NULL, NULL, NULL, 393711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten NULL }, 394711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_DYNAMICSOURCE, */ IDynamicSource_init, NULL, NULL, NULL, NULL }, 395711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_EFFECTSEND, */ IEffectSend_init, NULL, NULL, NULL, NULL }, 396711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ENGINE, */ IEngine_init, NULL, IEngine_deinit, NULL, NULL }, 397711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ENGINECAPABILITIES, */ IEngineCapabilities_init, NULL, NULL, NULL, NULL }, 398a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten { /* MPH_ENVIRONMENTALREVERB, */ IEnvironmentalReverb_init, NULL, IEnvironmentalReverb_deinit, 399711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten IEnvironmentalReverb_Expose, NULL }, 400711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_EQUALIZER, */ IEqualizer_init, NULL, IEqualizer_deinit, IEqualizer_Expose, NULL }, 401711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_LED, */ ILEDArray_init, NULL, NULL, NULL, NULL }, 402711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_METADATAEXTRACTION, */ IMetadataExtraction_init, NULL, NULL, NULL, NULL }, 403711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_METADATATRAVERSAL, */ IMetadataTraversal_init, NULL, NULL, NULL, NULL }, 404711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MIDIMESSAGE, */ IMIDIMessage_init, NULL, NULL, NULL, NULL }, 405711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MIDITIME, */ IMIDITime_init, NULL, NULL, NULL, NULL }, 406711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MIDITEMPO, */ IMIDITempo_init, NULL, NULL, NULL, NULL }, 407711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MIDIMUTESOLO, */ IMIDIMuteSolo_init, NULL, NULL, NULL, NULL }, 408711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_MUTESOLO, */ IMuteSolo_init, NULL, NULL, NULL, NULL }, 409711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_NULL, */ NULL, NULL, NULL, NULL, NULL }, 410711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_OBJECT, */ IObject_init, NULL, IObject_deinit, NULL, NULL }, 411711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_OUTPUTMIX, */ IOutputMix_init, NULL, NULL, NULL, NULL }, 412711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_PITCH, */ IPitch_init, NULL, NULL, NULL, NULL }, 413711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_PLAY, */ IPlay_init, NULL, NULL, NULL, NULL }, 414711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_PLAYBACKRATE, */ IPlaybackRate_init, NULL, NULL, NULL, NULL }, 415711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_PREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL, NULL, NULL }, 416a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten { /* MPH_PRESETREVERB, */ IPresetReverb_init, NULL, IPresetReverb_deinit, 417711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten IPresetReverb_Expose, NULL }, 418711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_RATEPITCH, */ IRatePitch_init, NULL, NULL, NULL, NULL }, 419711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_RECORD, */ IRecord_init, NULL, NULL, NULL, NULL }, 420711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_SEEK, */ ISeek_init, NULL, NULL, NULL, NULL }, 421711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_THREADSYNC, */ IThreadSync_init, NULL, IThreadSync_deinit, NULL, NULL }, 422711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_VIBRA, */ IVibra_init, NULL, NULL, NULL, NULL }, 423711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_VIRTUALIZER, */ IVirtualizer_init, NULL, IVirtualizer_deinit, IVirtualizer_Expose, 424711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten NULL }, 425711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_VISUALIZATION, */ IVisualization_init, NULL, NULL, NULL, NULL }, 426711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_VOLUME, */ IVolume_init, NULL, NULL, NULL, NULL }, 427b0ab2dee391dd2cb257faeaba252ee6ecccc5f03Glenn Kasten// Wilhelm desktop extended interfaces 428711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_OUTPUTMIXEXT, */ IOutputMixExt_init, NULL, NULL, NULL, NULL }, 429b0ab2dee391dd2cb257faeaba252ee6ecccc5f03Glenn Kasten// Android API level 9 extended interfaces 430711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ANDROIDEFFECT */ IAndroidEffect_init, NULL, IAndroidEffect_deinit, NULL, NULL }, 431a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten { /* MPH_ANDROIDEFFECTCAPABILITIES */ IAndroidEffectCapabilities_init, NULL, 432711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten IAndroidEffectCapabilities_deinit, IAndroidEffectCapabilities_Expose, NULL }, 433711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ANDROIDEFFECTSEND */ IAndroidEffectSend_init, NULL, NULL, NULL, NULL }, 434711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten { /* MPH_ANDROIDCONFIGURATION */ IAndroidConfiguration_init, NULL, NULL, NULL, NULL }, 43528bc6b725c207fb8fbd618caea4aa127f35ce1e1Jean-Michel Trivi { /* MPH_ANDROIDSIMPLEBUFFERQUEUE */ IBufferQueue_init /* alias */, NULL, NULL, NULL, NULL }, 436b0ab2dee391dd2cb257faeaba252ee6ecccc5f03Glenn Kasten// Android API level 10 extended interfaces 43760ca9f9ef02f6e486c3338cb811f603dd7825c05Glenn Kasten { /* MPH_ANDROIDBUFFERQUEUESOURCE */ IAndroidBufferQueue_init, NULL, IAndroidBufferQueue_deinit, 43860ca9f9ef02f6e486c3338cb811f603dd7825c05Glenn Kasten NULL, NULL }, 4398db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten// OpenMAX AL 1.0.1 interfaces 440faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAAUDIODECODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 441faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAAUDIOENCODER */ NULL, NULL, NULL, NULL, NULL }, 442faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAAUDIOENCODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 443faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAAUDIOIODEVICECAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 444faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XACAMERA */ NULL, NULL, NULL, NULL, NULL }, 445faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XACAMERACAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 446faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XACONFIGEXTENSION */ NULL, NULL, NULL, NULL, NULL }, 447faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XADEVICEVOLUME */ NULL, NULL, NULL, NULL, NULL }, 448faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XADYNAMICINTERFACEMANAGEMENT 59 */ NULL, NULL, NULL, NULL, NULL }, 449faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XADYNAMICSOURCE */ NULL, NULL, NULL, NULL, NULL }, 450faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAENGINE */ IXAEngine_init, NULL, IXAEngine_deinit, NULL, NULL }, 451faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAEQUALIZER */ NULL, NULL, NULL, NULL, NULL }, 452faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAIMAGECONTROLS */ NULL, NULL, NULL, NULL, NULL }, 453faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAIMAGEDECODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 454faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAIMAGEEFFECTS */ NULL, NULL, NULL, NULL, NULL }, 455faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAIMAGEENCODER */ NULL, NULL, NULL, NULL, NULL }, 456faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAIMAGEENCODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 457faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XALED */ NULL, NULL, NULL, NULL, NULL }, 458faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAMETADATAEXTRACTION */ NULL, NULL, NULL, NULL, NULL }, 459faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAMETADATAINSERTION */ NULL, NULL, NULL, NULL, NULL }, 460faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAMETADATATRAVERSAL */ NULL, NULL, NULL, NULL, NULL }, 461faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten// { /* MPH_XANULL */ NULL, NULL, NULL, NULL, NULL }, 462faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAOBJECT */ IObject_init, NULL, IObject_deinit, NULL, NULL }, 463faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAOUTPUTMIX */ NULL, NULL, NULL, NULL, NULL }, 46494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten { /* MPH_XAPLAY */ IPlay_init, NULL, NULL, NULL, NULL }, 465faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAPLAYBACKRATE */ NULL, NULL, NULL, NULL, NULL }, 466c623c89c0a32c5fc77c998f1742d58e7be69e8c1Glenn Kasten { /* MPH_XAPREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL, NULL, NULL }, 467faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XARADIO */ NULL, NULL, NULL, NULL, NULL }, 468faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XARDS */ NULL, NULL, NULL, NULL, NULL }, 469faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XARECORD */ NULL, NULL, NULL, NULL, NULL }, 47092b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi { /* MPH_XASEEK */ ISeek_init, NULL, NULL, NULL, NULL }, 471faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XASNAPSHOT */ NULL, NULL, NULL, NULL, NULL }, 47237dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi { /* MPH_XASTREAMINFORMATION */ IStreamInformation_init, NULL, IStreamInformation_deinit, 47337dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi NULL, NULL }, 474faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XATHREADSYNC */ NULL, NULL, NULL, NULL, NULL }, 475faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAVIBRA */ NULL, NULL, NULL, NULL, NULL }, 4766e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi { /* MPH_XAVIDEODECODERCAPABILITIES */ IVideoDecoderCapabilities_init, NULL, 4776e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi IVideoDecoderCapabilities_deinit, IVideoDecoderCapabilities_expose, NULL }, 478faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAVIDEOENCODER */ NULL, NULL, NULL, NULL, NULL }, 479faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAVIDEOENCODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 480faea005a67ba7e75faea571c521ad2e44fe3dc27Glenn Kasten { /* MPH_XAVIDEOPOSTPROCESSING */ NULL, NULL, NULL, NULL, NULL }, 48137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi { /* MPH_XAVOLUME, */ IVolume_init, NULL, NULL, NULL, NULL }, 482bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}; 483bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 4840b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 485e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief Construct a new instance of the specified class, exposing selected interfaces */ 486bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 487bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn KastenIObject *construct(const ClassTable *clazz, unsigned exposedMask, SLEngineItf engine) 488bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 489bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject *thiz; 490f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // Do not change this to malloc; we depend on the object being memset to zero 491bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz = (IObject *) calloc(1, clazz->mSize); 492bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL != thiz) { 493bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SL_LOGV("construct %s at %p", clazz->mName, thiz); 49472a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten unsigned lossOfControlMask = 0; 495ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // a NULL engine means we are constructing the engine 49672a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten IEngine *thisEngine = (IEngine *) engine; 497d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (NULL == thisEngine) { 498bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten // thisEngine = &((CEngine *) thiz)->mEngine; 499bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mEngine = (CEngine *) thiz; 500d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten } else { 501bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mEngine = (CEngine *) thisEngine->mThis; 502ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_lock_exclusive(thisEngine); 503d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten if (MAX_INSTANCE <= thisEngine->mInstanceCount) { 504f51dba65751107c930759938775b75531ec1f330Glenn Kasten SL_LOGE("Too many objects"); 505ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 506bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten free(thiz); 507ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten return NULL; 508ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 509d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // pre-allocate a pending slot, but don't assign bit from mInstanceMask yet 510ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten ++thisEngine->mInstanceCount; 511d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(((unsigned) ~0) != thisEngine->mInstanceMask); 512ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 513ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // const, no lock needed 514f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (thisEngine->mLossOfControlGlobal) { 515ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten lossOfControlMask = ~0; 516f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 517ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 518bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLossOfControlMask = lossOfControlMask; 519bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mClass = clazz; 520bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten const struct iid_vtable *x = clazz->mInterfaces; 521bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLuint8 *interfaceStateP = thiz->mInterfaceStates; 522510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint32 index; 523bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten for (index = 0; index < clazz->mInterfaceCount; ++index, ++x, exposedMask >>= 1) { 524276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten SLuint8 state; 525a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // initialize all interfaces with init hooks, even if not exposed 526a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten const struct MPH_init *mi = &MPH_init_table[x->mMPH]; 527a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten VoidHook init = mi->mInit; 528a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten if (NULL != init) { 529bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten void *self = (char *) thiz + x->mOffset; 530d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten // IObject does not have an mThis, so [1] is not always defined 531f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (index) { 532bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ((IObject **) self)[1] = thiz; 533f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 534a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // call the initialization hook 535a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten (*init)(self); 536e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten // IObject does not require a call to GetInterface 537f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (index) { 538711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // This trickery invalidates the v-table until GetInterface 539e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten ((size_t *) self)[0] ^= ~0; 540f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 541a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // if interface is exposed, also call the optional expose hook 542a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten BoolHook expose; 543a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten state = (exposedMask & 1) && ((NULL == (expose = mi->mExpose)) || (*expose)(self)) ? 544a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten INTERFACE_EXPOSED : INTERFACE_INITIALIZED; 545a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // FIXME log or report to application if an expose hook on a 546a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // required explicit interface fails at creation time 547f51dba65751107c930759938775b75531ec1f330Glenn Kasten } else { 548510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = INTERFACE_UNINITIALIZED; 549f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 550510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten *interfaceStateP++ = state; 551bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 552f51dba65751107c930759938775b75531ec1f330Glenn Kasten // note that the new object is not yet published; creator must call IObject_Publish 553bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 554bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten return thiz; 555bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 556