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
27static 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
295static 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
339static 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
662SLresult 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
779static 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
803SLresult 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
880SLresult 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
955void freeDataLocatorFormat(DataLocatorFormat *dlf)
956{
957    assert(NULL != dlf);
958    freeDataLocator(&dlf->mLocator);
959    freeDataFormat(&dlf->mFormat);
960}
961