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