18db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/* 28db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * Copyright (C) 2010 The Android Open Source Project 38db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * 48db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 58db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * you may not use this file except in compliance with the License. 68db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * You may obtain a copy of the License at 78db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * 88db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 98db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * 108db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * Unless required by applicable law or agreed to in writing, software 118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 128db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * See the License for the specific language governing permissions and 148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * limitations under the License. 158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten */ 168db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 178db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** Data locator, data format, data source, and data sink support */ 188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 198db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#include "sles_allinclusive.h" 20ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten#ifdef ANDROID // FIXME This file should be portable 21ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten#include "android/channels.h" 224e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean#include "data.h" 23ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten#endif 248db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 258db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** \brief Check a data locator and make local deep copy */ 268db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 2794a37e8117fb72790882dfb815f99e2365754c74Glenn Kastenstatic SLresult checkDataLocator(const char *name, void *pLocator, DataLocator *pDataLocator, 2894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 allowedDataLocatorMask) 298db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 3094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten assert(NULL != name && NULL != pDataLocator); 3194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLresult result = SL_RESULT_SUCCESS; 328db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 3394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 locatorType; 3494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (NULL == pLocator) { 3594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mLocatorType = locatorType = SL_DATALOCATOR_NULL; 3694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } else { 3794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten locatorType = *(SLuint32 *)pLocator; 3894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten switch (locatorType) { 3994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 4094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ADDRESS: 4194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator; 4294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // if length is greater than zero, then the address must be non-NULL 4394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if ((0 < pDataLocator->mAddress.length) && (NULL == pDataLocator->mAddress.pAddress)) { 4494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SL_LOGE("%s: pAddress=NULL", name); 4594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 4794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 488db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 4994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 508db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#ifdef ANDROID 5194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // This is an alias that is _not_ converted; the rest of the code must check for both 5294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // locator types. That's because it is only an alias for audio players, not audio recorder 5394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // objects so we have to remember the distinction. 5494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 558db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#endif 5694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator; 5794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // number of buffers must be specified, there is no default value, and can't be too big 5894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (!((1 <= pDataLocator->mBufferQueue.numBuffers) && 5994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten (pDataLocator->mBufferQueue.numBuffers <= 255))) { 60a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: numBuffers=%u", name, pDataLocator->mBufferQueue.numBuffers); 6194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 628db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 6394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 6494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 6594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_IODEVICE: 6694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten { 6794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator; 6894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 deviceType = pDataLocator->mIODevice.deviceType; 6994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLObjectItf device = pDataLocator->mIODevice.device; 7094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (NULL != device) { 7194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mIODevice.deviceID = 0; 7294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 expectedObjectID; 7394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten switch (deviceType) { 7494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_IODEVICE_LEDARRAY: 7594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten expectedObjectID = SL_OBJECTID_LEDDEVICE; 7694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 7794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_IODEVICE_VIBRA: 7894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten expectedObjectID = SL_OBJECTID_VIBRADEVICE; 7994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 8094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case XA_IODEVICE_CAMERA: 8194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten expectedObjectID = XA_OBJECTID_CAMERADEVICE; 8294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 8394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case XA_IODEVICE_RADIO: 8494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten expectedObjectID = XA_OBJECTID_RADIODEVICE; 8594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 8694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // audio input and audio output cannot be specified via objects 8794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_IODEVICE_AUDIOINPUT: 8894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // case SL_IODEVICE_AUDIOOUTPUT: // does not exist in 1.0.1, added in 1.1 8994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten default: 90a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: deviceType=%u", name, deviceType); 9194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mIODevice.device = NULL; 9294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten expectedObjectID = 0; 9394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 948db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 9594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (result == SL_RESULT_SUCCESS) { 9694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // check that device has the correct object ID and is realized, 9794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // and acquire a strong reference to it 9894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = AcquireStrongRef((IObject *) device, expectedObjectID); 9994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (SL_RESULT_SUCCESS != result) { 10094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SL_LOGE("%s: locatorType=IODEVICE, but device field %p has wrong " \ 10194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "object ID or is not realized", name, device); 10294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mIODevice.device = NULL; 10394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 1048db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 10594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } else { 10694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 deviceID = pDataLocator->mIODevice.deviceID; 10794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten switch (deviceType) { 10894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_IODEVICE_LEDARRAY: 10994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (SL_DEFAULTDEVICEID_LED != deviceID) { 110a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: invalid LED deviceID=%u", name, deviceID); 11194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 11294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 11394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 11494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_IODEVICE_VIBRA: 11594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (SL_DEFAULTDEVICEID_VIBRA != deviceID) { 116a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: invalid vibra deviceID=%u", name, deviceID); 11794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 11894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 11994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 12094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_IODEVICE_AUDIOINPUT: 12194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (SL_DEFAULTDEVICEID_AUDIOINPUT != deviceID) { 122a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: invalid audio input deviceID=%u", name, deviceID); 12394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 12494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 12594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 12694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case XA_IODEVICE_RADIO: 12794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // no default device ID for radio; see Khronos bug XXXX 12894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 12994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case XA_IODEVICE_CAMERA: 13094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (XA_DEFAULTDEVICEID_CAMERA != deviceID) { 131a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: invalid audio input deviceID=%u", name, deviceID); 13294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = XA_RESULT_PARAMETER_INVALID; 13394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 13494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 13594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // case SL_IODEVICE_AUDIOOUTPUT: 13694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // does not exist in 1.0.1, added in 1.1 13794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // break; 13894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten default: 139a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: deviceType=%u is invalid", name, deviceType); 14094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 1418b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 1428db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 14394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 14494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 1458db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 14694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 14794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator; 14894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (0 == pDataLocator->mMIDIBufferQueue.tpqn) { 14994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mMIDIBufferQueue.tpqn = 192; 15094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 15194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // number of buffers must be specified, there is no default value, and can't be too big 15294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) && 15394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) { 154a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: SLDataLocator_MIDIBufferQueue.numBuffers=%d", name, 15594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mMIDIBufferQueue.numBuffers); 15694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 15794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 15894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 1598db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 16094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 16194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator; 16294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // check that output mix object has the correct object ID and is realized, 16394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // and acquire a strong reference to it 16494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = AcquireStrongRef((IObject *) pDataLocator->mOutputMix.outputMix, 16594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SL_OBJECTID_OUTPUTMIX); 16694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (SL_RESULT_SUCCESS != result) { 16794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SL_LOGE("%s: locatorType=SL_DATALOCATOR_OUTPUTMIX, but outputMix field %p does " \ 16894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "not refer to an SL_OBJECTID_OUTPUTMIX or the output mix is not realized", \ 16994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten name, pDataLocator->mOutputMix.outputMix); 17094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mOutputMix.outputMix = NULL; 17194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 17294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 1738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 17494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case XA_DATALOCATOR_NATIVEDISPLAY: 17594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mNativeDisplay = *(XADataLocator_NativeDisplay *)pLocator; 17639310fca2e30101fa6e5168da443581cc60c20bfGlenn Kasten // hWindow is NDK C ANativeWindow * and hDisplay must be NULL 177ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten if (pDataLocator->mNativeDisplay.hWindow == NULL) { 17839310fca2e30101fa6e5168da443581cc60c20bfGlenn Kasten SL_LOGE("%s: hWindow must be non-NULL ANativeWindow *", name); 17939310fca2e30101fa6e5168da443581cc60c20bfGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 18039310fca2e30101fa6e5168da443581cc60c20bfGlenn Kasten } 18139310fca2e30101fa6e5168da443581cc60c20bfGlenn Kasten if (pDataLocator->mNativeDisplay.hDisplay != NULL) { 18239310fca2e30101fa6e5168da443581cc60c20bfGlenn Kasten SL_LOGE("%s: hDisplay must be NULL, but is %p", name, 18339310fca2e30101fa6e5168da443581cc60c20bfGlenn Kasten pDataLocator->mNativeDisplay.hDisplay); 184ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 185ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten } 18694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 1878b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 18894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_URI: 18994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten { 19094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mURI = *(SLDataLocator_URI *)pLocator; 19194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (NULL == pDataLocator->mURI.URI) { 19294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SL_LOGE("%s: invalid URI=NULL", name); 19394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 194c9919caaee38e3c4dbe09ea7cd5916d9b4a0f4a2Glenn Kasten } else { 1955793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten // NTH verify URI address for validity 1965793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten size_t len = strlen((const char *) pDataLocator->mURI.URI); 1975793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten SLchar *myURI = (SLchar *) malloc(len + 1); 1985793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten if (NULL == myURI) { 1995793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten result = SL_RESULT_MEMORY_FAILURE; 2005793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten } else { 2015793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten memcpy(myURI, pDataLocator->mURI.URI, len + 1); 2025793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten // Verify that another thread didn't change the NUL-terminator after we used it 2035793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten // to determine length of string to copy. It's OK if the string became shorter. 2045793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten if ('\0' != myURI[len]) { 2055793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten free(myURI); 2065793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten myURI = NULL; 2075793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 2085793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten } 209c9919caaee38e3c4dbe09ea7cd5916d9b4a0f4a2Glenn Kasten } 2105793033ccaeb30cc4936497f64dfa2cfe2cc405fGlenn Kasten pDataLocator->mURI.URI = myURI; 21194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 21294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 21394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 2148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 2158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#ifdef ANDROID 21694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ANDROIDFD: 217d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi { 21894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator; 219a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGV("%s: fd=%d offset=%lld length=%lld", name, pDataLocator->mFD.fd, 22094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mFD.offset, pDataLocator->mFD.length); 22194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // NTH check against process fd limit 22294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (0 > pDataLocator->mFD.fd) { 223a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: fd=%d\n", name, pDataLocator->mFD.fd); 22494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 22594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 22694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 227d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 22894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 229d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi { 230d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi pDataLocator->mABQ = *(SLDataLocator_AndroidBufferQueue*)pLocator; 231d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // number of buffers must be specified, there is no default value, and can't be too big 232d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi if (!((1 <= pDataLocator->mBufferQueue.numBuffers) && 233d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi (pDataLocator->mBufferQueue.numBuffers <= 255))) { 234a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: numBuffers=%u", name, pDataLocator->mABQ.numBuffers); 235d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi result = SL_RESULT_PARAMETER_INVALID; 23694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 23794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 238d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 23994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 24094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 24194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_NULL: // a NULL pointer is allowed, but not a pointer to NULL 24294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten default: 243a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: locatorType=%u", name, locatorType); 24494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 2458db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 24694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 24794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // Verify that another thread didn't change the locatorType field after we used it 24894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // to determine sizeof struct to copy. 2491d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten if ((SL_RESULT_SUCCESS == result) && (locatorType != pDataLocator->mLocatorType)) { 250a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: locatorType changed from %u to %u", name, locatorType, 25194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocator->mLocatorType); 25294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 2538db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 2548db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 2558db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 2568db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 25794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // Verify that the data locator type is allowed in this context 25894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (SL_RESULT_SUCCESS == result) { 25994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 actualMask; 26094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten switch (locatorType) { 26194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_NULL: 26294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_URI: 26394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ADDRESS: 26494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_IODEVICE: 26594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 26694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case XA_DATALOCATOR_NATIVEDISPLAY: 26794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 26894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 26994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten actualMask = 1L << locatorType; 27094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 27194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#ifdef ANDROID 27294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ANDROIDFD: 27394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 27494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 27594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten actualMask = 0x100L << (locatorType - SL_DATALOCATOR_ANDROIDFD); 27694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 27794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 27894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten default: 27994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten assert(false); 28094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten actualMask = 0L; 28194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 28294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 28394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (!(allowedDataLocatorMask & actualMask)) { 284a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: data locator type 0x%x not allowed", name, locatorType); 28594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 28694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 2878db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 28894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 28994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten return result; 2908db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 2918db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 2928db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 2938db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** \brief Free the local deep copy of a data locator */ 2948db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 2958db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic void freeDataLocator(DataLocator *pDataLocator) 2968db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 2978db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten switch (pDataLocator->mLocatorType) { 29894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_NULL: 2998b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATALOCATOR_ADDRESS: 3008b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 3018b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 3028b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_DATALOCATOR_NATIVEDISPLAY: 3038b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 3048db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_URI: 3058db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL != pDataLocator->mURI.URI) { 3068db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten free(pDataLocator->mURI.URI); 3078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pDataLocator->mURI.URI = NULL; 3088db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 3098db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pDataLocator->mURI.URI = NULL; 3108db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 3118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_IODEVICE: 3128db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL != pDataLocator->mIODevice.device) { 3138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device); 3148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pDataLocator->mIODevice.device = NULL; 3158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 3168db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 3178db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 3188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL != pDataLocator->mOutputMix.outputMix) { 3198db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix); 3208db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pDataLocator->mOutputMix.outputMix = NULL; 3218db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 3228db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 3238db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#ifdef ANDROID 324fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 3258b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 3268b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATALOCATOR_ANDROIDFD: 3278db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 3288db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#endif 3298db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten default: 3308b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // an invalid data locator is caught earlier when making the copy 3318b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten assert(false); 3328db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 3338db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 3348db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 3358db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 3368db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 3378db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** \brief Check a data format and make local deep copy */ 3388db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 33994a37e8117fb72790882dfb815f99e2365754c74Glenn Kastenstatic SLresult checkDataFormat(const char *name, void *pFormat, DataFormat *pDataFormat, 3404e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SLuint32 allowedDataFormatMask, SLboolean isOutputFormat) 3418db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 34294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten assert(NULL != name && NULL != pDataFormat); 3438db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten SLresult result = SL_RESULT_SUCCESS; 344e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists 34594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 formatType; 3468db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL == pFormat) { 34794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataFormat->mFormatType = formatType = SL_DATAFORMAT_NULL; 3488db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } else { 34994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten formatType = *(SLuint32 *)pFormat; 3508db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten switch (formatType) { 351e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case SL_ANDROID_DATAFORMAT_PCM_EX: 352e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung pDataFormat->mPCMEx.representation = 353e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung ((SLAndroidDataFormat_PCM_EX *)pFormat)->representation; 354e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung switch (pDataFormat->mPCMEx.representation) { 355e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT: 356e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT: 357e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case SL_ANDROID_PCM_REPRESENTATION_FLOAT: 358e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung df_representation = &pDataFormat->mPCMEx.representation; 359e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung break; 360e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung default: 361e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung SL_LOGE("%s: unsupported representation: %d", name, 362e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung pDataFormat->mPCMEx.representation); 363e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung result = SL_RESULT_PARAMETER_INVALID; 364e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung break; 365e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung } 366e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test. 3678db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATAFORMAT_PCM: 3688db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat; 3698db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten do { 3704e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (pDataFormat->mPCM.numChannels == 0) { 3718db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 3724e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } else if (pDataFormat->mPCM.numChannels > SL_ANDROID_SPEAKER_COUNT_MAX) { 3738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 3748db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 3758db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (SL_RESULT_SUCCESS != result) { 3761d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels); 3778db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 3788db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 3798db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 3808db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // check the sampling rate 381cc97dbea7dbe0726f097d235163f2085a1b21498Glenn Kasten if (pDataFormat->mPCM.samplesPerSec == 0) { 3828db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 383cc97dbea7dbe0726f097d235163f2085a1b21498Glenn Kasten } else if (pDataFormat->mPCM.samplesPerSec < SL_SAMPLINGRATE_8 || 384cc97dbea7dbe0726f097d235163f2085a1b21498Glenn Kasten pDataFormat->mPCM.samplesPerSec > SL_SAMPLINGRATE_192) { 3858db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 3868db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 3878db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (SL_RESULT_SUCCESS != result) { 388a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: samplesPerSec=%u", name, pDataFormat->mPCM.samplesPerSec); 3898db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 3908db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 3918db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 39271065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten // check the container bit depth and representation 393e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung switch (pDataFormat->mPCM.containerSize) { 394e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case 8: 3950d4d82daff89115d5a6318c53f94f22fa36a862bGlenn Kasten if (df_representation != NULL && 396e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung *df_representation != SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT) { 397e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung result = SL_RESULT_PARAMETER_INVALID; 398e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung } 3998db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 400e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case 16: 401e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case 24: 4020d4d82daff89115d5a6318c53f94f22fa36a862bGlenn Kasten if (df_representation != NULL && 403e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT) { 404e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung result = SL_RESULT_PARAMETER_INVALID; 405e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung } 406e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung break; 407e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case 32: 4080d4d82daff89115d5a6318c53f94f22fa36a862bGlenn Kasten if (df_representation != NULL 409e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung && *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT 410e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung && *df_representation != SL_ANDROID_PCM_REPRESENTATION_FLOAT) { 411e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung result = SL_RESULT_PARAMETER_INVALID; 412e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung } 4138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 4148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten default: 4158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4168db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 4178db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 4188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (SL_RESULT_SUCCESS != result) { 419e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung SL_LOGE("%s: containerSize=%u", name, pDataFormat->mPCM.containerSize); 4208db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 4218db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 4228db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 42371065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten // sample size cannot be zero, and container size cannot be less than sample size 42471065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten if (pDataFormat->mPCM.bitsPerSample == 0 || 42571065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) { 4268db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4278db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 4288db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (SL_RESULT_SUCCESS != result) { 4291d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name, 4308db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (unsigned) pDataFormat->mPCM.containerSize, 4318db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (unsigned) pDataFormat->mPCM.bitsPerSample); 4328db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 4338db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 4348db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 4358db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // check the channel mask 4364e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_LOGV("%s: Requested channel mask of 0x%x for %d channel audio", 4374e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean name, 4384e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean pDataFormat->mPCM.channelMask, 4394e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean pDataFormat->mPCM.numChannels); 4404e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 4414e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (pDataFormat->mPCM.channelMask == 0) { 4424e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // We can derive the channel mask from the channel count, 4434e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // but issue a warning--the automatic mask generation 4444e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // makes a lot of assumptions that may or may not be what 4454e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // the app was expecting. 4464e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SLuint32 mask = isOutputFormat 4474e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean ? sles_channel_out_mask_from_count(pDataFormat->mPCM.numChannels) 4484e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean : sles_channel_in_mask_from_count(pDataFormat->mPCM.numChannels); 4494e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (mask == SL_ANDROID_UNKNOWN_CHANNELMASK) { 4504e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_LOGE("No channel mask specified and no default mapping for" 4514e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean "requested speaker count of %u", pDataFormat->mPCM.numChannels); 45284bbadf848f606ff28273baf26fc246cf967059aAndy Hung result = SL_RESULT_PARAMETER_INVALID; 45384bbadf848f606ff28273baf26fc246cf967059aAndy Hung } else { 45484bbadf848f606ff28273baf26fc246cf967059aAndy Hung pDataFormat->mPCM.channelMask = mask; 4554e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_LOGW("No channel mask specified; Using mask %#x based on requested" 4564e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean "speaker count of %u", 4574e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean pDataFormat->mPCM.channelMask, 4584e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean pDataFormat->mPCM.numChannels); 45984bbadf848f606ff28273baf26fc246cf967059aAndy Hung } 4608db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 4614e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 4624e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SLuint32 mask = pDataFormat->mPCM.channelMask; 4634e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SLuint32 count = sles_channel_count_from_mask(mask); 4644e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (count != pDataFormat->mPCM.numChannels) { 4654e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_LOGE("%s: requested %d channels but mask (0x%x) has %d channel bits set", 4664e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean name, 4674e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean pDataFormat->mPCM.numChannels, 4684e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean mask, 4694e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean count); 4704e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean result = SL_RESULT_PARAMETER_INVALID; 4718db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 4728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 4738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 4744e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_LOGV("%s: final channel mask is 0x%x", name, pDataFormat->mPCM.channelMask); 4754e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 4768db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // check the endianness / byte order 4778db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten switch (pDataFormat->mPCM.endianness) { 4788db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_BYTEORDER_LITTLEENDIAN: 4798db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_BYTEORDER_BIGENDIAN: 4808db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 4818db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // native is proposed but not yet in spec 4828db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten default: 4838db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 4848db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 4858db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 4868db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (SL_RESULT_SUCCESS != result) { 4871d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness); 4888db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 4898db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 4908db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 4918db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // here if all checks passed successfully 4928db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 4938db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } while(0); 4948db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 4958db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 4968db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATAFORMAT_MIME: 4978db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat; 4988db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL != pDataFormat->mMIME.mimeType) { 4998db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // NTH check address for validity 5008db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten size_t len = strlen((const char *) pDataFormat->mMIME.mimeType); 5018db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten SLchar *myMIME = (SLchar *) malloc(len + 1); 5028db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL == myMIME) { 5038db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_MEMORY_FAILURE; 5048db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } else { 5058db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1); 5068db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // make sure MIME string was not modified asynchronously 5078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if ('\0' != myMIME[len]) { 5088db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten free(myMIME); 5098db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten myMIME = NULL; 5108db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 5118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 5128db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 5138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pDataFormat->mMIME.mimeType = myMIME; 5148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 5158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 5168db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 5178b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_DATAFORMAT_RAWIMAGE: 5188b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat; 5198b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten switch (pDataFormat->mRawImage.colorFormat) { 5208b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_MONOCHROME: 5218b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_8BITRGB332: 5228b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_12BITRGB444: 5238b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_16BITARGB4444: 5248b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_16BITARGB1555: 5258b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_16BITRGB565: 5268b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_16BITBGR565: 5278b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_18BITRGB666: 5288b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_18BITARGB1665: 5298b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_19BITARGB1666: 5308b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_24BITRGB888: 5318b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_24BITBGR888: 5328b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_24BITARGB1887: 5338b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_25BITARGB1888: 5348b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_32BITBGRA8888: 5358b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_32BITARGB8888: 5368b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_YUV411PLANAR: 5378b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_YUV420PLANAR: 5388b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_YUV420SEMIPLANAR: 5398b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_YUV422PLANAR: 5408b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_YUV422SEMIPLANAR: 5418b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_YCBYCR: 5428b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_YCRYCB: 5438b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_CBYCRY: 5448b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_CRYCBY: 5458b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_YUV444INTERLEAVED: 5468b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_RAWBAYER8BIT: 5478b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_RAWBAYER10BIT: 5488b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED: 5498b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_L2: 5508b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_L4: 5518b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_L8: 5528b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_L16: 5538b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_L24: 5548b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_L32: 5558b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_18BITBGR666: 5568b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_24BITARGB6666: 5578b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_24BITABGR6666: 5588b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 5598b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_COLORFORMAT_UNUSED: 5608b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten default: 5618b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten result = XA_RESULT_PARAMETER_INVALID; 562a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: unsupported color format %d", name, 5631d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten pDataFormat->mRawImage.colorFormat); 5648b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 5658b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 5668b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // no checks for height, width, or stride 5678b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 5688b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 5698db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten default: 5708db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 5711d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten SL_LOGE("%s: formatType=%u", name, (unsigned) formatType); 5728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 5738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 5748db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 5758db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 5768db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // make sure format type was not modified asynchronously 5778db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) { 578a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: formatType changed from %u to %u", name, formatType, 57994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataFormat->mFormatType); 5808db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 5818db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 5828db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 5838db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 5848db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 58594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // Verify that the data format type is allowed in this context 58694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (SL_RESULT_SUCCESS == result) { 58794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 actualMask; 58894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten switch (formatType) { 58994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATAFORMAT_NULL: 59094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATAFORMAT_MIME: 59194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATAFORMAT_PCM: 592e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case SL_ANDROID_DATAFORMAT_PCM_EX: 59394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case XA_DATAFORMAT_RAWIMAGE: 59494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten actualMask = 1L << formatType; 59594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 59694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten default: 59794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten assert(false); 59894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten actualMask = 0L; 59994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 60094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 60194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (!(allowedDataFormatMask & actualMask)) { 602a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGE("%s: data format %d not allowed", name, formatType); 60394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = SL_RESULT_CONTENT_UNSUPPORTED; 60494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 60594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 60694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 6078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return result; 6088db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 6098db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 6108db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 61113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi/** \brief Check interface ID compatibility with respect to a particular source 6127965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten * and sink data locator format 61313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi */ 6148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 6157965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn KastenSLresult checkSourceSinkVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat, 6167965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten const DataLocatorFormat *pSinkDataLocatorFormat, 61705c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten const ClassTable *clazz, unsigned requiredMask) { 6188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten int index; 61913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi switch (pSrcDataLocatorFormat->mLocator.mLocatorType) { 62013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi case SL_DATALOCATOR_URI: 62113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#ifdef ANDROID 62213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi case SL_DATALOCATOR_ANDROIDFD: 62313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#endif 62413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode 62513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // so we don't prevent the retrieval of the BufferQueue interfaces for those sources 6267965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten switch (pSinkDataLocatorFormat->mLocator.mLocatorType) { 6277965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 6287965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten#ifdef ANDROID 6297965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 6307965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten#endif 6317965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten break; 6327965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten default: 63305c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf 6347965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten // if the data sink is not a buffer queue 6357965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten index = clazz->mMPH_to_index[MPH_BUFFERQUEUE]; 6367965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten#ifdef ANDROID 6377965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]); 6387965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten#endif 6397965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten if (0 <= index) { 64005c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten if (requiredMask & (1 << index)) { 64105c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten SL_LOGE("can't require SL_IID_BUFFERQUEUE " 6427965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten#ifdef ANDROID 6437965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE " 6447965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten#endif 6457965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten "with a non-buffer queue data sink"); 6467965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 6477965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten } 6487965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten } 6497965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten break; 6507965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten } 65113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi break; 65213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi 6538db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 6548db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#ifdef ANDROID 6558db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 6568db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#endif 65705c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten // can't require SLSeekItf if data source is a buffer queue 658bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten index = clazz->mMPH_to_index[MPH_SEEK]; 6598db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (0 <= index) { 66005c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten if (requiredMask & (1 << index)) { 66105c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten SL_LOGE("can't require SL_IID_SEEK with a buffer queue data source"); 6628db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 6638db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 6648db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 66505c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten // can't require SLMuteSoloItf if data source is a mono buffer queue 666bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten index = clazz->mMPH_to_index[MPH_MUTESOLO]; 6678db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (0 <= index) { 66805c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten if ((requiredMask & (1 << index)) && 66913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) && 67013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) { 67105c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten SL_LOGE("can't require SL_IID_MUTESOLO with a mono buffer queue data source"); 6728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 6738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 6748db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 6758db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 67613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi 6778b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten#ifdef ANDROID 6788b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 679779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi // can't require SLSeekItf if data source is an Android buffer queue 680779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi index = clazz->mMPH_to_index[MPH_SEEK]; 681779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi if (0 <= index) { 682779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi if (requiredMask & (1 << index)) { 683779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi SL_LOGE("can't require SL_IID_SEEK with a SL_DATALOCATOR_ANDROIDBUFFERQUEUE "\ 684779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi "source"); 685779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi return SL_RESULT_FEATURE_UNSUPPORTED; 686779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi } 687779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi } 688bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi switch (pSinkDataLocatorFormat->mLocator.mLocatorType) { 689779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi // for use-case AAC decode from SLAndroidBufferQueueItf with AAC ADTS data 690bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi case SL_DATALOCATOR_BUFFERQUEUE: 691bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 692bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi break; 693779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi // for use-case audio playback from SLAndroidBufferQueueItf with MP2TS data 694779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi case SL_DATALOCATOR_OUTPUTMIX: 695779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi break; 696bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi default: 697779a533785a4b8d2521123bc3c0a035b93ba078dJean-Michel Trivi SL_LOGE("Invalid sink for SL_DATALOCATOR_ANDROIDBUFFERQUEUE source"); 698bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi return SL_RESULT_FEATURE_UNSUPPORTED; 699bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi break; 700bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 701bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi break; 7028b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten#endif 7038b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATALOCATOR_ADDRESS: 7048b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 7058b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_DATALOCATOR_NATIVEDISPLAY: 7068b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // any special checks here??? 7078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten default: 70805c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf 7098db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // if the data source is not a buffer queue 710bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten index = clazz->mMPH_to_index[MPH_BUFFERQUEUE]; 7118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#ifdef ANDROID 712bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]); 7138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#endif 7148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (0 <= index) { 71505c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten if (requiredMask & (1 << index)) { 71605c7b2d09d54b9260ff7f3f5e491f38d0097c406Glenn Kasten SL_LOGE("can't require SL_IID_BUFFERQUEUE " 7178db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#ifdef ANDROID 7188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE " 7198db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#endif 7208db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten "with a non-buffer queue data source"); 7218db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 7228db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 7238db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 7248db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 7258db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 7268db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return SL_RESULT_SUCCESS; 7278db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 7288db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 7298db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 7308db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** \brief Free the local deep copy of a data format */ 7318db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 7328db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic void freeDataFormat(DataFormat *pDataFormat) 7338db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 7348db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten switch (pDataFormat->mFormatType) { 7358db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATAFORMAT_MIME: 7368db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL != pDataFormat->mMIME.mimeType) { 7378db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten free(pDataFormat->mMIME.mimeType); 7388db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pDataFormat->mMIME.mimeType = NULL; 7398db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 7408db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 741e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung case SL_ANDROID_DATAFORMAT_PCM_EX: 7428b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATAFORMAT_PCM: 7438b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_DATAFORMAT_RAWIMAGE: 7448b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATAFORMAT_NULL: 7458b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 7468db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten default: 7478b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // an invalid data format is caught earlier during the copy 7488b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten assert(false); 7498db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 7508db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 7518db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 7528db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 7538db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 7548db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** \brief Check a data source and make local deep copy */ 7558db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 75694a37e8117fb72790882dfb815f99e2365754c74Glenn KastenSLresult checkDataSource(const char *name, const SLDataSource *pDataSrc, 75794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 75894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 allowedDataFormatMask) 7598db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 76094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten assert(NULL != name && NULL != pDataLocatorFormat); 76194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 76294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 76394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 7648db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL == pDataSrc) { 76594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 76694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 76794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 76894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 76994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten return SL_RESULT_SUCCESS; 77094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 7711d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten SL_LOGE("%s: data source cannot be NULL", name); 7728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 7738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 7748db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten SLDataSource myDataSrc = *pDataSrc; 7758db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten SLresult result; 77694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator, 77794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataLocatorMask); 7788db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (SL_RESULT_SUCCESS != result) { 7798db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return result; 7808db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 7818db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 78294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten switch (pDataLocatorFormat->mLocator.mLocatorType) { 7838db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_URI: 78494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 78594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 7868db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_ADDRESS: 7878db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 788e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX; 78994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 790e670554ea199eef745740eaccc176ff283b0cd10Glenn Kasten // Per the spec, the pFormat field is ignored in some cases 79194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_IODEVICE: 792e670554ea199eef745740eaccc176ff283b0cd10Glenn Kasten myDataSrc.pFormat = NULL; 793e670554ea199eef745740eaccc176ff283b0cd10Glenn Kasten // fall through 794e670554ea199eef745740eaccc176ff283b0cd10Glenn Kasten case SL_DATALOCATOR_NULL: 7958db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 79694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 79794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 79894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 79994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case XA_DATALOCATOR_NATIVEDISPLAY: 80094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask = DATAFORMAT_MASK_NONE; 80194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 8028db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#ifdef ANDROID 8038db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_ANDROIDFD: 80494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 80594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 8068db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 807e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX; 80894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 809fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 810c869defb7c0dd6f4e45ad26abb0f8ccc960152deJean-Michel Trivi allowedDataFormatMask &= DATAFORMAT_MASK_MIME;; 8118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 81294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 8138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten default: 81494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // invalid data locator type is caught earlier 81594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten assert(false); 81694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask = DATAFORMAT_MASK_NONE; 8178b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 8188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 8198db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 8204e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean result = checkDataFormat(name, 8214e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean myDataSrc.pFormat, 8224e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean &pDataLocatorFormat->mFormat, 8234e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean allowedDataFormatMask, 8244e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_BOOLEAN_TRUE /*isOutputFormat*/); 82594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (SL_RESULT_SUCCESS != result) { 82694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 82794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten return result; 82894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 82994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 8308db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return SL_RESULT_SUCCESS; 8318db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 8328db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 8338db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 8348db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** \brief Check a data sink and make local deep copy */ 8358db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 83694a37e8117fb72790882dfb815f99e2365754c74Glenn KastenSLresult checkDataSink(const char *name, const SLDataSink *pDataSink, 83794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 83894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten SLuint32 allowedDataFormatMask) 8398db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 84094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten assert(NULL != name && NULL != pDataLocatorFormat); 84194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 84294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 84394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 8448db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL == pDataSink) { 84594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 84694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 84794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 84894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 84994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten return SL_RESULT_SUCCESS; 85094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 8511d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten SL_LOGE("%s: data sink cannot be NULL", name); 8528db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 8538db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 8548db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten SLDataSink myDataSink = *pDataSink; 8558db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten SLresult result; 85694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator, 85794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataLocatorMask); 8588db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (SL_RESULT_SUCCESS != result) { 8598db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return result; 8608db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 8618db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 86294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten switch (pDataLocatorFormat->mLocator.mLocatorType) { 8638db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_URI: 86494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 8658db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 86694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ADDRESS: 8678db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 868e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX; 8698db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten break; 870e670554ea199eef745740eaccc176ff283b0cd10Glenn Kasten // Per the spec, the pFormat field is ignored in some cases 8718db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_IODEVICE: 8728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 8738b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case XA_DATALOCATOR_NATIVEDISPLAY: 874e670554ea199eef745740eaccc176ff283b0cd10Glenn Kasten myDataSink.pFormat = NULL; 875e670554ea199eef745740eaccc176ff283b0cd10Glenn Kasten // fall through 876e670554ea199eef745740eaccc176ff283b0cd10Glenn Kasten case SL_DATALOCATOR_NULL: 877e670554ea199eef745740eaccc176ff283b0cd10Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 87894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 8798b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 8808b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten#ifdef ANDROID 88194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ANDROIDFD: 88294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask = DATAFORMAT_MASK_NONE; 88394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 88494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 885e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX; 88694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 8878b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 88894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask = DATAFORMAT_MASK_NONE; 8898b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 8908b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten#endif 89194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten default: 89294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten // invalid data locator type is caught earlier 89394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten assert(false); 89494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten allowedDataFormatMask = DATAFORMAT_MASK_NONE; 89594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten break; 89694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten } 89794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 8984e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean result = checkDataFormat(name, 8994e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean myDataSink.pFormat, 9004e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean &pDataLocatorFormat->mFormat, 9014e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean allowedDataFormatMask, 9024e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_BOOLEAN_FALSE /*isOutputFormat*/); 9034e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 90494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten if (SL_RESULT_SUCCESS != result) { 90594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten freeDataLocator(&pDataLocatorFormat->mLocator); 90694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten return result; 9078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 9088db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9098db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return SL_RESULT_SUCCESS; 9108db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 9118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9128db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** \brief Free the local deep copy of a data locator format */ 9148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenvoid freeDataLocatorFormat(DataLocatorFormat *dlf) 9168db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 91794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten assert(NULL != dlf); 9188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten freeDataLocator(&dlf->mLocator); 9198db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten freeDataFormat(&dlf->mFormat); 9208db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 921