sles.cpp revision ccdf07b17f23b4c040dd3f62478d0965eba804e3
1773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi/* 2773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project 3773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * 4773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 5773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * you may not use this file except in compliance with the License. 6773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * You may obtain a copy of the License at 7773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * 8773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 9773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * 10773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 11773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 12773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * See the License for the specific language governing permissions and 14773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * limitations under the License. 15773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi */ 16d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 17d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* OpenSL ES prototype */ 18d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 19773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi#include "sles_allinclusive.h" 20d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 21bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Private functions */ 22bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 23b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten// Map an IObject to it's "object ID" (which is really a class ID) 24b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 25b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn KastenSLuint32 IObjectToObjectID(IObject *this) 26b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 27b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(NULL != this); 28b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return this->mClass->mObjectID; 29b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 30b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 31bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Map SLInterfaceID to its minimal perfect hash (MPH), or -1 if unknown 32bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 3361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/*static*/ int IID_to_MPH(const SLInterfaceID iid) 34d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 35bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (&SL_IID_array[0] <= iid && &SL_IID_array[MPH_MAX] > iid) 36bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return iid - &SL_IID_array[0]; 37bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL != iid) { 38bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten // FIXME Replace this linear search by a good MPH algorithm 39bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct SLInterfaceID_ *srch = &SL_IID_array[0]; 40bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten unsigned MPH; 41bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten for (MPH = 0; MPH < MPH_MAX; ++MPH, ++srch) 42bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (!memcmp(iid, srch, sizeof(struct SLInterfaceID_))) 43bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return MPH; 44bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 45bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return -1; 46bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 47bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 4829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten// Check the interface IDs passed into a Create operation 4929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten 50979a3f8743646af9999a89dff9e13b972b7efd87Glenn KastenSLresult checkInterfaces(const ClassTable *class__, 51bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 52bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const SLboolean *pInterfaceRequired, unsigned *pExposedMask) 53bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 54bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten assert(NULL != class__ && NULL != pExposedMask); 55bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten unsigned exposedMask = 0; 56bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct iid_vtable *interfaces = class__->mInterfaces; 57bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 interfaceCount = class__->mInterfaceCount; 58bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLuint32 i; 59bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten // FIXME This section could be pre-computed per class 60bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten for (i = 0; i < interfaceCount; ++i) { 61bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten switch (interfaces[i].mInterface) { 62bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten case INTERFACE_IMPLICIT: 63bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten exposedMask |= 1 << i; 64bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 65bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten default: 66bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten break; 67bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 68bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 69d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten if (0 < numInterfaces) { 70d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten if (NULL == pInterfaceIds || NULL == pInterfaceRequired) 71d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 72d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten for (i = 0; i < numInterfaces; ++i) { 73bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten SLInterfaceID iid = pInterfaceIds[i]; 74bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL == iid) 75bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 7629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten int MPH, index; 7729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten if ((0 > (MPH = IID_to_MPH(iid))) || 7829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten (0 > (index = class__->mMPH_to_index[MPH]))) { 79bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (pInterfaceRequired[i]) 80bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 81bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten continue; 82bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 8329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // FIXME this seems a bit strong? what is correct logic? 8429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // we are requesting a duplicate explicit interface, 8529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // or we are requesting one which is already implicit ? 8629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // if (exposedMask & (1 << index)) 8729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten // return SL_RESULT_PARAMETER_INVALID; 88daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // can we request dynamic interfaces here? 8929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten exposedMask |= (1 << index); 90d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 91d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten } 92bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten *pExposedMask = exposedMask; 93d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 94d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 95d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 9661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten// private helper shared by decoder and encoder 9761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn KastenSLresult GetCodecCapabilities(SLuint32 decoderId, SLuint32 *pIndex, 9861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten SLAudioCodecDescriptor *pDescriptor, 9961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten const struct CodecDescriptor *codecDescriptors) 100bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 10161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (NULL == pIndex) 10261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 10361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten const struct CodecDescriptor *cd = codecDescriptors; 10461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten SLuint32 index; 10561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (NULL == pDescriptor) { 10661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten for (index = 0 ; NULL != cd->mDescriptor; ++cd) 10761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (cd->mCodecID == decoderId) 10861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ++index; 10961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten *pIndex = index; 11061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_SUCCESS; 11161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 11261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten index = *pIndex; 11361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten for ( ; NULL != cd->mDescriptor; ++cd) { 11461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (cd->mCodecID == decoderId) { 11561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (0 == index) { 11661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten *pDescriptor = *cd->mDescriptor; 11761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_SUCCESS; 11861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 11961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten --index; 12061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 12161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 12261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 123bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 1242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten 125daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult checkDataLocator(void *pLocator, DataLocator *pDataLocator) 126daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 127daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pLocator) { 128daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mLocatorType = 0; 129daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 130daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 131daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 locatorType = *(SLuint32 *)pLocator; 132daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (locatorType) { 133daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_ADDRESS: 134daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator; 135daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 < pDataLocator->mAddress.length && NULL == pDataLocator->mAddress.pAddress) 136daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 137daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 138daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 139daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator; 140daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 == pDataLocator->mBufferQueue.numBuffers) 141daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 142daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // pDataLocator->mBufferQueue.numBuffers = 2; 143daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // FIXME check against a max 144daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 145daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_IODEVICE: 146daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 147daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator; 148daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 deviceType = pDataLocator->mIODevice.deviceType; 149daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL != pDataLocator->mIODevice.device) { 150daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (IObjectToObjectID((IObject *) pDataLocator->mIODevice.device)) { 151daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_OBJECTID_LEDDEVICE: 152daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_LEDARRAY != deviceType) 153daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 154daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 155daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_OBJECTID_VIBRADEVICE: 156daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_VIBRA != deviceType) 157daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 158daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 159daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 160daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 161daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 162daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mIODevice.deviceID = 0; 163daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } else { 164daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataLocator->mIODevice.deviceID) { 165daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DEFAULTDEVICEID_LED: 166daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_LEDARRAY != deviceType) 167daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 168daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 169daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DEFAULTDEVICEID_VIBRA: 170daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_VIBRA != deviceType) 171daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 172daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 173daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DEFAULTDEVICEID_AUDIOINPUT: 174daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_IODEVICE_AUDIOINPUT != deviceType) 175daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 176daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 177daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 178daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 179daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 180daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 181daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 182daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 183daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 184daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator; 185daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 == pDataLocator->mMIDIBufferQueue.tpqn) 186daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue.tpqn = 192; 187daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (0 == pDataLocator->mMIDIBufferQueue.numBuffers) 188daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mMIDIBufferQueue.numBuffers = 2; 189daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 190daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 191daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator; 192daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if ((NULL == pDataLocator->mOutputMix.outputMix) || (SL_OBJECTID_OUTPUTMIX != IObjectToObjectID((IObject *) pDataLocator->mOutputMix.outputMix))) 193daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 194daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 195daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 196daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 197daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mURI = *(SLDataLocator_URI *)pLocator; 198daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataLocator->mURI.URI) 199daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 200daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten size_t len = strlen((const char *) pDataLocator->mURI.URI); 201daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLchar *myURI = (SLchar *) malloc(len + 1); 202daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == myURI) 203daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_MEMORY_FAILURE; 204daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten memcpy(myURI, pDataLocator->mURI.URI, len + 1); 205daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // Verify that another thread didn't change the NUL-terminator after we used it 206daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // to determine length of string to copy. It's OK if the string became shorter. 207daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if ('\0' != myURI[len]) { 208daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(myURI); 209daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 210daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 211daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataLocator->mURI.URI = myURI; 212daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 213daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 214daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 215daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 216daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 217daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // Verify that another thread didn't change the locatorType field after we used it 218daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // to determine sizeof struct to copy. 219daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (locatorType != pDataLocator->mLocatorType) 220daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 221daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 222daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 223daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 224daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic void freeDataLocator(DataLocator *pDataLocator) 225daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 226daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataLocator->mLocatorType) { 227daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 228daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(pDataLocator->mURI.URI); 229daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 230daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 231daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 232daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 233daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 234daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 235daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult checkDataFormat(void *pFormat, DataFormat *pDataFormat) 236daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 237daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pFormat) { 238daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mFormatType = 0; 239daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 240daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 241daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 formatType = *(SLuint32 *)pFormat; 242daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (formatType) { 243daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_PCM: 244daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat; 245daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.numChannels) { 246daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 1: 247daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 2: 248daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 249daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 0: 250daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 251daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 252daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 253daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 254daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.samplesPerSec) { 255daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_8: 256daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_11_025: 257daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_12: 258daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_16: 259daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_22_05: 260daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_24: 261daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_32: 262daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_44_1: 263daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_48: 264daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_64: 265daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_88_2: 266daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_96: 267daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SAMPLINGRATE_192: 268daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 269daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 0: 270daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 271daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 272daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 273daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 274daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.bitsPerSample) { 275daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_8: 276daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_16: 277daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 278daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_20: 279daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_24: 280daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_28: 281daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_32: 282daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 283daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 284daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 285daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 286daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.containerSize) { 287daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_8: 288daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_16: 289daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) 290daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 291daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 292daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 293daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 294daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 295daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.channelMask) { 296daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT: 297daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (2 != pDataFormat->mPCM.numChannels) 298daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 299daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 300daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SPEAKER_FRONT_LEFT: 301daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SPEAKER_FRONT_RIGHT: 302daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_SPEAKER_FRONT_CENTER: 303daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (1 != pDataFormat->mPCM.numChannels) 304daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 305daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 306daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case 0: 307daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ? SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER; 308daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 309daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 310daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 311daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 312daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mPCM.endianness) { 313daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_BYTEORDER_LITTLEENDIAN: 314daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 315daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_BYTEORDER_BIGENDIAN: 316daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 317daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 318daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 319daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 320daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 321daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_MIME: 322daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 323daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat; 324daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataFormat->mMIME.mimeType) 325daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 326daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten size_t len = strlen((const char *) pDataFormat->mMIME.mimeType); 327daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLchar *myMIME = (SLchar *) malloc(len + 1); 328daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == myMIME) 329daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_MEMORY_FAILURE; 330daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1); 331daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // ditto 332daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if ('\0' != myMIME[len]) { 333daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(myMIME); 334daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 335daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 336daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten pDataFormat->mMIME.mimeType = myMIME; 337daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 338daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 339daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 340daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 341daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 342daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (formatType != pDataFormat->mFormatType) 343daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 344daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 345daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 346daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 347daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic void freeDataFormat(DataFormat *pDataFormat) 348daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 349daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (pDataFormat->mFormatType) { 350daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_MIME: 351daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten free(pDataFormat->mMIME.mimeType); 352daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 353daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 354daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 355daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 356daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 357daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 358daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn KastenSLresult checkDataSource(const SLDataSource *pDataSrc, DataLocatorFormat *pDataLocatorFormat) 359daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 360daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataSrc) 361daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 362daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataSource myDataSrc = *pDataSrc; 363daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLresult result; 364daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataLocator(myDataSrc.pLocator, &pDataLocatorFormat->mLocator); 365daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_RESULT_SUCCESS != result) 366daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 367daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataFormat(myDataSrc.pFormat, &pDataLocatorFormat->mFormat); 368daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_RESULT_SUCCESS != result) { 369daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 370daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 371daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 372acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 373acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 374daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 375daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 376daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 377daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn KastenSLresult checkDataSink(const SLDataSink *pDataSink, DataLocatorFormat *pDataLocatorFormat) 378daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 379daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == pDataSink) 380daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 381daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataSink myDataSink = *pDataSink; 382daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLresult result; 383daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataLocator(myDataSink.pLocator, &pDataLocatorFormat->mLocator); 384daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_RESULT_SUCCESS != result) 385daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 386daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat); 387daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (SL_RESULT_SUCCESS != result) { 388daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 389daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return result; 390daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 391acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 392acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 393daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 394daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 395daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 396daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenvoid freeDataLocatorFormat(DataLocatorFormat *dlf) 397daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 398daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataLocator(&dlf->mLocator); 399daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten freeDataFormat(&dlf->mFormat); 400daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 401daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 40261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/* Interface initialization hooks */ 4032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten 404a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenextern void 405a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DCommit_init(void *), 406a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DDoppler_init(void *), 407a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DGrouping_init(void *), 408a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_init(void *), 409a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DMacroscopic_init(void *), 410a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DSource_init(void *), 41161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioDecoderCapabilities_init(void *), 41261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioEncoderCapabilities_init(void *), 41361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioEncoder_init(void *), 41461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IAudioIODeviceCapabilities_init(void *), 415a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IBassBoost_init(void *), 4160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IBufferQueue_init(void *), 41761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDeviceVolume_init(void *), 41861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicInterfaceManagement_init(void *), 41961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IDynamicSource_init(void *), 42061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_init(void *), 4210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngineCapabilities_init(void *), 4220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_init(void *), 423a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEnvironmentalReverb_init(void *), 424a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IEqualizer_init(void *), 42561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ILEDArray_init(void *), 4260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMessage_init(void *), 4270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDIMuteSolo_init(void *), 4280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITempo_init(void *), 4290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IMIDITime_init(void *), 43061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataExtraction_init(void *), 43161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMetadataTraversal_init(void *), 43261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IMuteSolo_init(void *), 43361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_init(void *), 4340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IOutputMix_init(void *), 43561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPitch_init(void *), 4360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_init(void *), 43761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPlaybackRate_init(void *), 43861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IPrefetchStatus_init(void *), 439a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IPresetReverb_init(void *), 44061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRatePitch_init(void *), 44161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IRecord_init(void *), 4420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten ISeek_init(void *), 44361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IThreadSync_init(void *), 44461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IVibra_init(void *), 445a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten IVirtualizer_init(void *), 4460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IVisualization_init(void *), 4470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IVolume_init(void *); 448a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 449b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#ifdef USE_OUTPUTMIXEXT 450b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kastenextern void 451b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten IOutputMixExt_init(void *); 452b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#endif 453b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 45461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/*static*/ const struct MPH_init MPH_init_table[MPH_MAX] = { 455a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_3DCOMMIT, */ I3DCommit_init, NULL }, 456a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_3DDOPPLER, */ I3DDoppler_init, NULL }, 457a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_3DGROUPING, */ I3DGrouping_init, NULL }, 458a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_3DLOCATION, */ I3DLocation_init, NULL }, 459a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_3DMACROSCOPIC, */ I3DMacroscopic_init, NULL }, 460a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_3DSOURCE, */ I3DSource_init, NULL }, 46161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_AUDIODECODERCAPABILITIES, */ IAudioDecoderCapabilities_init, NULL }, 46261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_AUDIOENCODER, */ IAudioEncoder_init, NULL }, 46361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_AUDIOENCODERCAPABILITIES, */ IAudioEncoderCapabilities_init, NULL }, 46461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_AUDIOIODEVICECAPABILITIES, */ IAudioIODeviceCapabilities_init, 465bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten NULL }, 466a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_BASSBOOST, */ IBassBoost_init, NULL }, 4670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_BUFFERQUEUE, */ IBufferQueue_init, NULL }, 46861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_DEVICEVOLUME, */ IDeviceVolume_init, NULL }, 46961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ IDynamicInterfaceManagement_init, 470bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten NULL }, 47161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_DYNAMICSOURCE, */ IDynamicSource_init, NULL }, 47261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_EFFECTSEND, */ IEffectSend_init, NULL }, 4730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_ENGINE, */ IEngine_init, NULL }, 4740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_ENGINECAPABILITIES, */ IEngineCapabilities_init, NULL }, 475a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_ENVIRONMENTALREVERB, */ IEnvironmentalReverb_init, NULL }, 476a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_EQUALIZER, */ IEqualizer_init, NULL }, 47761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_LED, */ ILEDArray_init, NULL }, 47861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_METADATAEXTRACTION, */ IMetadataExtraction_init, NULL }, 47961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_METADATATRAVERSAL, */ IMetadataTraversal_init, NULL }, 4800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_MIDIMESSAGE, */ IMIDIMessage_init, NULL }, 4810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_MIDITIME, */ IMIDITime_init, NULL }, 4820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_MIDITEMPO, */ IMIDITempo_init, NULL }, 4830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_MIDIMUTESOLO, */ IMIDIMuteSolo_init, NULL }, 48461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_MUTESOLO, */ IMuteSolo_init, NULL }, 485bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten { /* MPH_NULL, */ NULL, NULL }, 48661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_OBJECT, */ IObject_init, NULL }, 4870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_OUTPUTMIX, */ IOutputMix_init, NULL }, 48861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_PITCH, */ IPitch_init, NULL }, 4890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_PLAY, */ IPlay_init, NULL }, 49061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_PLAYBACKRATE, */ IPlaybackRate_init, NULL }, 49161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_PREFETCHSTATUS, */ IPrefetchStatus_init, NULL }, 492a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_PRESETREVERB, */ IPresetReverb_init, NULL }, 49361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_RATEPITCH, */ IRatePitch_init, NULL }, 49461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_RECORD, */ IRecord_init, NULL }, 4950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_SEEK, */ ISeek_init, NULL }, 49661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_THREADSYNC, */ IThreadSync_init, NULL }, 49761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten { /* MPH_VIBRA, */ IVibra_init, NULL }, 498a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_VIRTUALIZER, */ IVirtualizer_init, NULL }, 499a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten { /* MPH_VISUALIZATION, */ IVisualization_init, NULL }, 5000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { /* MPH_VOLUME, */ IVolume_init, NULL }, 501bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten { /* MPH_OUTPUTMIXEXT, */ 502bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT 503b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten IOutputMixExt_init, NULL 504bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else 505bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten NULL, NULL 506bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif 507bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 508bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}; 509bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 510bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Construct a new instance of the specified class, exposing selected interfaces 511bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 512ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn KastenIObject *construct(const ClassTable *class__, unsigned exposedMask, SLEngineItf engine) 513bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{ 51472a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten IObject *this; 51572a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten this = (IObject *) calloc(1, class__->mSize); 516bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL != this) { 51772a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten unsigned lossOfControlMask = 0; 518ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // a NULL engine means we are constructing the engine 51972a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten IEngine *thisEngine = (IEngine *) engine; 52072a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten if (NULL == thisEngine) 52172a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten thisEngine = &((CEngine *) this)->mEngine; 522ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten else { 523ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_lock_exclusive(thisEngine); 524ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten if (INSTANCE_MAX <= thisEngine->mInstanceCount) { 525ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // too many objects 526ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten free(this); 527ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 528ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten return NULL; 529ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 530ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten ++thisEngine->mInstanceCount; 531ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 532ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // const, no lock needed 533ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten if (thisEngine->mLossOfControlGlobal) 534ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten lossOfControlMask = ~0; 535ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 53672a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten this->mLossOfControlMask = lossOfControlMask; 537ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mClass = class__; 538ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mExposedMask = exposedMask; 539ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mEngine = thisEngine; 540bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten const struct iid_vtable *x = class__->mInterfaces; 541bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten unsigned i; 542bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten for (i = 0; exposedMask; ++i, ++x, exposedMask >>= 1) { 543bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (exposedMask & 1) { 54483f93b0afd3607b1570d8473c2f6e45276c133baGlenn Kasten void *self = (char *) this + x->mOffset; 54572a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten ((IObject **) self)[1] = this; 54683f93b0afd3607b1570d8473c2f6e45276c133baGlenn Kasten VoidHook init = MPH_init_table[x->mMPH].mInit; 547bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten if (NULL != init) 548bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten (*init)(self); 549bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 550bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 551ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // only expose new object to sync thread after it is fully initialized 552ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_lock_exclusive(thisEngine); 553ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten unsigned mask = thisEngine->mInstanceMask; 554ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten assert(mask != ~0); 555ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // FIXME O(n) 556ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten for (i = 0; i < INSTANCE_MAX; ++i, mask >>= 1) { 557ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten if (!(mask & 1)) { 558ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten assert(NULL == thisEngine->mInstances[i]); 559ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten thisEngine->mInstances[i] = this; 560ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten thisEngine->mInstanceMask |= 1 << i; 561ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // avoid zero as a valid instance ID 562ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten this->mInstanceID = i + 1; 563ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten break; 564ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten } 56572a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten } 566ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten assert(i < INSTANCE_MAX); 567ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 568bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten } 569bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten return this; 570bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} 571bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten 572b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten// The sync thread runs periodically to synchronize audio state between 573b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten// the application and platform-specific device driver; for best results 574b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten// it should run about every graphics frame (e.g. 20 Hz to 50 Hz). 575d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 576b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kastenstatic void *sync_body(void *arg) 577d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 5780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten CEngine *this = (CEngine *) arg; 5790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten for (;;) { 5800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten usleep(20000*50); 5810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned i; 5820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten for (i = 0; i < INSTANCE_MAX; ++i) { 5830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IObject *instance = (IObject *) this->mEngine.mInstances[i]; 5840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == instance) 5850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten continue; 586b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (IObjectToObjectID(instance)) { 587b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case SL_OBJECTID_AUDIOPLAYER: 5885fdec70b45c6c9b0cd52203b0ad49961a188eaffGlenn Kasten putchar('.'); 5895fdec70b45c6c9b0cd52203b0ad49961a188eaffGlenn Kasten fflush(stdout); 590b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 591b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 592b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 593b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 5940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 5952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten } 5960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return NULL; 597d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 598d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 5990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/* Initial entry points */ 600d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 6010b167267bda99b68346045ccab14e810121d5de4Glenn KastenSLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions, 6020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLEngineOption *pEngineOptions, SLuint32 numInterfaces, 6030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 604d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 6056fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi#ifdef USE_ANDROID 6066fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi android::ProcessState::self()->startThreadPool(); 6076fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi#endif 6080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pEngine) 609d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 6100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pEngine = NULL; 6110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // default values 6120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLboolean threadSafe = SL_BOOLEAN_TRUE; 6130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLboolean lossOfControlGlobal = SL_BOOLEAN_FALSE; 6140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL != pEngineOptions) { 6150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 i; 6160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLEngineOption *option = pEngineOptions; 6170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten for (i = 0; i < numOptions; ++i, ++option) { 6180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (option->feature) { 6190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_ENGINEOPTION_THREADSAFE: 6200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten threadSafe = (SLboolean) option->data; 6210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 6220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_ENGINEOPTION_LOSSOFCONTROL: 6230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten lossOfControlGlobal = (SLboolean) option->data; 6240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 6250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 6260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 6270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 6280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 62929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten } 6300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 631b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE); 632b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten SLresult result = checkInterfaces(pCEngine_class, numInterfaces, 6330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 6340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 6350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 636b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten CEngine *this = (CEngine *) construct(pCEngine_class, exposedMask, NULL); 6370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == this) 6380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 6390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0; 6400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mEngine.mLossOfControlGlobal = lossOfControlGlobal; 6410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mEngineCapabilities.mThreadSafe = threadSafe; 6420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten int ok; 643b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten ok = pthread_create(&this->mSyncThread, (const pthread_attr_t *) NULL, sync_body, this); 6440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten assert(ok == 0); 6450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pEngine = &this->mObject.mItf; 646d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 647d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 648d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 6490b167267bda99b68346045ccab14e810121d5de4Glenn KastenSLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces( 6500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 *pNumSupportedInterfaces) 651d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 6520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pNumSupportedInterfaces) 6532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 654b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE); 655b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten *pNumSupportedInterfaces = pCEngine_class->mInterfaceCount; 656d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 657d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 658d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 6590b167267bda99b68346045ccab14e810121d5de4Glenn KastenSLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, 6600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLInterfaceID *pInterfaceId) 661d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{ 6620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pInterfaceId) 6632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 664b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE); 665b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (pCEngine_class->mInterfaceCount <= index) 666b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 667b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten *pInterfaceId = &SL_IID_array[pCEngine_class->mInterfaces[index].mMPH]; 668d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten return SL_RESULT_SUCCESS; 669d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten} 670d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten 671d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* End */ 672