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