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