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