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