1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/** Data locator, data format, data source, and data sink support */
18
19#include "sles_allinclusive.h"
20#ifdef ANDROID  // FIXME This file should be portable
21#include "android/channels.h"
22#include "data.h"
23#endif
24
25#include <cutils/bitops.h>
26
27/** \brief Check a data locator and make local deep copy */
28
29static SLresult checkDataLocator(const char *name, void *pLocator, DataLocator *pDataLocator,
30        SLuint32 allowedDataLocatorMask)
31{
32    assert(NULL != name && NULL != pDataLocator);
33    SLresult result = SL_RESULT_SUCCESS;
34
35    SLuint32 locatorType;
36    if (NULL == pLocator) {
37        pDataLocator->mLocatorType = locatorType = SL_DATALOCATOR_NULL;
38    } else {
39        locatorType = *(SLuint32 *)pLocator;
40        switch (locatorType) {
41
42        case SL_DATALOCATOR_ADDRESS:
43            pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator;
44            // if length is greater than zero, then the address must be non-NULL
45            if ((0 < pDataLocator->mAddress.length) && (NULL == pDataLocator->mAddress.pAddress)) {
46                SL_LOGE("%s: pAddress=NULL", name);
47                result = SL_RESULT_PARAMETER_INVALID;
48            }
49            break;
50
51        case SL_DATALOCATOR_BUFFERQUEUE:
52#ifdef ANDROID
53        // This is an alias that is _not_ converted; the rest of the code must check for both
54        // locator types. That's because it is only an alias for audio players, not audio recorder
55        // objects so we have to remember the distinction.
56        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
57#endif
58            pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator;
59            // number of buffers must be specified, there is no default value, and can't be too big
60            if (!((1 <= pDataLocator->mBufferQueue.numBuffers) &&
61                (pDataLocator->mBufferQueue.numBuffers <= 255))) {
62                SL_LOGE("%s: numBuffers=%u", name, pDataLocator->mBufferQueue.numBuffers);
63                result = SL_RESULT_PARAMETER_INVALID;
64            }
65            break;
66
67        case SL_DATALOCATOR_IODEVICE:
68            {
69            pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator;
70            SLuint32 deviceType = pDataLocator->mIODevice.deviceType;
71            SLObjectItf device = pDataLocator->mIODevice.device;
72            if (NULL != device) {
73                pDataLocator->mIODevice.deviceID = 0;
74                SLuint32 expectedObjectID;
75                switch (deviceType) {
76                case SL_IODEVICE_LEDARRAY:
77                    expectedObjectID = SL_OBJECTID_LEDDEVICE;
78                    break;
79                case SL_IODEVICE_VIBRA:
80                    expectedObjectID = SL_OBJECTID_VIBRADEVICE;
81                    break;
82                case XA_IODEVICE_CAMERA:
83                    expectedObjectID = XA_OBJECTID_CAMERADEVICE;
84                    break;
85                case XA_IODEVICE_RADIO:
86                    expectedObjectID = XA_OBJECTID_RADIODEVICE;
87                    break;
88                // audio input and audio output cannot be specified via objects
89                case SL_IODEVICE_AUDIOINPUT:
90                // case SL_IODEVICE_AUDIOOUTPUT:   // does not exist in 1.0.1, added in 1.1
91                default:
92                    SL_LOGE("%s: deviceType=%u", name, deviceType);
93                    pDataLocator->mIODevice.device = NULL;
94                    expectedObjectID = 0;
95                    result = SL_RESULT_PARAMETER_INVALID;
96                }
97                if (result == SL_RESULT_SUCCESS) {
98                    // check that device has the correct object ID and is realized,
99                    // and acquire a strong reference to it
100                    result = AcquireStrongRef((IObject *) device, expectedObjectID);
101                    if (SL_RESULT_SUCCESS != result) {
102                        SL_LOGE("%s: locatorType=IODEVICE, but device field %p has wrong " \
103                            "object ID or is not realized", name, device);
104                        pDataLocator->mIODevice.device = NULL;
105                    }
106                }
107            } else {
108                SLuint32 deviceID = pDataLocator->mIODevice.deviceID;
109                switch (deviceType) {
110                case SL_IODEVICE_LEDARRAY:
111                    if (SL_DEFAULTDEVICEID_LED != deviceID) {
112                        SL_LOGE("%s: invalid LED deviceID=%u", name, deviceID);
113                        result = SL_RESULT_PARAMETER_INVALID;
114                    }
115                    break;
116                case SL_IODEVICE_VIBRA:
117                    if (SL_DEFAULTDEVICEID_VIBRA != deviceID) {
118                        SL_LOGE("%s: invalid vibra deviceID=%u", name, deviceID);
119                        result = SL_RESULT_PARAMETER_INVALID;
120                    }
121                    break;
122                case SL_IODEVICE_AUDIOINPUT:
123                    if (SL_DEFAULTDEVICEID_AUDIOINPUT != deviceID) {
124                        SL_LOGE("%s: invalid audio input deviceID=%u", name, deviceID);
125                        result = SL_RESULT_PARAMETER_INVALID;
126                    }
127                    break;
128                case XA_IODEVICE_RADIO:
129                    // no default device ID for radio; see Khronos bug XXXX
130                    break;
131                case XA_IODEVICE_CAMERA:
132                    if (XA_DEFAULTDEVICEID_CAMERA != deviceID) {
133                        SL_LOGE("%s: invalid audio input deviceID=%u", name, deviceID);
134                        result = XA_RESULT_PARAMETER_INVALID;
135                    }
136                    break;
137                // case SL_IODEVICE_AUDIOOUTPUT:
138                    // does not exist in 1.0.1, added in 1.1
139                    // break;
140                default:
141                    SL_LOGE("%s: deviceType=%u is invalid", name, deviceType);
142                    result = SL_RESULT_PARAMETER_INVALID;
143                }
144            }
145            }
146            break;
147
148        case SL_DATALOCATOR_MIDIBUFFERQUEUE:
149            pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator;
150            if (0 == pDataLocator->mMIDIBufferQueue.tpqn) {
151                pDataLocator->mMIDIBufferQueue.tpqn = 192;
152            }
153            // number of buffers must be specified, there is no default value, and can't be too big
154            if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) &&
155                (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) {
156                SL_LOGE("%s: SLDataLocator_MIDIBufferQueue.numBuffers=%d", name,
157                        pDataLocator->mMIDIBufferQueue.numBuffers);
158                result = SL_RESULT_PARAMETER_INVALID;
159            }
160            break;
161
162        case SL_DATALOCATOR_OUTPUTMIX:
163            pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator;
164            // check that output mix object has the correct object ID and is realized,
165            // and acquire a strong reference to it
166            result = AcquireStrongRef((IObject *) pDataLocator->mOutputMix.outputMix,
167                SL_OBJECTID_OUTPUTMIX);
168            if (SL_RESULT_SUCCESS != result) {
169                SL_LOGE("%s: locatorType=SL_DATALOCATOR_OUTPUTMIX, but outputMix field %p does " \
170                    "not refer to an SL_OBJECTID_OUTPUTMIX or the output mix is not realized", \
171                    name, pDataLocator->mOutputMix.outputMix);
172                pDataLocator->mOutputMix.outputMix = NULL;
173            }
174            break;
175
176        case XA_DATALOCATOR_NATIVEDISPLAY:
177            pDataLocator->mNativeDisplay = *(XADataLocator_NativeDisplay *)pLocator;
178            // hWindow is NDK C ANativeWindow * and hDisplay must be NULL
179            if (pDataLocator->mNativeDisplay.hWindow == NULL) {
180                SL_LOGE("%s: hWindow must be non-NULL ANativeWindow *", name);
181                result = SL_RESULT_PARAMETER_INVALID;
182            }
183            if (pDataLocator->mNativeDisplay.hDisplay != NULL) {
184                SL_LOGE("%s: hDisplay must be NULL, but is %p", name,
185                        pDataLocator->mNativeDisplay.hDisplay);
186                result = SL_RESULT_PARAMETER_INVALID;
187            }
188            break;
189
190        case SL_DATALOCATOR_URI:
191            {
192            pDataLocator->mURI = *(SLDataLocator_URI *)pLocator;
193            if (NULL == pDataLocator->mURI.URI) {
194                SL_LOGE("%s: invalid URI=NULL", name);
195                result = SL_RESULT_PARAMETER_INVALID;
196            } else {
197                // NTH verify URI address for validity
198                size_t len = strlen((const char *) pDataLocator->mURI.URI);
199                SLchar *myURI = (SLchar *) malloc(len + 1);
200                if (NULL == myURI) {
201                    result = SL_RESULT_MEMORY_FAILURE;
202                } else {
203                    memcpy(myURI, pDataLocator->mURI.URI, len + 1);
204                    // Verify that another thread didn't change the NUL-terminator after we used it
205                    // to determine length of string to copy. It's OK if the string became shorter.
206                    if ('\0' != myURI[len]) {
207                        free(myURI);
208                        myURI = NULL;
209                        result = SL_RESULT_PARAMETER_INVALID;
210                    }
211                }
212                pDataLocator->mURI.URI = myURI;
213            }
214            }
215            break;
216
217#ifdef ANDROID
218        case SL_DATALOCATOR_ANDROIDFD:
219        {
220            pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator;
221            SL_LOGV("%s: fd=%d offset=%lld length=%lld", name, pDataLocator->mFD.fd,
222                    pDataLocator->mFD.offset, pDataLocator->mFD.length);
223            // NTH check against process fd limit
224            if (0 > pDataLocator->mFD.fd) {
225                SL_LOGE("%s: fd=%d\n", name, pDataLocator->mFD.fd);
226                result = SL_RESULT_PARAMETER_INVALID;
227            }
228            break;
229        }
230        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
231        {
232            pDataLocator->mABQ = *(SLDataLocator_AndroidBufferQueue*)pLocator;
233            // number of buffers must be specified, there is no default value, and can't be too big
234            if (!((1 <= pDataLocator->mBufferQueue.numBuffers) &&
235                    (pDataLocator->mBufferQueue.numBuffers <= 255))) {
236                SL_LOGE("%s: numBuffers=%u", name, pDataLocator->mABQ.numBuffers);
237                result = SL_RESULT_PARAMETER_INVALID;
238            }
239            break;
240        }
241#endif
242
243        case SL_DATALOCATOR_NULL:   // a NULL pointer is allowed, but not a pointer to NULL
244        default:
245            SL_LOGE("%s: locatorType=%u", name, locatorType);
246            result = SL_RESULT_PARAMETER_INVALID;
247        }
248
249        // Verify that another thread didn't change the locatorType field after we used it
250        // to determine sizeof struct to copy.
251        if ((SL_RESULT_SUCCESS == result) && (locatorType != pDataLocator->mLocatorType)) {
252            SL_LOGE("%s: locatorType changed from %u to %u", name, locatorType,
253                    pDataLocator->mLocatorType);
254            result = SL_RESULT_PRECONDITIONS_VIOLATED;
255        }
256
257    }
258
259    // Verify that the data locator type is allowed in this context
260    if (SL_RESULT_SUCCESS == result) {
261        SLuint32 actualMask;
262        switch (locatorType) {
263        case SL_DATALOCATOR_NULL:
264        case SL_DATALOCATOR_URI:
265        case SL_DATALOCATOR_ADDRESS:
266        case SL_DATALOCATOR_IODEVICE:
267        case SL_DATALOCATOR_OUTPUTMIX:
268        case XA_DATALOCATOR_NATIVEDISPLAY:
269        case SL_DATALOCATOR_BUFFERQUEUE:
270        case SL_DATALOCATOR_MIDIBUFFERQUEUE:
271            actualMask = 1L << locatorType;
272            break;
273#ifdef ANDROID
274        case SL_DATALOCATOR_ANDROIDFD:
275        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
276        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
277            actualMask = 0x100L << (locatorType - SL_DATALOCATOR_ANDROIDFD);
278            break;
279#endif
280        default:
281            assert(false);
282            actualMask = 0L;
283            break;
284        }
285        if (!(allowedDataLocatorMask & actualMask)) {
286            SL_LOGE("%s: data locator type 0x%x not allowed", name, locatorType);
287            result = SL_RESULT_CONTENT_UNSUPPORTED;
288        }
289    }
290
291    return result;
292}
293
294
295/** \brief Free the local deep copy of a data locator */
296
297static void freeDataLocator(DataLocator *pDataLocator)
298{
299    switch (pDataLocator->mLocatorType) {
300    case SL_DATALOCATOR_NULL:
301    case SL_DATALOCATOR_ADDRESS:
302    case SL_DATALOCATOR_BUFFERQUEUE:
303    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
304    case XA_DATALOCATOR_NATIVEDISPLAY:
305        break;
306    case SL_DATALOCATOR_URI:
307        if (NULL != pDataLocator->mURI.URI) {
308            free(pDataLocator->mURI.URI);
309            pDataLocator->mURI.URI = NULL;
310        }
311        pDataLocator->mURI.URI = NULL;
312        break;
313    case SL_DATALOCATOR_IODEVICE:
314        if (NULL != pDataLocator->mIODevice.device) {
315            ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device);
316            pDataLocator->mIODevice.device = NULL;
317        }
318        break;
319    case SL_DATALOCATOR_OUTPUTMIX:
320        if (NULL != pDataLocator->mOutputMix.outputMix) {
321            ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix);
322            pDataLocator->mOutputMix.outputMix = NULL;
323        }
324        break;
325#ifdef ANDROID
326    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
327    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
328    case SL_DATALOCATOR_ANDROIDFD:
329        break;
330#endif
331    default:
332        // an invalid data locator is caught earlier when making the copy
333        assert(false);
334        break;
335    }
336}
337
338
339/** \brief Check a data format and make local deep copy */
340
341static SLresult checkDataFormat(const char *name, void *pFormat, DataFormat *pDataFormat,
342        SLuint32 allowedDataFormatMask, SLboolean isOutputFormat)
343{
344    assert(NULL != name && NULL != pDataFormat);
345    SLresult result = SL_RESULT_SUCCESS;
346    const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists
347    SLuint32 formatType;
348    if (NULL == pFormat) {
349        pDataFormat->mFormatType = formatType = SL_DATAFORMAT_NULL;
350    } else {
351        formatType = *(SLuint32 *)pFormat;
352        switch (formatType) {
353        case SL_ANDROID_DATAFORMAT_PCM_EX:
354            pDataFormat->mPCMEx.representation =
355                    ((SLAndroidDataFormat_PCM_EX *)pFormat)->representation;
356            switch (pDataFormat->mPCMEx.representation) {
357            case SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT:
358            case SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT:
359            case SL_ANDROID_PCM_REPRESENTATION_FLOAT:
360                df_representation = &pDataFormat->mPCMEx.representation;
361                break;
362            default:
363                SL_LOGE("%s: unsupported representation: %d", name,
364                        pDataFormat->mPCMEx.representation);
365                result = SL_RESULT_PARAMETER_INVALID;
366                break;
367            }
368            // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test.
369        case SL_DATAFORMAT_PCM:
370            pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat;
371            do {
372                if (pDataFormat->mPCM.numChannels == 0) {
373                    result = SL_RESULT_PARAMETER_INVALID;
374                } else if (pDataFormat->mPCM.numChannels > SL_ANDROID_SPEAKER_COUNT_MAX) {
375                    result = SL_RESULT_CONTENT_UNSUPPORTED;
376                }
377                if (SL_RESULT_SUCCESS != result) {
378                    SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels);
379                    break;
380                }
381
382                // check the sampling rate
383                if (pDataFormat->mPCM.samplesPerSec == 0) {
384                    result = SL_RESULT_PARAMETER_INVALID;
385                } else if (pDataFormat->mPCM.samplesPerSec < SL_SAMPLINGRATE_8 ||
386                        pDataFormat->mPCM.samplesPerSec > SL_SAMPLINGRATE_192) {
387                    result = SL_RESULT_CONTENT_UNSUPPORTED;
388                }
389                if (SL_RESULT_SUCCESS != result) {
390                    SL_LOGE("%s: samplesPerSec=%u", name, pDataFormat->mPCM.samplesPerSec);
391                    break;
392                }
393
394                // check the container bit depth and representation
395                switch (pDataFormat->mPCM.containerSize) {
396                case 8:
397                    if (df_representation != NULL &&
398                            *df_representation != SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT) {
399                        result = SL_RESULT_PARAMETER_INVALID;
400                    }
401                    break;
402                case 16:
403                case 24:
404                    if (df_representation != NULL &&
405                            *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT) {
406                        result = SL_RESULT_PARAMETER_INVALID;
407                    }
408                    break;
409                case 32:
410                    if (df_representation != NULL
411                            && *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT
412                            && *df_representation != SL_ANDROID_PCM_REPRESENTATION_FLOAT) {
413                        result = SL_RESULT_PARAMETER_INVALID;
414                    }
415                    break;
416                default:
417                    result = SL_RESULT_PARAMETER_INVALID;
418                    break;
419                }
420                if (SL_RESULT_SUCCESS != result) {
421                    SL_LOGE("%s: containerSize=%u", name, pDataFormat->mPCM.containerSize);
422                    break;
423                }
424
425                // sample size cannot be zero, and container size cannot be less than sample size
426                if (pDataFormat->mPCM.bitsPerSample == 0 ||
427                        pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) {
428                    result = SL_RESULT_PARAMETER_INVALID;
429                }
430                if (SL_RESULT_SUCCESS != result) {
431                    SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name,
432                            (unsigned) pDataFormat->mPCM.containerSize,
433                            (unsigned) pDataFormat->mPCM.bitsPerSample);
434                    break;
435                }
436
437                // check the channel mask
438                SL_LOGV("%s: Requested channel mask of 0x%x for %d channel audio",
439                    name,
440                    pDataFormat->mPCM.channelMask,
441                    pDataFormat->mPCM.numChannels);
442
443                if (pDataFormat->mPCM.channelMask == 0) {
444                    // We can derive the channel mask from the channel count,
445                    // but issue a warning--the automatic mask generation
446                    // makes a lot of assumptions that may or may not be what
447                    // the app was expecting.
448                    SLuint32 mask = isOutputFormat
449                            ? sles_channel_out_mask_from_count(pDataFormat->mPCM.numChannels)
450                            : sles_channel_in_mask_from_count(pDataFormat->mPCM.numChannels);
451                    if (mask == SL_ANDROID_UNKNOWN_CHANNELMASK) {
452                        SL_LOGE("No channel mask specified and no default mapping for"
453                                "requested speaker count of %u", pDataFormat->mPCM.numChannels);
454                        result = SL_RESULT_PARAMETER_INVALID;
455                    } else {
456                        pDataFormat->mPCM.channelMask = mask;
457                        SL_LOGW("No channel mask specified; Using mask %#x based on requested"
458                                        "speaker count of %u",
459                                pDataFormat->mPCM.channelMask,
460                                pDataFormat->mPCM.numChannels);
461                    }
462                }
463
464                SLuint32 mask = pDataFormat->mPCM.channelMask;
465                SLuint32 count = sles_channel_count_from_mask(mask);
466                if (count != pDataFormat->mPCM.numChannels) {
467                    SL_LOGE("%s: requested %d channels but mask (0x%x) has %d channel bits set",
468                        name,
469                        pDataFormat->mPCM.numChannels,
470                        mask,
471                        count);
472                    result = SL_RESULT_PARAMETER_INVALID;
473                    break;
474                }
475
476                SL_LOGV("%s: final channel mask is 0x%x", name, pDataFormat->mPCM.channelMask);
477
478                // check the endianness / byte order
479                switch (pDataFormat->mPCM.endianness) {
480                case SL_BYTEORDER_LITTLEENDIAN:
481                case SL_BYTEORDER_BIGENDIAN:
482                    break;
483                // native is proposed but not yet in spec
484                default:
485                    result = SL_RESULT_PARAMETER_INVALID;
486                    break;
487                }
488                if (SL_RESULT_SUCCESS != result) {
489                    SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness);
490                    break;
491                }
492
493                // here if all checks passed successfully
494
495            } while(0);
496            break;
497
498        case SL_DATAFORMAT_MIME:
499            pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat;
500            if (NULL != pDataFormat->mMIME.mimeType) {
501                // NTH check address for validity
502                size_t len = strlen((const char *) pDataFormat->mMIME.mimeType);
503                SLchar *myMIME = (SLchar *) malloc(len + 1);
504                if (NULL == myMIME) {
505                    result = SL_RESULT_MEMORY_FAILURE;
506                } else {
507                    memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1);
508                    // make sure MIME string was not modified asynchronously
509                    if ('\0' != myMIME[len]) {
510                        free(myMIME);
511                        myMIME = NULL;
512                        result = SL_RESULT_PRECONDITIONS_VIOLATED;
513                    }
514                }
515                pDataFormat->mMIME.mimeType = myMIME;
516            }
517            break;
518
519        case XA_DATAFORMAT_RAWIMAGE:
520            pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat;
521            switch (pDataFormat->mRawImage.colorFormat) {
522            case XA_COLORFORMAT_MONOCHROME:
523            case XA_COLORFORMAT_8BITRGB332:
524            case XA_COLORFORMAT_12BITRGB444:
525            case XA_COLORFORMAT_16BITARGB4444:
526            case XA_COLORFORMAT_16BITARGB1555:
527            case XA_COLORFORMAT_16BITRGB565:
528            case XA_COLORFORMAT_16BITBGR565:
529            case XA_COLORFORMAT_18BITRGB666:
530            case XA_COLORFORMAT_18BITARGB1665:
531            case XA_COLORFORMAT_19BITARGB1666:
532            case XA_COLORFORMAT_24BITRGB888:
533            case XA_COLORFORMAT_24BITBGR888:
534            case XA_COLORFORMAT_24BITARGB1887:
535            case XA_COLORFORMAT_25BITARGB1888:
536            case XA_COLORFORMAT_32BITBGRA8888:
537            case XA_COLORFORMAT_32BITARGB8888:
538            case XA_COLORFORMAT_YUV411PLANAR:
539            case XA_COLORFORMAT_YUV420PLANAR:
540            case XA_COLORFORMAT_YUV420SEMIPLANAR:
541            case XA_COLORFORMAT_YUV422PLANAR:
542            case XA_COLORFORMAT_YUV422SEMIPLANAR:
543            case XA_COLORFORMAT_YCBYCR:
544            case XA_COLORFORMAT_YCRYCB:
545            case XA_COLORFORMAT_CBYCRY:
546            case XA_COLORFORMAT_CRYCBY:
547            case XA_COLORFORMAT_YUV444INTERLEAVED:
548            case XA_COLORFORMAT_RAWBAYER8BIT:
549            case XA_COLORFORMAT_RAWBAYER10BIT:
550            case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED:
551            case XA_COLORFORMAT_L2:
552            case XA_COLORFORMAT_L4:
553            case XA_COLORFORMAT_L8:
554            case XA_COLORFORMAT_L16:
555            case XA_COLORFORMAT_L24:
556            case XA_COLORFORMAT_L32:
557            case XA_COLORFORMAT_18BITBGR666:
558            case XA_COLORFORMAT_24BITARGB6666:
559            case XA_COLORFORMAT_24BITABGR6666:
560                break;
561            case XA_COLORFORMAT_UNUSED:
562            default:
563                result = XA_RESULT_PARAMETER_INVALID;
564                SL_LOGE("%s: unsupported color format %d", name,
565                    pDataFormat->mRawImage.colorFormat);
566                break;
567            }
568            // no checks for height, width, or stride
569            break;
570
571        default:
572            result = SL_RESULT_PARAMETER_INVALID;
573            SL_LOGE("%s: formatType=%u", name, (unsigned) formatType);
574            break;
575
576        }
577
578        // make sure format type was not modified asynchronously
579        if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) {
580            SL_LOGE("%s: formatType changed from %u to %u", name, formatType,
581                    pDataFormat->mFormatType);
582            result = SL_RESULT_PRECONDITIONS_VIOLATED;
583        }
584
585    }
586
587    // Verify that the data format type is allowed in this context
588    if (SL_RESULT_SUCCESS == result) {
589        SLuint32 actualMask;
590        switch (formatType) {
591        case SL_DATAFORMAT_NULL:
592        case SL_DATAFORMAT_MIME:
593        case SL_DATAFORMAT_PCM:
594        case SL_ANDROID_DATAFORMAT_PCM_EX:
595        case XA_DATAFORMAT_RAWIMAGE:
596            actualMask = 1L << formatType;
597            break;
598        default:
599            assert(false);
600            actualMask = 0L;
601            break;
602        }
603        if (!(allowedDataFormatMask & actualMask)) {
604            SL_LOGE("%s: data format %d not allowed", name, formatType);
605            result = SL_RESULT_CONTENT_UNSUPPORTED;
606        }
607    }
608
609    return result;
610}
611
612
613/** \brief Check interface ID compatibility with respect to a particular source
614 *         and sink data locator format
615 */
616
617SLresult checkSourceSinkVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat,
618        const DataLocatorFormat *pSinkDataLocatorFormat,
619        const ClassTable *clazz, unsigned requiredMask) {
620    int index;
621    switch (pSrcDataLocatorFormat->mLocator.mLocatorType) {
622    case SL_DATALOCATOR_URI:
623#ifdef ANDROID
624    case SL_DATALOCATOR_ANDROIDFD:
625#endif
626        // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode
627        // so we don't prevent the retrieval of the BufferQueue interfaces for those sources
628        switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
629        case SL_DATALOCATOR_BUFFERQUEUE:
630#ifdef ANDROID
631        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
632#endif
633            break;
634        default:
635            // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
636            // if the data sink is not a buffer queue
637            index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
638#ifdef ANDROID
639            assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
640#endif
641            if (0 <= index) {
642                if (requiredMask & (1 << index)) {
643                    SL_LOGE("can't require SL_IID_BUFFERQUEUE "
644#ifdef ANDROID
645                            "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
646#endif
647                            "with a non-buffer queue data sink");
648                    return SL_RESULT_FEATURE_UNSUPPORTED;
649                }
650            }
651            break;
652        }
653        break;
654
655    case SL_DATALOCATOR_BUFFERQUEUE:
656#ifdef ANDROID
657    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
658#endif
659        // can't require SLSeekItf if data source is a buffer queue
660        index = clazz->mMPH_to_index[MPH_SEEK];
661        if (0 <= index) {
662            if (requiredMask & (1 << index)) {
663                SL_LOGE("can't require SL_IID_SEEK with a buffer queue data source");
664                return SL_RESULT_FEATURE_UNSUPPORTED;
665            }
666        }
667        // can't require SLMuteSoloItf if data source is a mono buffer queue
668        index = clazz->mMPH_to_index[MPH_MUTESOLO];
669        if (0 <= index) {
670            if ((requiredMask & (1 << index)) &&
671                    (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) &&
672                    (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) {
673                SL_LOGE("can't require SL_IID_MUTESOLO with a mono buffer queue data source");
674                return SL_RESULT_FEATURE_UNSUPPORTED;
675            }
676        }
677        break;
678
679#ifdef ANDROID
680    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
681        // can't require SLSeekItf if data source is an Android buffer queue
682        index = clazz->mMPH_to_index[MPH_SEEK];
683        if (0 <= index) {
684            if (requiredMask & (1 << index)) {
685                SL_LOGE("can't require SL_IID_SEEK with a SL_DATALOCATOR_ANDROIDBUFFERQUEUE "\
686                        "source");
687                return SL_RESULT_FEATURE_UNSUPPORTED;
688            }
689        }
690        switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
691        // for use-case AAC decode from SLAndroidBufferQueueItf with AAC ADTS data
692        case SL_DATALOCATOR_BUFFERQUEUE:
693        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
694            break;
695        // for use-case audio playback from SLAndroidBufferQueueItf with MP2TS data
696        case SL_DATALOCATOR_OUTPUTMIX:
697            break;
698        default:
699            SL_LOGE("Invalid sink for SL_DATALOCATOR_ANDROIDBUFFERQUEUE source");
700            return SL_RESULT_FEATURE_UNSUPPORTED;
701            break;
702        }
703        break;
704#endif
705    case SL_DATALOCATOR_ADDRESS:
706    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
707    case XA_DATALOCATOR_NATIVEDISPLAY:
708        // any special checks here???
709    default:
710        // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
711        // if the data source is not a buffer queue
712        index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
713#ifdef ANDROID
714        assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
715#endif
716        if (0 <= index) {
717            if (requiredMask & (1 << index)) {
718                SL_LOGE("can't require SL_IID_BUFFERQUEUE "
719#ifdef ANDROID
720                        "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
721#endif
722                        "with a non-buffer queue data source");
723                return SL_RESULT_FEATURE_UNSUPPORTED;
724            }
725        }
726        break;
727    }
728    return SL_RESULT_SUCCESS;
729}
730
731
732/** \brief Free the local deep copy of a data format */
733
734static void freeDataFormat(DataFormat *pDataFormat)
735{
736    switch (pDataFormat->mFormatType) {
737    case SL_DATAFORMAT_MIME:
738        if (NULL != pDataFormat->mMIME.mimeType) {
739            free(pDataFormat->mMIME.mimeType);
740            pDataFormat->mMIME.mimeType = NULL;
741        }
742        break;
743    case SL_ANDROID_DATAFORMAT_PCM_EX:
744    case SL_DATAFORMAT_PCM:
745    case XA_DATAFORMAT_RAWIMAGE:
746    case SL_DATAFORMAT_NULL:
747        break;
748    default:
749        // an invalid data format is caught earlier during the copy
750        assert(false);
751        break;
752    }
753}
754
755
756/** \brief Check a data source and make local deep copy */
757
758SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc,
759        DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
760        SLuint32 allowedDataFormatMask)
761{
762    assert(NULL != name && NULL != pDataLocatorFormat);
763    pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator;
764    pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat;
765
766    if (NULL == pDataSrc) {
767        pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
768        pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
769        if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
770                (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
771            return SL_RESULT_SUCCESS;
772        }
773        SL_LOGE("%s: data source cannot be NULL", name);
774        return SL_RESULT_PARAMETER_INVALID;
775    }
776    SLDataSource myDataSrc = *pDataSrc;
777    SLresult result;
778    result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator,
779            allowedDataLocatorMask);
780    if (SL_RESULT_SUCCESS != result) {
781        return result;
782    }
783
784    switch (pDataLocatorFormat->mLocator.mLocatorType) {
785    case SL_DATALOCATOR_URI:
786        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
787        break;
788    case SL_DATALOCATOR_ADDRESS:
789    case SL_DATALOCATOR_BUFFERQUEUE:
790        allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
791        break;
792    // Per the spec, the pFormat field is ignored in some cases
793    case SL_DATALOCATOR_IODEVICE:
794        myDataSrc.pFormat = NULL;
795        // fall through
796    case SL_DATALOCATOR_NULL:
797    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
798        allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
799        break;
800    case SL_DATALOCATOR_OUTPUTMIX:
801    case XA_DATALOCATOR_NATIVEDISPLAY:
802        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
803        break;
804#ifdef ANDROID
805    case SL_DATALOCATOR_ANDROIDFD:
806        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
807        break;
808    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
809        allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
810        break;
811    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
812        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;;
813        break;
814#endif
815    default:
816        // invalid data locator type is caught earlier
817        assert(false);
818        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
819        break;
820    }
821
822    result = checkDataFormat(name,
823                             myDataSrc.pFormat,
824                             &pDataLocatorFormat->mFormat,
825                             allowedDataFormatMask,
826                             SL_BOOLEAN_TRUE /*isOutputFormat*/);
827    if (SL_RESULT_SUCCESS != result) {
828        freeDataLocator(&pDataLocatorFormat->mLocator);
829        return result;
830    }
831
832    return SL_RESULT_SUCCESS;
833}
834
835
836/** \brief Check a data sink and make local deep copy */
837
838SLresult checkDataSink(const char *name, const SLDataSink *pDataSink,
839        DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
840        SLuint32 allowedDataFormatMask)
841{
842    assert(NULL != name && NULL != pDataLocatorFormat);
843    pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator;
844    pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat;
845
846    if (NULL == pDataSink) {
847        pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
848        pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
849        if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
850                (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
851            return SL_RESULT_SUCCESS;
852        }
853        SL_LOGE("%s: data sink cannot be NULL", name);
854        return SL_RESULT_PARAMETER_INVALID;
855    }
856    SLDataSink myDataSink = *pDataSink;
857    SLresult result;
858    result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator,
859            allowedDataLocatorMask);
860    if (SL_RESULT_SUCCESS != result) {
861        return result;
862    }
863
864    switch (pDataLocatorFormat->mLocator.mLocatorType) {
865    case SL_DATALOCATOR_URI:
866        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
867        break;
868    case SL_DATALOCATOR_ADDRESS:
869    case SL_DATALOCATOR_BUFFERQUEUE:
870        allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
871        break;
872    // Per the spec, the pFormat field is ignored in some cases
873    case SL_DATALOCATOR_IODEVICE:
874    case SL_DATALOCATOR_OUTPUTMIX:
875    case XA_DATALOCATOR_NATIVEDISPLAY:
876        myDataSink.pFormat = NULL;
877        // fall through
878    case SL_DATALOCATOR_NULL:
879    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
880        allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
881        break;
882#ifdef ANDROID
883    case SL_DATALOCATOR_ANDROIDFD:
884        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
885        break;
886    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
887        allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
888        break;
889    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
890        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
891        break;
892#endif
893    default:
894        // invalid data locator type is caught earlier
895        assert(false);
896        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
897        break;
898    }
899
900    result = checkDataFormat(name,
901            myDataSink.pFormat,
902            &pDataLocatorFormat->mFormat,
903            allowedDataFormatMask,
904            SL_BOOLEAN_FALSE /*isOutputFormat*/);
905
906    if (SL_RESULT_SUCCESS != result) {
907        freeDataLocator(&pDataLocatorFormat->mLocator);
908        return result;
909    }
910
911    return SL_RESULT_SUCCESS;
912}
913
914
915/** \brief Free the local deep copy of a data locator format */
916
917void freeDataLocatorFormat(DataLocatorFormat *dlf)
918{
919    assert(NULL != dlf);
920    freeDataLocator(&dlf->mLocator);
921    freeDataFormat(&dlf->mFormat);
922}
923