data.c revision 39310fca2e30101fa6e5168da443581cc60c20bf
1fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin/* 2fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * Copyright (C) 2010 The Android Open Source Project 3fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * 4fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License"); 5fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * you may not use this file except in compliance with the License. 6fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * You may obtain a copy of the License at 7fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * 8fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * http://www.apache.org/licenses/LICENSE-2.0 9fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * 10fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * Unless required by applicable law or agreed to in writing, software 11fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS, 12fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * See the License for the specific language governing permissions and 14fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * limitations under the License. 15fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin */ 16fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 17fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin/** Data locator, data format, data source, and data sink support */ 18fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 1900a9b46b5a85c2e7ff03d94e517f732d397eb020Igor Murashkin#include "sles_allinclusive.h" 20fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 21fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 22fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin/** \brief Check a data locator and make local deep copy */ 23fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 242d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkinstatic SLresult checkDataLocator(const char *name, void *pLocator, DataLocator *pDataLocator, 252d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin SLuint32 allowedDataLocatorMask) 26fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin{ 27fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin assert(NULL != name && NULL != pDataLocator); 28fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLresult result = SL_RESULT_SUCCESS; 29fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 30fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLuint32 locatorType; 31fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (NULL == pLocator) { 32fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mLocatorType = locatorType = SL_DATALOCATOR_NULL; 33fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } else { 34e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin locatorType = *(SLuint32 *)pLocator; 35e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin switch (locatorType) { 36e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin 37e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin case SL_DATALOCATOR_ADDRESS: 38fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator; 39fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // if length is greater than zero, then the address must be non-NULL 40fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if ((0 < pDataLocator->mAddress.length) && (NULL == pDataLocator->mAddress.pAddress)) { 41fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: pAddress=NULL", name); 42fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 43fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 44fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 45fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 46fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_BUFFERQUEUE: 47fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin#ifdef ANDROID 48fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // This is an alias that is _not_ converted; the rest of the code must check for both 49fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // locator types. That's because it is only an alias for audio players, not audio recorder 50fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // objects so we have to remember the distinction. 51fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 52fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin#endif 53fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator; 54fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // number of buffers must be specified, there is no default value, and can't be too big 55fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (!((1 <= pDataLocator->mBufferQueue.numBuffers) && 56fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin (pDataLocator->mBufferQueue.numBuffers <= 255))) { 57fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: numBuffers=%lu", name, pDataLocator->mBufferQueue.numBuffers); 58fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 59fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 60fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 61fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 62fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_IODEVICE: 63fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin { 64fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator; 65fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLuint32 deviceType = pDataLocator->mIODevice.deviceType; 66fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLObjectItf device = pDataLocator->mIODevice.device; 67fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (NULL != device) { 68fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mIODevice.deviceID = 0; 69fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLuint32 expectedObjectID; 70fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin switch (deviceType) { 71fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_IODEVICE_LEDARRAY: 72fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin expectedObjectID = SL_OBJECTID_LEDDEVICE; 73fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 74fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_IODEVICE_VIBRA: 75fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin expectedObjectID = SL_OBJECTID_VIBRADEVICE; 76fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 77fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case XA_IODEVICE_CAMERA: 78fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin expectedObjectID = XA_OBJECTID_CAMERADEVICE; 79fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 80fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case XA_IODEVICE_RADIO: 812d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin expectedObjectID = XA_OBJECTID_RADIODEVICE; 822d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin break; 832d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin // audio input and audio output cannot be specified via objects 842d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin case SL_IODEVICE_AUDIOINPUT: 85fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // case SL_IODEVICE_AUDIOOUTPUT: // does not exist in 1.0.1, added in 1.1 86fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin default: 87fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: deviceType=%lu", name, deviceType); 88fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mIODevice.device = NULL; 89fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin expectedObjectID = 0; 90fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 91fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 92fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (result == SL_RESULT_SUCCESS) { 93fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // check that device has the correct object ID and is realized, 94bb013aa3e197e881756be5ad13e6ad30bfb4aeffEino-Ville Talvala // and acquire a strong reference to it 95fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = AcquireStrongRef((IObject *) device, expectedObjectID); 96fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (SL_RESULT_SUCCESS != result) { 97fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: locatorType=IODEVICE, but device field %p has wrong " \ 98fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin "object ID or is not realized", name, device); 99fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mIODevice.device = NULL; 100fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 101fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 102fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } else { 103fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLuint32 deviceID = pDataLocator->mIODevice.deviceID; 104806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin switch (deviceType) { 105806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin case SL_IODEVICE_LEDARRAY: 106806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin if (SL_DEFAULTDEVICEID_LED != deviceID) { 107806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin SL_LOGE("%s: invalid LED deviceID=%lu", name, deviceID); 108806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin result = SL_RESULT_PARAMETER_INVALID; 109806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin } 110806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin break; 111806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin case SL_IODEVICE_VIBRA: 112806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin if (SL_DEFAULTDEVICEID_VIBRA != deviceID) { 113806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin SL_LOGE("%s: invalid vibra deviceID=%lu", name, deviceID); 114806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin result = SL_RESULT_PARAMETER_INVALID; 115806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin } 116806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin break; 117806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin case SL_IODEVICE_AUDIOINPUT: 118806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin if (SL_DEFAULTDEVICEID_AUDIOINPUT != deviceID) { 119806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin SL_LOGE("%s: invalid audio input deviceID=%lu", name, deviceID); 120806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin result = SL_RESULT_PARAMETER_INVALID; 121806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin } 122806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin break; 123806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin case XA_IODEVICE_RADIO: 124806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin // no default device ID for radio; see Khronos bug XXXX 125806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin break; 126806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin case XA_IODEVICE_CAMERA: 127ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin if (XA_DEFAULTDEVICEID_CAMERA != deviceID) { 128ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin SL_LOGE("%s: invalid audio input deviceID=%lu", name, deviceID); 129ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin result = XA_RESULT_PARAMETER_INVALID; 130ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin } 131ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin break; 132ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin // case SL_IODEVICE_AUDIOOUTPUT: 133ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin // does not exist in 1.0.1, added in 1.1 134ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin // break; 135ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin default: 136ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin SL_LOGE("%s: deviceType=%lu is invalid", name, deviceType); 137ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 138ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin } 139ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin } 140ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin } 141fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 142a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin 143a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin case SL_DATALOCATOR_MIDIBUFFERQUEUE: 144fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator; 145a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin if (0 == pDataLocator->mMIDIBufferQueue.tpqn) { 146fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mMIDIBufferQueue.tpqn = 192; 147fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 148fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // number of buffers must be specified, there is no default value, and can't be too big 149fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) && 150a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) { 151a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin SL_LOGE("%s: SLDataLocator_MIDIBufferQueue.numBuffers=%ld", name, 152fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mMIDIBufferQueue.numBuffers); 153fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 154a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin } 155fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 156fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 157fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_OUTPUTMIX: 158fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator; 1592d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin // check that output mix object has the correct object ID and is realized, 160fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // and acquire a strong reference to it 161fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = AcquireStrongRef((IObject *) pDataLocator->mOutputMix.outputMix, 162fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_OBJECTID_OUTPUTMIX); 1632d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin if (SL_RESULT_SUCCESS != result) { 164fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: locatorType=SL_DATALOCATOR_OUTPUTMIX, but outputMix field %p does " \ 165fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin "not refer to an SL_OBJECTID_OUTPUTMIX or the output mix is not realized", \ 166134cd3193ddc17e97cb6364594d85e5b203c7cc6Igor Murashkin name, pDataLocator->mOutputMix.outputMix); 167134cd3193ddc17e97cb6364594d85e5b203c7cc6Igor Murashkin pDataLocator->mOutputMix.outputMix = NULL; 168134cd3193ddc17e97cb6364594d85e5b203c7cc6Igor Murashkin } 169134cd3193ddc17e97cb6364594d85e5b203c7cc6Igor Murashkin break; 170fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 171fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case XA_DATALOCATOR_NATIVEDISPLAY: 172fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mNativeDisplay = *(XADataLocator_NativeDisplay *)pLocator; 173fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // hWindow is NDK C ANativeWindow * and hDisplay must be NULL 174fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (pDataLocator->mNativeDisplay.hWindow == NULL) { 175fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: hWindow must be non-NULL ANativeWindow *", name); 176fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 177fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 178fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (pDataLocator->mNativeDisplay.hDisplay != NULL) { 179fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: hDisplay must be NULL, but is %p", name, 180fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mNativeDisplay.hDisplay); 181fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 182fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 183fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 184e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin 185e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin case SL_DATALOCATOR_URI: 186e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin { 187e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin pDataLocator->mURI = *(SLDataLocator_URI *)pLocator; 188e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin if (NULL == pDataLocator->mURI.URI) { 189e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin SL_LOGE("%s: invalid URI=NULL", name); 190e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin result = SL_RESULT_PARAMETER_INVALID; 191e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin } 192e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin // NTH verify URI address for validity 193e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin size_t len = strlen((const char *) pDataLocator->mURI.URI); 194e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin SLchar *myURI = (SLchar *) malloc(len + 1); 195e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin if (NULL == myURI) { 196e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin result = SL_RESULT_MEMORY_FAILURE; 197e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin } else { 198e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin memcpy(myURI, pDataLocator->mURI.URI, len + 1); 199e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin // Verify that another thread didn't change the NUL-terminator after we used it 200fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // to determine length of string to copy. It's OK if the string became shorter. 201fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if ('\0' != myURI[len]) { 202fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin free(myURI); 203fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin myURI = NULL; 204fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 205fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 206fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 207fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mURI.URI = myURI; 208fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 209fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 210fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 211fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin#ifdef ANDROID 212fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ANDROIDFD: 213fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin { 214fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator; 215fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGV("%s: fd=%ld offset=%lld length=%lld", name, pDataLocator->mFD.fd, 216fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mFD.offset, pDataLocator->mFD.length); 217fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // NTH check against process fd limit 218fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (0 > pDataLocator->mFD.fd) { 219fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: fd=%ld\n", name, pDataLocator->mFD.fd); 220fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 221fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 222fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 223fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 224fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 225fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin { 2262d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin pDataLocator->mABQ = *(SLDataLocator_AndroidBufferQueue*)pLocator; 2272d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin // number of buffers must be specified, there is no default value, and can't be too big 228fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (!((1 <= pDataLocator->mBufferQueue.numBuffers) && 229fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin (pDataLocator->mBufferQueue.numBuffers <= 255))) { 230fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: numBuffers=%lu", name, pDataLocator->mABQ.numBuffers); 231fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 232fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 233fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 234fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 235fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin#endif 236fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 237fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_NULL: // a NULL pointer is allowed, but not a pointer to NULL 238fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin default: 239fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: locatorType=%lu", name, locatorType); 240fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 241fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 242fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 243fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // Verify that another thread didn't change the locatorType field after we used it 244fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // to determine sizeof struct to copy. 245fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if ((SL_RESULT_SUCCESS == result) && (locatorType != pDataLocator->mLocatorType)) { 246fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: locatorType changed from %lu to %lu", name, locatorType, 247fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mLocatorType); 248fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_PRECONDITIONS_VIOLATED; 249fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 250fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 251fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 252fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 253fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // Verify that the data locator type is allowed in this context 254fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (SL_RESULT_SUCCESS == result) { 255fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLuint32 actualMask; 256fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin switch (locatorType) { 257fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_NULL: 258fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_URI: 259fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ADDRESS: 260fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_IODEVICE: 261fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_OUTPUTMIX: 262fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case XA_DATALOCATOR_NATIVEDISPLAY: 263fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_BUFFERQUEUE: 264fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_MIDIBUFFERQUEUE: 265fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin actualMask = 1L << locatorType; 266fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 267fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin#ifdef ANDROID 268fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ANDROIDFD: 269fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 270fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 271fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin actualMask = 0x100L << (locatorType - SL_DATALOCATOR_ANDROIDFD); 272fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 273fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin#endif 274fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin default: 275fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin assert(false); 276fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin actualMask = 0L; 277fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 278fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 279fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (!(allowedDataLocatorMask & actualMask)) { 280fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SL_LOGE("%s: data locator type 0x%lx not allowed", name, locatorType); 281fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin result = SL_RESULT_CONTENT_UNSUPPORTED; 282fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 283fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 284fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 285fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin return result; 286fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin} 287fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 288fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 289fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin/** \brief Free the local deep copy of a data locator */ 290fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 291fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkinstatic void freeDataLocator(DataLocator *pDataLocator) 292fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin{ 293fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin switch (pDataLocator->mLocatorType) { 294fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_NULL: 295fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ADDRESS: 296fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_BUFFERQUEUE: 297fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_MIDIBUFFERQUEUE: 298fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case XA_DATALOCATOR_NATIVEDISPLAY: 299fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 300fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_URI: 301fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (NULL != pDataLocator->mURI.URI) { 302fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin free(pDataLocator->mURI.URI); 303fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mURI.URI = NULL; 304fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 305fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mURI.URI = NULL; 306fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 307fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_IODEVICE: 3082d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin if (NULL != pDataLocator->mIODevice.device) { 3092d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device); 310fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mIODevice.device = NULL; 311fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 312fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 313fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_OUTPUTMIX: 314fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (NULL != pDataLocator->mOutputMix.outputMix) { 315fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix); 316fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataLocator->mOutputMix.outputMix = NULL; 317fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 318fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 319fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin#ifdef ANDROID 320fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 321fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 322fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin case SL_DATALOCATOR_ANDROIDFD: 323fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 324fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin#endif 325fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin default: 326fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin // an invalid data locator is caught earlier when making the copy 327fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin assert(false); 328fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 329fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } 330fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin} 331fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 332fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 333fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin/** \brief Check a data format and make local deep copy */ 334fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 335fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkinstatic SLresult checkDataFormat(const char *name, void *pFormat, DataFormat *pDataFormat, 336fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLuint32 allowedDataFormatMask) 337fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin{ 338fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin assert(NULL != name && NULL != pDataFormat); 339fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLresult result = SL_RESULT_SUCCESS; 340fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin 341fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin SLuint32 formatType; 342fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin if (NULL == pFormat) { 343fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin pDataFormat->mFormatType = formatType = SL_DATAFORMAT_NULL; 344fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin } else { 345fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin formatType = *(SLuint32 *)pFormat; 3462d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin switch (formatType) { 3472d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin 3482d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin case SL_DATAFORMAT_PCM: 3492d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat; 3502d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin do { 3512d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin 3522d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin // check the channel count 3532d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin switch (pDataFormat->mPCM.numChannels) { 3542d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin case 1: // mono 3552d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin case 2: // stereo 3562d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin break; 3572d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin case 0: // unknown 3582d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin result = SL_RESULT_PARAMETER_INVALID; 3592d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin break; 3602d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin default: // multi-channel 3612d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin result = SL_RESULT_CONTENT_UNSUPPORTED; 3622d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin break; 3632d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin } 3642d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin if (SL_RESULT_SUCCESS != result) { 3652d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels); 3662d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin break; 3672d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin } 3682d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin 369d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He // check the sampling rate 370d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He switch (pDataFormat->mPCM.samplesPerSec) { 371d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_8: 372d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_11_025: 373d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_12: 374d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_16: 375d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_22_05: 376d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_24: 377d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_32: 378d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_44_1: 379d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_48: 380d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_64: 381d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_88_2: 382d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_96: 383d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case SL_SAMPLINGRATE_192: 384d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He break; 385d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He case 0: 386d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He result = SL_RESULT_PARAMETER_INVALID; 387d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He break; 388d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He default: 389d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He result = SL_RESULT_CONTENT_UNSUPPORTED; 390fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin break; 391 } 392 if (SL_RESULT_SUCCESS != result) { 393 SL_LOGE("%s: samplesPerSec=%lu", name, pDataFormat->mPCM.samplesPerSec); 394 break; 395 } 396 397 // check the sample bit depth 398 switch (pDataFormat->mPCM.bitsPerSample) { 399 case SL_PCMSAMPLEFORMAT_FIXED_8: 400 case SL_PCMSAMPLEFORMAT_FIXED_16: 401 break; 402 case SL_PCMSAMPLEFORMAT_FIXED_20: 403 case SL_PCMSAMPLEFORMAT_FIXED_24: 404 case SL_PCMSAMPLEFORMAT_FIXED_28: 405 case SL_PCMSAMPLEFORMAT_FIXED_32: 406 result = SL_RESULT_CONTENT_UNSUPPORTED; 407 break; 408 default: 409 result = SL_RESULT_PARAMETER_INVALID; 410 break; 411 } 412 if (SL_RESULT_SUCCESS != result) { 413 SL_LOGE("%s: bitsPerSample=%lu", name, pDataFormat->mPCM.bitsPerSample); 414 break; 415 } 416 417 // check the container bit depth 418 if (pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) { 419 result = SL_RESULT_PARAMETER_INVALID; 420 } else if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) { 421 result = SL_RESULT_CONTENT_UNSUPPORTED; 422 } 423 if (SL_RESULT_SUCCESS != result) { 424 SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name, 425 (unsigned) pDataFormat->mPCM.containerSize, 426 (unsigned) pDataFormat->mPCM.bitsPerSample); 427 break; 428 } 429 430 // check the channel mask 431 switch (pDataFormat->mPCM.channelMask) { 432 case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT: 433 if (2 != pDataFormat->mPCM.numChannels) { 434 result = SL_RESULT_PARAMETER_INVALID; 435 } 436 break; 437 case SL_SPEAKER_FRONT_LEFT: 438 case SL_SPEAKER_FRONT_RIGHT: 439 case SL_SPEAKER_FRONT_CENTER: 440 if (1 != pDataFormat->mPCM.numChannels) { 441 result = SL_RESULT_PARAMETER_INVALID; 442 } 443 break; 444 case 0: 445 pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ? 446 SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER; 447 break; 448 default: 449 result = SL_RESULT_PARAMETER_INVALID; 450 break; 451 } 452 if (SL_RESULT_SUCCESS != result) { 453 SL_LOGE("%s: channelMask=0x%lx numChannels=%lu", name, 454 pDataFormat->mPCM.channelMask, pDataFormat->mPCM.numChannels); 455 break; 456 } 457 458 // check the endianness / byte order 459 switch (pDataFormat->mPCM.endianness) { 460 case SL_BYTEORDER_LITTLEENDIAN: 461 case SL_BYTEORDER_BIGENDIAN: 462 break; 463 // native is proposed but not yet in spec 464 default: 465 result = SL_RESULT_PARAMETER_INVALID; 466 break; 467 } 468 if (SL_RESULT_SUCCESS != result) { 469 SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness); 470 break; 471 } 472 473 // here if all checks passed successfully 474 475 } while(0); 476 break; 477 478 case SL_DATAFORMAT_MIME: 479 pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat; 480 if (NULL != pDataFormat->mMIME.mimeType) { 481 // NTH check address for validity 482 size_t len = strlen((const char *) pDataFormat->mMIME.mimeType); 483 SLchar *myMIME = (SLchar *) malloc(len + 1); 484 if (NULL == myMIME) { 485 result = SL_RESULT_MEMORY_FAILURE; 486 } else { 487 memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1); 488 // make sure MIME string was not modified asynchronously 489 if ('\0' != myMIME[len]) { 490 free(myMIME); 491 myMIME = NULL; 492 result = SL_RESULT_PRECONDITIONS_VIOLATED; 493 } 494 } 495 pDataFormat->mMIME.mimeType = myMIME; 496 } 497 break; 498 499 case XA_DATAFORMAT_RAWIMAGE: 500 pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat; 501 switch (pDataFormat->mRawImage.colorFormat) { 502 case XA_COLORFORMAT_MONOCHROME: 503 case XA_COLORFORMAT_8BITRGB332: 504 case XA_COLORFORMAT_12BITRGB444: 505 case XA_COLORFORMAT_16BITARGB4444: 506 case XA_COLORFORMAT_16BITARGB1555: 507 case XA_COLORFORMAT_16BITRGB565: 508 case XA_COLORFORMAT_16BITBGR565: 509 case XA_COLORFORMAT_18BITRGB666: 510 case XA_COLORFORMAT_18BITARGB1665: 511 case XA_COLORFORMAT_19BITARGB1666: 512 case XA_COLORFORMAT_24BITRGB888: 513 case XA_COLORFORMAT_24BITBGR888: 514 case XA_COLORFORMAT_24BITARGB1887: 515 case XA_COLORFORMAT_25BITARGB1888: 516 case XA_COLORFORMAT_32BITBGRA8888: 517 case XA_COLORFORMAT_32BITARGB8888: 518 case XA_COLORFORMAT_YUV411PLANAR: 519 case XA_COLORFORMAT_YUV420PLANAR: 520 case XA_COLORFORMAT_YUV420SEMIPLANAR: 521 case XA_COLORFORMAT_YUV422PLANAR: 522 case XA_COLORFORMAT_YUV422SEMIPLANAR: 523 case XA_COLORFORMAT_YCBYCR: 524 case XA_COLORFORMAT_YCRYCB: 525 case XA_COLORFORMAT_CBYCRY: 526 case XA_COLORFORMAT_CRYCBY: 527 case XA_COLORFORMAT_YUV444INTERLEAVED: 528 case XA_COLORFORMAT_RAWBAYER8BIT: 529 case XA_COLORFORMAT_RAWBAYER10BIT: 530 case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED: 531 case XA_COLORFORMAT_L2: 532 case XA_COLORFORMAT_L4: 533 case XA_COLORFORMAT_L8: 534 case XA_COLORFORMAT_L16: 535 case XA_COLORFORMAT_L24: 536 case XA_COLORFORMAT_L32: 537 case XA_COLORFORMAT_18BITBGR666: 538 case XA_COLORFORMAT_24BITARGB6666: 539 case XA_COLORFORMAT_24BITABGR6666: 540 break; 541 case XA_COLORFORMAT_UNUSED: 542 default: 543 result = XA_RESULT_PARAMETER_INVALID; 544 SL_LOGE("%s: unsupported color format %ld", name, 545 pDataFormat->mRawImage.colorFormat); 546 break; 547 } 548 // no checks for height, width, or stride 549 break; 550 551 default: 552 result = SL_RESULT_PARAMETER_INVALID; 553 SL_LOGE("%s: formatType=%u", name, (unsigned) formatType); 554 break; 555 556 } 557 558 // make sure format type was not modified asynchronously 559 if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) { 560 SL_LOGE("%s: formatType changed from %lu to %lu", name, formatType, 561 pDataFormat->mFormatType); 562 result = SL_RESULT_PRECONDITIONS_VIOLATED; 563 } 564 565 } 566 567 // Verify that the data format type is allowed in this context 568 if (SL_RESULT_SUCCESS == result) { 569 SLuint32 actualMask; 570 switch (formatType) { 571 case SL_DATAFORMAT_NULL: 572 case SL_DATAFORMAT_MIME: 573 case SL_DATAFORMAT_PCM: 574 case XA_DATAFORMAT_RAWIMAGE: 575 actualMask = 1L << formatType; 576 break; 577 default: 578 assert(false); 579 actualMask = 0L; 580 break; 581 } 582 if (!(allowedDataFormatMask & actualMask)) { 583 SL_LOGE("%s: data format %ld not allowed", name, formatType); 584 result = SL_RESULT_CONTENT_UNSUPPORTED; 585 } 586 } 587 588 return result; 589} 590 591 592/** \brief Check interface ID compatibility with respect to a particular source 593 * data locator format 594 */ 595 596SLresult checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat, 597 const ClassTable *clazz, unsigned exposedMask) { 598 int index; 599 switch (pSrcDataLocatorFormat->mLocator.mLocatorType) { 600 case SL_DATALOCATOR_URI: 601#ifdef ANDROID 602 case SL_DATALOCATOR_ANDROIDFD: 603#endif 604 // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode 605 // so we don't prevent the retrieval of the BufferQueue interfaces for those sources 606 break; 607 608 case SL_DATALOCATOR_BUFFERQUEUE: 609#ifdef ANDROID 610 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 611#endif 612 // can't request SLSeekItf if data source is a buffer queue 613 index = clazz->mMPH_to_index[MPH_SEEK]; 614 if (0 <= index) { 615 if (exposedMask & (1 << index)) { 616 SL_LOGE("can't request SL_IID_SEEK with a buffer queue data source"); 617 return SL_RESULT_FEATURE_UNSUPPORTED; 618 } 619 } 620 // can't request SLMuteSoloItf if data source is a mono buffer queue 621 index = clazz->mMPH_to_index[MPH_MUTESOLO]; 622 if (0 <= index) { 623 if ((exposedMask & (1 << index)) && 624 (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) && 625 (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) { 626 SL_LOGE("can't request SL_IID_MUTESOLO with a mono buffer queue data source"); 627 return SL_RESULT_FEATURE_UNSUPPORTED; 628 } 629 } 630 break; 631 632#ifdef ANDROID 633 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 634#endif 635 case SL_DATALOCATOR_ADDRESS: 636 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 637 case XA_DATALOCATOR_NATIVEDISPLAY: 638 // any special checks here??? 639 default: 640 // can't request SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf 641 // if the data source is not a buffer queue 642 index = clazz->mMPH_to_index[MPH_BUFFERQUEUE]; 643#ifdef ANDROID 644 assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]); 645#endif 646 if (0 <= index) { 647 if (exposedMask & (1 << index)) { 648 SL_LOGE("can't request SL_IID_BUFFERQUEUE " 649#ifdef ANDROID 650 "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE " 651#endif 652 "with a non-buffer queue data source"); 653 return SL_RESULT_FEATURE_UNSUPPORTED; 654 } 655 } 656 break; 657 } 658 return SL_RESULT_SUCCESS; 659} 660 661 662/** \brief Free the local deep copy of a data format */ 663 664static void freeDataFormat(DataFormat *pDataFormat) 665{ 666 switch (pDataFormat->mFormatType) { 667 case SL_DATAFORMAT_MIME: 668 if (NULL != pDataFormat->mMIME.mimeType) { 669 free(pDataFormat->mMIME.mimeType); 670 pDataFormat->mMIME.mimeType = NULL; 671 } 672 break; 673 case SL_DATAFORMAT_PCM: 674 case XA_DATAFORMAT_RAWIMAGE: 675 case SL_DATAFORMAT_NULL: 676 break; 677 default: 678 // an invalid data format is caught earlier during the copy 679 assert(false); 680 break; 681 } 682} 683 684 685/** \brief Check a data source and make local deep copy */ 686 687SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc, 688 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 689 SLuint32 allowedDataFormatMask) 690{ 691 assert(NULL != name && NULL != pDataLocatorFormat); 692 pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 693 pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 694 695 if (NULL == pDataSrc) { 696 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 697 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 698 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 699 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 700 return SL_RESULT_SUCCESS; 701 } 702 SL_LOGE("%s: data source cannot be NULL", name); 703 return SL_RESULT_PARAMETER_INVALID; 704 } 705 SLDataSource myDataSrc = *pDataSrc; 706 SLresult result; 707 result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator, 708 allowedDataLocatorMask); 709 if (SL_RESULT_SUCCESS != result) { 710 return result; 711 } 712 713 switch (pDataLocatorFormat->mLocator.mLocatorType) { 714 case SL_DATALOCATOR_URI: 715 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 716 break; 717 case SL_DATALOCATOR_ADDRESS: 718 case SL_DATALOCATOR_BUFFERQUEUE: 719 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 720 break; 721 // Per the spec, the pFormat field is ignored in some cases 722 case SL_DATALOCATOR_IODEVICE: 723 myDataSrc.pFormat = NULL; 724 // fall through 725 case SL_DATALOCATOR_NULL: 726 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 727 allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 728 break; 729 case SL_DATALOCATOR_OUTPUTMIX: 730 case XA_DATALOCATOR_NATIVEDISPLAY: 731 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 732 break; 733#ifdef ANDROID 734 case SL_DATALOCATOR_ANDROIDFD: 735 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 736 break; 737 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 738 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 739 break; 740 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 741 allowedDataFormatMask &= DATAFORMAT_MASK_MIME;; 742 break; 743#endif 744 default: 745 // invalid data locator type is caught earlier 746 assert(false); 747 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 748 break; 749 } 750 751 result = checkDataFormat(name, myDataSrc.pFormat, &pDataLocatorFormat->mFormat, 752 allowedDataFormatMask); 753 if (SL_RESULT_SUCCESS != result) { 754 freeDataLocator(&pDataLocatorFormat->mLocator); 755 return result; 756 } 757 758 return SL_RESULT_SUCCESS; 759} 760 761 762/** \brief Check a data sink and make local deep copy */ 763 764SLresult checkDataSink(const char *name, const SLDataSink *pDataSink, 765 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 766 SLuint32 allowedDataFormatMask) 767{ 768 assert(NULL != name && NULL != pDataLocatorFormat); 769 pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 770 pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 771 772 if (NULL == pDataSink) { 773 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 774 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 775 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 776 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 777 return SL_RESULT_SUCCESS; 778 } 779 SL_LOGE("%s: data sink cannot be NULL", name); 780 return SL_RESULT_PARAMETER_INVALID; 781 } 782 SLDataSink myDataSink = *pDataSink; 783 SLresult result; 784 result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator, 785 allowedDataLocatorMask); 786 if (SL_RESULT_SUCCESS != result) { 787 return result; 788 } 789 790 switch (pDataLocatorFormat->mLocator.mLocatorType) { 791 case SL_DATALOCATOR_URI: 792 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 793 break; 794 case SL_DATALOCATOR_ADDRESS: 795 case SL_DATALOCATOR_BUFFERQUEUE: 796 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 797 break; 798 // Per the spec, the pFormat field is ignored in some cases 799 case SL_DATALOCATOR_IODEVICE: 800 case SL_DATALOCATOR_OUTPUTMIX: 801 case XA_DATALOCATOR_NATIVEDISPLAY: 802 myDataSink.pFormat = NULL; 803 // fall through 804 case SL_DATALOCATOR_NULL: 805 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 806 allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 807 break; 808#ifdef ANDROID 809 case SL_DATALOCATOR_ANDROIDFD: 810 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 811 break; 812 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 813 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 814 break; 815 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 816 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 817 break; 818#endif 819 default: 820 // invalid data locator type is caught earlier 821 assert(false); 822 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 823 break; 824 } 825 826 result = checkDataFormat(name, myDataSink.pFormat, &pDataLocatorFormat->mFormat, 827 allowedDataFormatMask); 828 if (SL_RESULT_SUCCESS != result) { 829 freeDataLocator(&pDataLocatorFormat->mLocator); 830 return result; 831 } 832 833 return SL_RESULT_SUCCESS; 834} 835 836 837/** \brief Free the local deep copy of a data locator format */ 838 839void freeDataLocatorFormat(DataLocatorFormat *dlf) 840{ 841 assert(NULL != dlf); 842 freeDataLocator(&dlf->mLocator); 843 freeDataFormat(&dlf->mFormat); 844} 845