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