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