data.c revision e57c13397185f9ad0f162855e9a8ebeb0c94bfc4
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
24static 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
292static 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
345static 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
651SLresult 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
768static 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
792SLresult 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
869SLresult 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
944void freeDataLocatorFormat(DataLocatorFormat *dlf)
945{
946    assert(NULL != dlf);
947    freeDataLocator(&dlf->mLocator);
948    freeDataFormat(&dlf->mFormat);
949}
950