data.c revision ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8
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=%lu", 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=%lu", 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=%lu", 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=%lu", 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=%lu", 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=%lu", 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=%lu 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=%ld", 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            // if hDisplay is NULL, then hWindow is NDK C ANativeWindow *
174            // if hDisplay is non-NULL, then:
175            //   hWindow is JNI jobject Surface or SurfaceTexture
176            //   hDisplay is JNIENV *
177            if (pDataLocator->mNativeDisplay.hWindow == NULL) {
178                SL_LOGE("%s: hWindow must be non-NULL", name);
179                result = SL_RESULT_PARAMETER_INVALID;
180            }
181            break;
182
183        case SL_DATALOCATOR_URI:
184            {
185            pDataLocator->mURI = *(SLDataLocator_URI *)pLocator;
186            if (NULL == pDataLocator->mURI.URI) {
187                SL_LOGE("%s: invalid URI=NULL", name);
188                result = SL_RESULT_PARAMETER_INVALID;
189            }
190            // NTH verify URI address for validity
191            size_t len = strlen((const char *) pDataLocator->mURI.URI);
192            SLchar *myURI = (SLchar *) malloc(len + 1);
193            if (NULL == myURI) {
194                result = SL_RESULT_MEMORY_FAILURE;
195            } else {
196                memcpy(myURI, pDataLocator->mURI.URI, len + 1);
197                // Verify that another thread didn't change the NUL-terminator after we used it
198                // to determine length of string to copy. It's OK if the string became shorter.
199                if ('\0' != myURI[len]) {
200                    free(myURI);
201                    myURI = NULL;
202                    result = SL_RESULT_PARAMETER_INVALID;
203                }
204            }
205            pDataLocator->mURI.URI = myURI;
206            }
207            break;
208
209#ifdef ANDROID
210        case SL_DATALOCATOR_ANDROIDFD:
211        {
212            pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator;
213            SL_LOGV("%s: fd=%ld offset=%lld length=%lld", name, pDataLocator->mFD.fd,
214                    pDataLocator->mFD.offset, pDataLocator->mFD.length);
215            // NTH check against process fd limit
216            if (0 > pDataLocator->mFD.fd) {
217                SL_LOGE("%s: fd=%ld\n", name, pDataLocator->mFD.fd);
218                result = SL_RESULT_PARAMETER_INVALID;
219            }
220            break;
221        }
222        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
223        {
224            pDataLocator->mABQ = *(SLDataLocator_AndroidBufferQueue*)pLocator;
225            // number of buffers must be specified, there is no default value, and can't be too big
226            if (!((1 <= pDataLocator->mBufferQueue.numBuffers) &&
227                    (pDataLocator->mBufferQueue.numBuffers <= 255))) {
228                SL_LOGE("%s: numBuffers=%lu", name, pDataLocator->mABQ.numBuffers);
229                result = SL_RESULT_PARAMETER_INVALID;
230            }
231            break;
232        }
233#endif
234
235        case SL_DATALOCATOR_NULL:   // a NULL pointer is allowed, but not a pointer to NULL
236        default:
237            SL_LOGE("%s: locatorType=%lu", name, locatorType);
238            result = SL_RESULT_PARAMETER_INVALID;
239        }
240
241        // Verify that another thread didn't change the locatorType field after we used it
242        // to determine sizeof struct to copy.
243        if ((SL_RESULT_SUCCESS == result) && (locatorType != pDataLocator->mLocatorType)) {
244            SL_LOGE("%s: locatorType changed from %lu to %lu", name, locatorType,
245                    pDataLocator->mLocatorType);
246            result = SL_RESULT_PRECONDITIONS_VIOLATED;
247        }
248
249    }
250
251    // Verify that the data locator type is allowed in this context
252    if (SL_RESULT_SUCCESS == result) {
253        SLuint32 actualMask;
254        switch (locatorType) {
255        case SL_DATALOCATOR_NULL:
256        case SL_DATALOCATOR_URI:
257        case SL_DATALOCATOR_ADDRESS:
258        case SL_DATALOCATOR_IODEVICE:
259        case SL_DATALOCATOR_OUTPUTMIX:
260        case XA_DATALOCATOR_NATIVEDISPLAY:
261        case SL_DATALOCATOR_BUFFERQUEUE:
262        case SL_DATALOCATOR_MIDIBUFFERQUEUE:
263            actualMask = 1L << locatorType;
264            break;
265#ifdef ANDROID
266        case SL_DATALOCATOR_ANDROIDFD:
267        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
268        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
269            actualMask = 0x100L << (locatorType - SL_DATALOCATOR_ANDROIDFD);
270            break;
271#endif
272        default:
273            assert(false);
274            actualMask = 0L;
275            break;
276        }
277        if (!(allowedDataLocatorMask & actualMask)) {
278            SL_LOGE("%s: data locator type 0x%lx not allowed", name, locatorType);
279            result = SL_RESULT_CONTENT_UNSUPPORTED;
280        }
281    }
282
283    return result;
284}
285
286
287/** \brief Free the local deep copy of a data locator */
288
289static void freeDataLocator(DataLocator *pDataLocator)
290{
291    switch (pDataLocator->mLocatorType) {
292    case SL_DATALOCATOR_NULL:
293    case SL_DATALOCATOR_ADDRESS:
294    case SL_DATALOCATOR_BUFFERQUEUE:
295    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
296    case XA_DATALOCATOR_NATIVEDISPLAY:
297        break;
298    case SL_DATALOCATOR_URI:
299        if (NULL != pDataLocator->mURI.URI) {
300            free(pDataLocator->mURI.URI);
301            pDataLocator->mURI.URI = NULL;
302        }
303        pDataLocator->mURI.URI = NULL;
304        break;
305    case SL_DATALOCATOR_IODEVICE:
306        if (NULL != pDataLocator->mIODevice.device) {
307            ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device);
308            pDataLocator->mIODevice.device = NULL;
309        }
310        break;
311    case SL_DATALOCATOR_OUTPUTMIX:
312        if (NULL != pDataLocator->mOutputMix.outputMix) {
313            ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix);
314            pDataLocator->mOutputMix.outputMix = NULL;
315        }
316        break;
317#ifdef ANDROID
318    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
319    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
320    case SL_DATALOCATOR_ANDROIDFD:
321        break;
322#endif
323    default:
324        // an invalid data locator is caught earlier when making the copy
325        assert(false);
326        break;
327    }
328}
329
330
331/** \brief Check a data format and make local deep copy */
332
333static SLresult checkDataFormat(const char *name, void *pFormat, DataFormat *pDataFormat,
334        SLuint32 allowedDataFormatMask)
335{
336    assert(NULL != name && NULL != pDataFormat);
337    SLresult result = SL_RESULT_SUCCESS;
338
339    SLuint32 formatType;
340    if (NULL == pFormat) {
341        pDataFormat->mFormatType = formatType = SL_DATAFORMAT_NULL;
342    } else {
343        formatType = *(SLuint32 *)pFormat;
344        switch (formatType) {
345
346        case SL_DATAFORMAT_PCM:
347            pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat;
348            do {
349
350                // check the channel count
351                switch (pDataFormat->mPCM.numChannels) {
352                case 1:     // mono
353                case 2:     // stereo
354                    break;
355                case 0:     // unknown
356                    result = SL_RESULT_PARAMETER_INVALID;
357                    break;
358                default:    // multi-channel
359                    result = SL_RESULT_CONTENT_UNSUPPORTED;
360                    break;
361                }
362                if (SL_RESULT_SUCCESS != result) {
363                    SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels);
364                    break;
365                }
366
367                // check the sampling rate
368                switch (pDataFormat->mPCM.samplesPerSec) {
369                case SL_SAMPLINGRATE_8:
370                case SL_SAMPLINGRATE_11_025:
371                case SL_SAMPLINGRATE_12:
372                case SL_SAMPLINGRATE_16:
373                case SL_SAMPLINGRATE_22_05:
374                case SL_SAMPLINGRATE_24:
375                case SL_SAMPLINGRATE_32:
376                case SL_SAMPLINGRATE_44_1:
377                case SL_SAMPLINGRATE_48:
378                case SL_SAMPLINGRATE_64:
379                case SL_SAMPLINGRATE_88_2:
380                case SL_SAMPLINGRATE_96:
381                case SL_SAMPLINGRATE_192:
382                    break;
383                case 0:
384                    result = SL_RESULT_PARAMETER_INVALID;
385                    break;
386                default:
387                    result = SL_RESULT_CONTENT_UNSUPPORTED;
388                    break;
389                }
390                if (SL_RESULT_SUCCESS != result) {
391                    SL_LOGE("%s: samplesPerSec=%lu", name, pDataFormat->mPCM.samplesPerSec);
392                    break;
393                }
394
395                // check the sample bit depth
396                switch (pDataFormat->mPCM.bitsPerSample) {
397                case SL_PCMSAMPLEFORMAT_FIXED_8:
398                case SL_PCMSAMPLEFORMAT_FIXED_16:
399                    break;
400                case SL_PCMSAMPLEFORMAT_FIXED_20:
401                case SL_PCMSAMPLEFORMAT_FIXED_24:
402                case SL_PCMSAMPLEFORMAT_FIXED_28:
403                case SL_PCMSAMPLEFORMAT_FIXED_32:
404                    result = SL_RESULT_CONTENT_UNSUPPORTED;
405                    break;
406                default:
407                    result = SL_RESULT_PARAMETER_INVALID;
408                    break;
409                }
410                if (SL_RESULT_SUCCESS != result) {
411                    SL_LOGE("%s: bitsPerSample=%lu", name, pDataFormat->mPCM.bitsPerSample);
412                    break;
413                }
414
415                // check the container bit depth
416                if (pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) {
417                    result = SL_RESULT_PARAMETER_INVALID;
418                } else if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) {
419                    result = SL_RESULT_CONTENT_UNSUPPORTED;
420                }
421                if (SL_RESULT_SUCCESS != result) {
422                    SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name,
423                            (unsigned) pDataFormat->mPCM.containerSize,
424                            (unsigned) pDataFormat->mPCM.bitsPerSample);
425                    break;
426                }
427
428                // check the channel mask
429                switch (pDataFormat->mPCM.channelMask) {
430                case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT:
431                    if (2 != pDataFormat->mPCM.numChannels) {
432                        result = SL_RESULT_PARAMETER_INVALID;
433                    }
434                    break;
435                case SL_SPEAKER_FRONT_LEFT:
436                case SL_SPEAKER_FRONT_RIGHT:
437                case SL_SPEAKER_FRONT_CENTER:
438                    if (1 != pDataFormat->mPCM.numChannels) {
439                        result = SL_RESULT_PARAMETER_INVALID;
440                    }
441                    break;
442                case 0:
443                    pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ?
444                        SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER;
445                    break;
446                default:
447                    result = SL_RESULT_PARAMETER_INVALID;
448                    break;
449                }
450                if (SL_RESULT_SUCCESS != result) {
451                    SL_LOGE("%s: channelMask=0x%lx numChannels=%lu", name,
452                        pDataFormat->mPCM.channelMask, pDataFormat->mPCM.numChannels);
453                    break;
454                }
455
456                // check the endianness / byte order
457                switch (pDataFormat->mPCM.endianness) {
458                case SL_BYTEORDER_LITTLEENDIAN:
459                case SL_BYTEORDER_BIGENDIAN:
460                    break;
461                // native is proposed but not yet in spec
462                default:
463                    result = SL_RESULT_PARAMETER_INVALID;
464                    break;
465                }
466                if (SL_RESULT_SUCCESS != result) {
467                    SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness);
468                    break;
469                }
470
471                // here if all checks passed successfully
472
473            } while(0);
474            break;
475
476        case SL_DATAFORMAT_MIME:
477            pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat;
478            if (NULL != pDataFormat->mMIME.mimeType) {
479                // NTH check address for validity
480                size_t len = strlen((const char *) pDataFormat->mMIME.mimeType);
481                SLchar *myMIME = (SLchar *) malloc(len + 1);
482                if (NULL == myMIME) {
483                    result = SL_RESULT_MEMORY_FAILURE;
484                } else {
485                    memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1);
486                    // make sure MIME string was not modified asynchronously
487                    if ('\0' != myMIME[len]) {
488                        free(myMIME);
489                        myMIME = NULL;
490                        result = SL_RESULT_PRECONDITIONS_VIOLATED;
491                    }
492                }
493                pDataFormat->mMIME.mimeType = myMIME;
494            }
495            break;
496
497        case XA_DATAFORMAT_RAWIMAGE:
498            pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat;
499            switch (pDataFormat->mRawImage.colorFormat) {
500            case XA_COLORFORMAT_MONOCHROME:
501            case XA_COLORFORMAT_8BITRGB332:
502            case XA_COLORFORMAT_12BITRGB444:
503            case XA_COLORFORMAT_16BITARGB4444:
504            case XA_COLORFORMAT_16BITARGB1555:
505            case XA_COLORFORMAT_16BITRGB565:
506            case XA_COLORFORMAT_16BITBGR565:
507            case XA_COLORFORMAT_18BITRGB666:
508            case XA_COLORFORMAT_18BITARGB1665:
509            case XA_COLORFORMAT_19BITARGB1666:
510            case XA_COLORFORMAT_24BITRGB888:
511            case XA_COLORFORMAT_24BITBGR888:
512            case XA_COLORFORMAT_24BITARGB1887:
513            case XA_COLORFORMAT_25BITARGB1888:
514            case XA_COLORFORMAT_32BITBGRA8888:
515            case XA_COLORFORMAT_32BITARGB8888:
516            case XA_COLORFORMAT_YUV411PLANAR:
517            case XA_COLORFORMAT_YUV420PLANAR:
518            case XA_COLORFORMAT_YUV420SEMIPLANAR:
519            case XA_COLORFORMAT_YUV422PLANAR:
520            case XA_COLORFORMAT_YUV422SEMIPLANAR:
521            case XA_COLORFORMAT_YCBYCR:
522            case XA_COLORFORMAT_YCRYCB:
523            case XA_COLORFORMAT_CBYCRY:
524            case XA_COLORFORMAT_CRYCBY:
525            case XA_COLORFORMAT_YUV444INTERLEAVED:
526            case XA_COLORFORMAT_RAWBAYER8BIT:
527            case XA_COLORFORMAT_RAWBAYER10BIT:
528            case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED:
529            case XA_COLORFORMAT_L2:
530            case XA_COLORFORMAT_L4:
531            case XA_COLORFORMAT_L8:
532            case XA_COLORFORMAT_L16:
533            case XA_COLORFORMAT_L24:
534            case XA_COLORFORMAT_L32:
535            case XA_COLORFORMAT_18BITBGR666:
536            case XA_COLORFORMAT_24BITARGB6666:
537            case XA_COLORFORMAT_24BITABGR6666:
538                break;
539            case XA_COLORFORMAT_UNUSED:
540            default:
541                result = XA_RESULT_PARAMETER_INVALID;
542                SL_LOGE("%s: unsupported color format %ld", name,
543                    pDataFormat->mRawImage.colorFormat);
544                break;
545            }
546            // no checks for height, width, or stride
547            break;
548
549        default:
550            result = SL_RESULT_PARAMETER_INVALID;
551            SL_LOGE("%s: formatType=%u", name, (unsigned) formatType);
552            break;
553
554        }
555
556        // make sure format type was not modified asynchronously
557        if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) {
558            SL_LOGE("%s: formatType changed from %lu to %lu", name, formatType,
559                    pDataFormat->mFormatType);
560            result = SL_RESULT_PRECONDITIONS_VIOLATED;
561        }
562
563    }
564
565    // Verify that the data format type is allowed in this context
566    if (SL_RESULT_SUCCESS == result) {
567        SLuint32 actualMask;
568        switch (formatType) {
569        case SL_DATAFORMAT_NULL:
570        case SL_DATAFORMAT_MIME:
571        case SL_DATAFORMAT_PCM:
572        case XA_DATAFORMAT_RAWIMAGE:
573            actualMask = 1L << formatType;
574            break;
575        default:
576            assert(false);
577            actualMask = 0L;
578            break;
579        }
580        if (!(allowedDataFormatMask & actualMask)) {
581            SL_LOGE("%s: data format %ld not allowed", name, formatType);
582            result = SL_RESULT_CONTENT_UNSUPPORTED;
583        }
584    }
585
586    return result;
587}
588
589
590/** \brief Check interface ID compatibility with respect to a particular source
591 *         data locator format
592 */
593
594SLresult checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat,
595        const ClassTable *clazz, unsigned exposedMask) {
596    int index;
597    switch (pSrcDataLocatorFormat->mLocator.mLocatorType) {
598    case SL_DATALOCATOR_URI:
599#ifdef ANDROID
600    case SL_DATALOCATOR_ANDROIDFD:
601#endif
602        // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode
603        // so we don't prevent the retrieval of the BufferQueue interfaces for those sources
604        break;
605
606    case SL_DATALOCATOR_BUFFERQUEUE:
607#ifdef ANDROID
608    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
609#endif
610        // can't request SLSeekItf if data source is a buffer queue
611        index = clazz->mMPH_to_index[MPH_SEEK];
612        if (0 <= index) {
613            if (exposedMask & (1 << index)) {
614                SL_LOGE("can't request SL_IID_SEEK with a buffer queue data source");
615                return SL_RESULT_FEATURE_UNSUPPORTED;
616            }
617        }
618        // can't request SLMuteSoloItf if data source is a mono buffer queue
619        index = clazz->mMPH_to_index[MPH_MUTESOLO];
620        if (0 <= index) {
621            if ((exposedMask & (1 << index)) &&
622                    (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) &&
623                    (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) {
624                SL_LOGE("can't request SL_IID_MUTESOLO with a mono buffer queue data source");
625                return SL_RESULT_FEATURE_UNSUPPORTED;
626            }
627        }
628        break;
629
630#ifdef ANDROID
631    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
632#endif
633    case SL_DATALOCATOR_ADDRESS:
634    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
635    case XA_DATALOCATOR_NATIVEDISPLAY:
636        // any special checks here???
637    default:
638        // can't request SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
639        // if the data source is not a buffer queue
640        index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
641#ifdef ANDROID
642        assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
643#endif
644        if (0 <= index) {
645            if (exposedMask & (1 << index)) {
646                SL_LOGE("can't request SL_IID_BUFFERQUEUE "
647#ifdef ANDROID
648                        "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
649#endif
650                        "with a non-buffer queue data source");
651                return SL_RESULT_FEATURE_UNSUPPORTED;
652            }
653        }
654        break;
655    }
656    return SL_RESULT_SUCCESS;
657}
658
659
660/** \brief Free the local deep copy of a data format */
661
662static void freeDataFormat(DataFormat *pDataFormat)
663{
664    switch (pDataFormat->mFormatType) {
665    case SL_DATAFORMAT_MIME:
666        if (NULL != pDataFormat->mMIME.mimeType) {
667            free(pDataFormat->mMIME.mimeType);
668            pDataFormat->mMIME.mimeType = NULL;
669        }
670        break;
671    case SL_DATAFORMAT_PCM:
672    case XA_DATAFORMAT_RAWIMAGE:
673    case SL_DATAFORMAT_NULL:
674        break;
675    default:
676        // an invalid data format is caught earlier during the copy
677        assert(false);
678        break;
679    }
680}
681
682
683/** \brief Check a data source and make local deep copy */
684
685SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc,
686        DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
687        SLuint32 allowedDataFormatMask)
688{
689    assert(NULL != name && NULL != pDataLocatorFormat);
690    pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator;
691    pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat;
692
693    if (NULL == pDataSrc) {
694        pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
695        pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
696        if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
697                (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
698            return SL_RESULT_SUCCESS;
699        }
700        SL_LOGE("%s: data source cannot be NULL", name);
701        return SL_RESULT_PARAMETER_INVALID;
702    }
703    SLDataSource myDataSrc = *pDataSrc;
704    SLresult result;
705    result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator,
706            allowedDataLocatorMask);
707    if (SL_RESULT_SUCCESS != result) {
708        return result;
709    }
710
711    switch (pDataLocatorFormat->mLocator.mLocatorType) {
712    case SL_DATALOCATOR_URI:
713        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
714        break;
715    case SL_DATALOCATOR_ADDRESS:
716    case SL_DATALOCATOR_BUFFERQUEUE:
717        allowedDataFormatMask &= DATAFORMAT_MASK_PCM;
718        break;
719    // Per the spec, the pFormat field is ignored in some cases
720    case SL_DATALOCATOR_IODEVICE:
721        myDataSrc.pFormat = NULL;
722        // fall through
723    case SL_DATALOCATOR_NULL:
724    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
725        allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
726        break;
727    case SL_DATALOCATOR_OUTPUTMIX:
728    case XA_DATALOCATOR_NATIVEDISPLAY:
729        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
730        break;
731#ifdef ANDROID
732    case SL_DATALOCATOR_ANDROIDFD:
733        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
734        break;
735    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
736        allowedDataFormatMask &= DATAFORMAT_MASK_PCM;
737        break;
738    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
739        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;;
740        break;
741#endif
742    default:
743        // invalid data locator type is caught earlier
744        assert(false);
745        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
746        break;
747    }
748
749    result = checkDataFormat(name, myDataSrc.pFormat, &pDataLocatorFormat->mFormat,
750            allowedDataFormatMask);
751    if (SL_RESULT_SUCCESS != result) {
752        freeDataLocator(&pDataLocatorFormat->mLocator);
753        return result;
754    }
755
756    return SL_RESULT_SUCCESS;
757}
758
759
760/** \brief Check a data sink and make local deep copy */
761
762SLresult checkDataSink(const char *name, const SLDataSink *pDataSink,
763        DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
764        SLuint32 allowedDataFormatMask)
765{
766    assert(NULL != name && NULL != pDataLocatorFormat);
767    pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator;
768    pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat;
769
770    if (NULL == pDataSink) {
771        pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
772        pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
773        if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
774                (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
775            return SL_RESULT_SUCCESS;
776        }
777        SL_LOGE("%s: data sink cannot be NULL", name);
778        return SL_RESULT_PARAMETER_INVALID;
779    }
780    SLDataSink myDataSink = *pDataSink;
781    SLresult result;
782    result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator,
783            allowedDataLocatorMask);
784    if (SL_RESULT_SUCCESS != result) {
785        return result;
786    }
787
788    switch (pDataLocatorFormat->mLocator.mLocatorType) {
789    case SL_DATALOCATOR_URI:
790        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
791        break;
792    case SL_DATALOCATOR_ADDRESS:
793    case SL_DATALOCATOR_BUFFERQUEUE:
794        allowedDataFormatMask &= DATAFORMAT_MASK_PCM;
795        break;
796    // Per the spec, the pFormat field is ignored in some cases
797    case SL_DATALOCATOR_IODEVICE:
798    case SL_DATALOCATOR_OUTPUTMIX:
799    case XA_DATALOCATOR_NATIVEDISPLAY:
800        myDataSink.pFormat = NULL;
801        // fall through
802    case SL_DATALOCATOR_NULL:
803    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
804        allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
805        break;
806#ifdef ANDROID
807    case SL_DATALOCATOR_ANDROIDFD:
808        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
809        break;
810    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
811        allowedDataFormatMask &= DATAFORMAT_MASK_PCM;
812        break;
813    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
814        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
815        break;
816#endif
817    default:
818        // invalid data locator type is caught earlier
819        assert(false);
820        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
821        break;
822    }
823
824    result = checkDataFormat(name, myDataSink.pFormat, &pDataLocatorFormat->mFormat,
825            allowedDataFormatMask);
826    if (SL_RESULT_SUCCESS != result) {
827        freeDataLocator(&pDataLocatorFormat->mLocator);
828        return result;
829    }
830
831    return SL_RESULT_SUCCESS;
832}
833
834
835/** \brief Free the local deep copy of a data locator format */
836
837void freeDataLocatorFormat(DataLocatorFormat *dlf)
838{
839    assert(NULL != dlf);
840    freeDataLocator(&dlf->mLocator);
841    freeDataFormat(&dlf->mFormat);
842}
843