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