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