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 #define SL_ANDROID_SPEAKER_QUAD (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \
336 | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT)
337
338 #define SL_ANDROID_SPEAKER_5DOT1 (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \
339 | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY| SL_SPEAKER_BACK_LEFT \
340 | SL_SPEAKER_BACK_RIGHT)
341
342 #define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT \
343 |SL_SPEAKER_SIDE_RIGHT)
344
checkDataFormat(const char * name,void * pFormat,DataFormat * pDataFormat,SLuint32 allowedDataFormatMask)345 static SLresult checkDataFormat(const char *name, void *pFormat, DataFormat *pDataFormat,
346 SLuint32 allowedDataFormatMask)
347 {
348 assert(NULL != name && NULL != pDataFormat);
349 SLresult result = SL_RESULT_SUCCESS;
350 const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists
351 SLuint32 formatType;
352 if (NULL == pFormat) {
353 pDataFormat->mFormatType = formatType = SL_DATAFORMAT_NULL;
354 } else {
355 formatType = *(SLuint32 *)pFormat;
356 switch (formatType) {
357 case SL_ANDROID_DATAFORMAT_PCM_EX:
358 pDataFormat->mPCMEx.representation =
359 ((SLAndroidDataFormat_PCM_EX *)pFormat)->representation;
360 switch (pDataFormat->mPCMEx.representation) {
361 case SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT:
362 case SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT:
363 case SL_ANDROID_PCM_REPRESENTATION_FLOAT:
364 df_representation = &pDataFormat->mPCMEx.representation;
365 break;
366 default:
367 SL_LOGE("%s: unsupported representation: %d", name,
368 pDataFormat->mPCMEx.representation);
369 result = SL_RESULT_PARAMETER_INVALID;
370 break;
371 }
372 // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test.
373 case SL_DATAFORMAT_PCM:
374 pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat;
375 do {
376
377 // check the channel count
378 switch (pDataFormat->mPCM.numChannels) {
379 case 1: // mono
380 case 2: // stereo
381 case 4: // QUAD
382 case 6: // 5.1
383 case 8: // 8.1
384 break;
385 case 0: // unknown
386 result = SL_RESULT_PARAMETER_INVALID;
387 break;
388 default: // multi-channel
389 result = SL_RESULT_CONTENT_UNSUPPORTED;
390 break;
391 }
392 if (SL_RESULT_SUCCESS != result) {
393 SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels);
394 break;
395 }
396
397 // check the sampling rate
398 switch (pDataFormat->mPCM.samplesPerSec) {
399 case SL_SAMPLINGRATE_8:
400 case SL_SAMPLINGRATE_11_025:
401 case SL_SAMPLINGRATE_12:
402 case SL_SAMPLINGRATE_16:
403 case SL_SAMPLINGRATE_22_05:
404 case SL_SAMPLINGRATE_24:
405 case SL_SAMPLINGRATE_32:
406 case SL_SAMPLINGRATE_44_1:
407 case SL_SAMPLINGRATE_48:
408 case SL_SAMPLINGRATE_64:
409 case SL_SAMPLINGRATE_88_2:
410 case SL_SAMPLINGRATE_96:
411 case SL_SAMPLINGRATE_192:
412 break;
413 case 0:
414 result = SL_RESULT_PARAMETER_INVALID;
415 break;
416 default:
417 result = SL_RESULT_CONTENT_UNSUPPORTED;
418 break;
419 }
420 if (SL_RESULT_SUCCESS != result) {
421 SL_LOGE("%s: samplesPerSec=%u", name, pDataFormat->mPCM.samplesPerSec);
422 break;
423 }
424
425 // check the container bit depth
426 switch (pDataFormat->mPCM.containerSize) {
427 case 8:
428 if (df_representation &&
429 *df_representation != SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT) {
430 result = SL_RESULT_PARAMETER_INVALID;
431 }
432 break;
433 case 16:
434 case 24:
435 if (df_representation &&
436 *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT) {
437 result = SL_RESULT_PARAMETER_INVALID;
438 }
439 break;
440 case 32:
441 if (df_representation
442 && *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT
443 && *df_representation != SL_ANDROID_PCM_REPRESENTATION_FLOAT) {
444 result = SL_RESULT_PARAMETER_INVALID;
445 }
446 break;
447 default:
448 result = SL_RESULT_PARAMETER_INVALID;
449 break;
450 }
451 if (SL_RESULT_SUCCESS != result) {
452 SL_LOGE("%s: containerSize=%u", name, pDataFormat->mPCM.containerSize);
453 break;
454 }
455
456 // container size cannot be less than sample size
457 if (pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) {
458 result = SL_RESULT_PARAMETER_INVALID;
459 }
460 if (SL_RESULT_SUCCESS != result) {
461 SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name,
462 (unsigned) pDataFormat->mPCM.containerSize,
463 (unsigned) pDataFormat->mPCM.bitsPerSample);
464 break;
465 }
466
467 // check the channel mask
468 switch (pDataFormat->mPCM.channelMask) {
469 case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT:
470 if (2 != pDataFormat->mPCM.numChannels) {
471 result = SL_RESULT_PARAMETER_INVALID;
472 }
473 break;
474 case SL_SPEAKER_FRONT_LEFT:
475 case SL_SPEAKER_FRONT_RIGHT:
476 case SL_SPEAKER_FRONT_CENTER:
477 if (1 != pDataFormat->mPCM.numChannels) {
478 result = SL_RESULT_PARAMETER_INVALID;
479 }
480 break;
481 case SL_ANDROID_SPEAKER_QUAD:
482 if (4 != pDataFormat->mPCM.numChannels) {
483 result = SL_RESULT_PARAMETER_INVALID;
484 }
485 break;
486 case SL_ANDROID_SPEAKER_5DOT1:
487 if (6 != 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 case 0:
497 // The default of front left rather than center for mono may be non-intuitive,
498 // but the left channel is the first channel for stereo or multichannel content.
499 pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ?
500 SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_LEFT;
501 break;
502 default:
503 result = SL_RESULT_PARAMETER_INVALID;
504 break;
505 }
506 if (SL_RESULT_SUCCESS != result) {
507 SL_LOGE("%s: channelMask=0x%x numChannels=%u", name,
508 pDataFormat->mPCM.channelMask, pDataFormat->mPCM.numChannels);
509 break;
510 }
511
512 // check the endianness / byte order
513 switch (pDataFormat->mPCM.endianness) {
514 case SL_BYTEORDER_LITTLEENDIAN:
515 case SL_BYTEORDER_BIGENDIAN:
516 break;
517 // native is proposed but not yet in spec
518 default:
519 result = SL_RESULT_PARAMETER_INVALID;
520 break;
521 }
522 if (SL_RESULT_SUCCESS != result) {
523 SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness);
524 break;
525 }
526
527 // here if all checks passed successfully
528
529 } while(0);
530 break;
531
532 case SL_DATAFORMAT_MIME:
533 pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat;
534 if (NULL != pDataFormat->mMIME.mimeType) {
535 // NTH check address for validity
536 size_t len = strlen((const char *) pDataFormat->mMIME.mimeType);
537 SLchar *myMIME = (SLchar *) malloc(len + 1);
538 if (NULL == myMIME) {
539 result = SL_RESULT_MEMORY_FAILURE;
540 } else {
541 memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1);
542 // make sure MIME string was not modified asynchronously
543 if ('\0' != myMIME[len]) {
544 free(myMIME);
545 myMIME = NULL;
546 result = SL_RESULT_PRECONDITIONS_VIOLATED;
547 }
548 }
549 pDataFormat->mMIME.mimeType = myMIME;
550 }
551 break;
552
553 case XA_DATAFORMAT_RAWIMAGE:
554 pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat;
555 switch (pDataFormat->mRawImage.colorFormat) {
556 case XA_COLORFORMAT_MONOCHROME:
557 case XA_COLORFORMAT_8BITRGB332:
558 case XA_COLORFORMAT_12BITRGB444:
559 case XA_COLORFORMAT_16BITARGB4444:
560 case XA_COLORFORMAT_16BITARGB1555:
561 case XA_COLORFORMAT_16BITRGB565:
562 case XA_COLORFORMAT_16BITBGR565:
563 case XA_COLORFORMAT_18BITRGB666:
564 case XA_COLORFORMAT_18BITARGB1665:
565 case XA_COLORFORMAT_19BITARGB1666:
566 case XA_COLORFORMAT_24BITRGB888:
567 case XA_COLORFORMAT_24BITBGR888:
568 case XA_COLORFORMAT_24BITARGB1887:
569 case XA_COLORFORMAT_25BITARGB1888:
570 case XA_COLORFORMAT_32BITBGRA8888:
571 case XA_COLORFORMAT_32BITARGB8888:
572 case XA_COLORFORMAT_YUV411PLANAR:
573 case XA_COLORFORMAT_YUV420PLANAR:
574 case XA_COLORFORMAT_YUV420SEMIPLANAR:
575 case XA_COLORFORMAT_YUV422PLANAR:
576 case XA_COLORFORMAT_YUV422SEMIPLANAR:
577 case XA_COLORFORMAT_YCBYCR:
578 case XA_COLORFORMAT_YCRYCB:
579 case XA_COLORFORMAT_CBYCRY:
580 case XA_COLORFORMAT_CRYCBY:
581 case XA_COLORFORMAT_YUV444INTERLEAVED:
582 case XA_COLORFORMAT_RAWBAYER8BIT:
583 case XA_COLORFORMAT_RAWBAYER10BIT:
584 case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED:
585 case XA_COLORFORMAT_L2:
586 case XA_COLORFORMAT_L4:
587 case XA_COLORFORMAT_L8:
588 case XA_COLORFORMAT_L16:
589 case XA_COLORFORMAT_L24:
590 case XA_COLORFORMAT_L32:
591 case XA_COLORFORMAT_18BITBGR666:
592 case XA_COLORFORMAT_24BITARGB6666:
593 case XA_COLORFORMAT_24BITABGR6666:
594 break;
595 case XA_COLORFORMAT_UNUSED:
596 default:
597 result = XA_RESULT_PARAMETER_INVALID;
598 SL_LOGE("%s: unsupported color format %d", name,
599 pDataFormat->mRawImage.colorFormat);
600 break;
601 }
602 // no checks for height, width, or stride
603 break;
604
605 default:
606 result = SL_RESULT_PARAMETER_INVALID;
607 SL_LOGE("%s: formatType=%u", name, (unsigned) formatType);
608 break;
609
610 }
611
612 // make sure format type was not modified asynchronously
613 if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) {
614 SL_LOGE("%s: formatType changed from %u to %u", name, formatType,
615 pDataFormat->mFormatType);
616 result = SL_RESULT_PRECONDITIONS_VIOLATED;
617 }
618
619 }
620
621 // Verify that the data format type is allowed in this context
622 if (SL_RESULT_SUCCESS == result) {
623 SLuint32 actualMask;
624 switch (formatType) {
625 case SL_DATAFORMAT_NULL:
626 case SL_DATAFORMAT_MIME:
627 case SL_DATAFORMAT_PCM:
628 case SL_ANDROID_DATAFORMAT_PCM_EX:
629 case XA_DATAFORMAT_RAWIMAGE:
630 actualMask = 1L << formatType;
631 break;
632 default:
633 assert(false);
634 actualMask = 0L;
635 break;
636 }
637 if (!(allowedDataFormatMask & actualMask)) {
638 SL_LOGE("%s: data format %d not allowed", name, formatType);
639 result = SL_RESULT_CONTENT_UNSUPPORTED;
640 }
641 }
642
643 return result;
644 }
645
646
647 /** \brief Check interface ID compatibility with respect to a particular source
648 * and sink data locator format
649 */
650
checkSourceSinkVsInterfacesCompatibility(const DataLocatorFormat * pSrcDataLocatorFormat,const DataLocatorFormat * pSinkDataLocatorFormat,const ClassTable * clazz,unsigned requiredMask)651 SLresult checkSourceSinkVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat,
652 const DataLocatorFormat *pSinkDataLocatorFormat,
653 const ClassTable *clazz, unsigned requiredMask) {
654 int index;
655 switch (pSrcDataLocatorFormat->mLocator.mLocatorType) {
656 case SL_DATALOCATOR_URI:
657 #ifdef ANDROID
658 case SL_DATALOCATOR_ANDROIDFD:
659 #endif
660 // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode
661 // so we don't prevent the retrieval of the BufferQueue interfaces for those sources
662 switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
663 case SL_DATALOCATOR_BUFFERQUEUE:
664 #ifdef ANDROID
665 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
666 #endif
667 break;
668 default:
669 // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
670 // if the data sink is not a buffer queue
671 index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
672 #ifdef ANDROID
673 assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
674 #endif
675 if (0 <= index) {
676 if (requiredMask & (1 << index)) {
677 SL_LOGE("can't require SL_IID_BUFFERQUEUE "
678 #ifdef ANDROID
679 "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
680 #endif
681 "with a non-buffer queue data sink");
682 return SL_RESULT_FEATURE_UNSUPPORTED;
683 }
684 }
685 break;
686 }
687 break;
688
689 case SL_DATALOCATOR_BUFFERQUEUE:
690 #ifdef ANDROID
691 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
692 #endif
693 // can't require SLSeekItf if data source is a buffer queue
694 index = clazz->mMPH_to_index[MPH_SEEK];
695 if (0 <= index) {
696 if (requiredMask & (1 << index)) {
697 SL_LOGE("can't require SL_IID_SEEK with a buffer queue data source");
698 return SL_RESULT_FEATURE_UNSUPPORTED;
699 }
700 }
701 // can't require SLMuteSoloItf if data source is a mono buffer queue
702 index = clazz->mMPH_to_index[MPH_MUTESOLO];
703 if (0 <= index) {
704 if ((requiredMask & (1 << index)) &&
705 (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) &&
706 (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) {
707 SL_LOGE("can't require SL_IID_MUTESOLO with a mono buffer queue data source");
708 return SL_RESULT_FEATURE_UNSUPPORTED;
709 }
710 }
711 break;
712
713 #ifdef ANDROID
714 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
715 // can't require SLSeekItf if data source is an Android buffer queue
716 index = clazz->mMPH_to_index[MPH_SEEK];
717 if (0 <= index) {
718 if (requiredMask & (1 << index)) {
719 SL_LOGE("can't require SL_IID_SEEK with a SL_DATALOCATOR_ANDROIDBUFFERQUEUE "\
720 "source");
721 return SL_RESULT_FEATURE_UNSUPPORTED;
722 }
723 }
724 switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
725 // for use-case AAC decode from SLAndroidBufferQueueItf with AAC ADTS data
726 case SL_DATALOCATOR_BUFFERQUEUE:
727 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
728 break;
729 // for use-case audio playback from SLAndroidBufferQueueItf with MP2TS data
730 case SL_DATALOCATOR_OUTPUTMIX:
731 break;
732 default:
733 SL_LOGE("Invalid sink for SL_DATALOCATOR_ANDROIDBUFFERQUEUE source");
734 return SL_RESULT_FEATURE_UNSUPPORTED;
735 break;
736 }
737 break;
738 #endif
739 case SL_DATALOCATOR_ADDRESS:
740 case SL_DATALOCATOR_MIDIBUFFERQUEUE:
741 case XA_DATALOCATOR_NATIVEDISPLAY:
742 // any special checks here???
743 default:
744 // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
745 // if the data source is not a buffer queue
746 index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
747 #ifdef ANDROID
748 assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
749 #endif
750 if (0 <= index) {
751 if (requiredMask & (1 << index)) {
752 SL_LOGE("can't require SL_IID_BUFFERQUEUE "
753 #ifdef ANDROID
754 "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
755 #endif
756 "with a non-buffer queue data source");
757 return SL_RESULT_FEATURE_UNSUPPORTED;
758 }
759 }
760 break;
761 }
762 return SL_RESULT_SUCCESS;
763 }
764
765
766 /** \brief Free the local deep copy of a data format */
767
freeDataFormat(DataFormat * pDataFormat)768 static void freeDataFormat(DataFormat *pDataFormat)
769 {
770 switch (pDataFormat->mFormatType) {
771 case SL_DATAFORMAT_MIME:
772 if (NULL != pDataFormat->mMIME.mimeType) {
773 free(pDataFormat->mMIME.mimeType);
774 pDataFormat->mMIME.mimeType = NULL;
775 }
776 break;
777 case SL_ANDROID_DATAFORMAT_PCM_EX:
778 case SL_DATAFORMAT_PCM:
779 case XA_DATAFORMAT_RAWIMAGE:
780 case SL_DATAFORMAT_NULL:
781 break;
782 default:
783 // an invalid data format is caught earlier during the copy
784 assert(false);
785 break;
786 }
787 }
788
789
790 /** \brief Check a data source and make local deep copy */
791
checkDataSource(const char * name,const SLDataSource * pDataSrc,DataLocatorFormat * pDataLocatorFormat,SLuint32 allowedDataLocatorMask,SLuint32 allowedDataFormatMask)792 SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc,
793 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
794 SLuint32 allowedDataFormatMask)
795 {
796 assert(NULL != name && NULL != pDataLocatorFormat);
797 pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator;
798 pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat;
799
800 if (NULL == pDataSrc) {
801 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
802 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
803 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
804 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
805 return SL_RESULT_SUCCESS;
806 }
807 SL_LOGE("%s: data source cannot be NULL", name);
808 return SL_RESULT_PARAMETER_INVALID;
809 }
810 SLDataSource myDataSrc = *pDataSrc;
811 SLresult result;
812 result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator,
813 allowedDataLocatorMask);
814 if (SL_RESULT_SUCCESS != result) {
815 return result;
816 }
817
818 switch (pDataLocatorFormat->mLocator.mLocatorType) {
819 case SL_DATALOCATOR_URI:
820 allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
821 break;
822 case SL_DATALOCATOR_ADDRESS:
823 case SL_DATALOCATOR_BUFFERQUEUE:
824 allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
825 break;
826 // Per the spec, the pFormat field is ignored in some cases
827 case SL_DATALOCATOR_IODEVICE:
828 myDataSrc.pFormat = NULL;
829 // fall through
830 case SL_DATALOCATOR_NULL:
831 case SL_DATALOCATOR_MIDIBUFFERQUEUE:
832 allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
833 break;
834 case SL_DATALOCATOR_OUTPUTMIX:
835 case XA_DATALOCATOR_NATIVEDISPLAY:
836 allowedDataFormatMask = DATAFORMAT_MASK_NONE;
837 break;
838 #ifdef ANDROID
839 case SL_DATALOCATOR_ANDROIDFD:
840 allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
841 break;
842 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
843 allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
844 break;
845 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
846 allowedDataFormatMask &= DATAFORMAT_MASK_MIME;;
847 break;
848 #endif
849 default:
850 // invalid data locator type is caught earlier
851 assert(false);
852 allowedDataFormatMask = DATAFORMAT_MASK_NONE;
853 break;
854 }
855
856 result = checkDataFormat(name, myDataSrc.pFormat, &pDataLocatorFormat->mFormat,
857 allowedDataFormatMask);
858 if (SL_RESULT_SUCCESS != result) {
859 freeDataLocator(&pDataLocatorFormat->mLocator);
860 return result;
861 }
862
863 return SL_RESULT_SUCCESS;
864 }
865
866
867 /** \brief Check a data sink and make local deep copy */
868
checkDataSink(const char * name,const SLDataSink * pDataSink,DataLocatorFormat * pDataLocatorFormat,SLuint32 allowedDataLocatorMask,SLuint32 allowedDataFormatMask)869 SLresult checkDataSink(const char *name, const SLDataSink *pDataSink,
870 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
871 SLuint32 allowedDataFormatMask)
872 {
873 assert(NULL != name && NULL != pDataLocatorFormat);
874 pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator;
875 pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat;
876
877 if (NULL == pDataSink) {
878 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
879 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
880 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
881 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
882 return SL_RESULT_SUCCESS;
883 }
884 SL_LOGE("%s: data sink cannot be NULL", name);
885 return SL_RESULT_PARAMETER_INVALID;
886 }
887 SLDataSink myDataSink = *pDataSink;
888 SLresult result;
889 result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator,
890 allowedDataLocatorMask);
891 if (SL_RESULT_SUCCESS != result) {
892 return result;
893 }
894
895 switch (pDataLocatorFormat->mLocator.mLocatorType) {
896 case SL_DATALOCATOR_URI:
897 allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
898 break;
899 case SL_DATALOCATOR_ADDRESS:
900 case SL_DATALOCATOR_BUFFERQUEUE:
901 allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
902 break;
903 // Per the spec, the pFormat field is ignored in some cases
904 case SL_DATALOCATOR_IODEVICE:
905 case SL_DATALOCATOR_OUTPUTMIX:
906 case XA_DATALOCATOR_NATIVEDISPLAY:
907 myDataSink.pFormat = NULL;
908 // fall through
909 case SL_DATALOCATOR_NULL:
910 case SL_DATALOCATOR_MIDIBUFFERQUEUE:
911 allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
912 break;
913 #ifdef ANDROID
914 case SL_DATALOCATOR_ANDROIDFD:
915 allowedDataFormatMask = DATAFORMAT_MASK_NONE;
916 break;
917 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
918 allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
919 break;
920 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
921 allowedDataFormatMask = DATAFORMAT_MASK_NONE;
922 break;
923 #endif
924 default:
925 // invalid data locator type is caught earlier
926 assert(false);
927 allowedDataFormatMask = DATAFORMAT_MASK_NONE;
928 break;
929 }
930
931 result = checkDataFormat(name, myDataSink.pFormat, &pDataLocatorFormat->mFormat,
932 allowedDataFormatMask);
933 if (SL_RESULT_SUCCESS != result) {
934 freeDataLocator(&pDataLocatorFormat->mLocator);
935 return result;
936 }
937
938 return SL_RESULT_SUCCESS;
939 }
940
941
942 /** \brief Free the local deep copy of a data locator format */
943
freeDataLocatorFormat(DataLocatorFormat * dlf)944 void freeDataLocatorFormat(DataLocatorFormat *dlf)
945 {
946 assert(NULL != dlf);
947 freeDataLocator(&dlf->mLocator);
948 freeDataFormat(&dlf->mFormat);
949 }
950