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