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