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 #endif 23 24 25 /** \brief Check a data locator and make local deep copy */ 26 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 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 339 static SLresult checkDataFormat(const char *name, void *pFormat, DataFormat *pDataFormat, 340 SLuint32 allowedDataFormatMask) 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 case SL_DATAFORMAT_PCM: 368 pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat; 369 do { 370 371 // check the channel count 372 // FIXME FCC_8 Android and 8-channel positional assumptions here 373 switch (pDataFormat->mPCM.numChannels) { 374 case 1: // mono 375 case 2: // stereo 376 case 3: // stereo + front center 377 case 4: // QUAD 378 case 5: // QUAD + front center 379 case 6: // 5.1 380 case 7: // 5.1 + back center 381 case 8: // 7.1 382 break; 383 case 0: // unknown 384 result = SL_RESULT_PARAMETER_INVALID; 385 break; 386 default: // multi-channel 387 result = SL_RESULT_CONTENT_UNSUPPORTED; 388 break; 389 } 390 if (SL_RESULT_SUCCESS != result) { 391 SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels); 392 break; 393 } 394 395 // check the sampling rate 396 if (pDataFormat->mPCM.samplesPerSec == 0) { 397 result = SL_RESULT_PARAMETER_INVALID; 398 } else if (pDataFormat->mPCM.samplesPerSec < SL_SAMPLINGRATE_8 || 399 pDataFormat->mPCM.samplesPerSec > SL_SAMPLINGRATE_192) { 400 result = SL_RESULT_CONTENT_UNSUPPORTED; 401 } 402 if (SL_RESULT_SUCCESS != result) { 403 SL_LOGE("%s: samplesPerSec=%u", name, pDataFormat->mPCM.samplesPerSec); 404 break; 405 } 406 407 // check the container bit depth and representation 408 switch (pDataFormat->mPCM.containerSize) { 409 case 8: 410 if (df_representation != NULL && 411 *df_representation != SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT) { 412 result = SL_RESULT_PARAMETER_INVALID; 413 } 414 break; 415 case 16: 416 case 24: 417 if (df_representation != NULL && 418 *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT) { 419 result = SL_RESULT_PARAMETER_INVALID; 420 } 421 break; 422 case 32: 423 if (df_representation != NULL 424 && *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT 425 && *df_representation != SL_ANDROID_PCM_REPRESENTATION_FLOAT) { 426 result = SL_RESULT_PARAMETER_INVALID; 427 } 428 break; 429 default: 430 result = SL_RESULT_PARAMETER_INVALID; 431 break; 432 } 433 if (SL_RESULT_SUCCESS != result) { 434 SL_LOGE("%s: containerSize=%u", name, pDataFormat->mPCM.containerSize); 435 break; 436 } 437 438 // sample size cannot be zero, and container size cannot be less than sample size 439 if (pDataFormat->mPCM.bitsPerSample == 0 || 440 pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) { 441 result = SL_RESULT_PARAMETER_INVALID; 442 } 443 if (SL_RESULT_SUCCESS != result) { 444 SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name, 445 (unsigned) pDataFormat->mPCM.containerSize, 446 (unsigned) pDataFormat->mPCM.bitsPerSample); 447 break; 448 } 449 450 // check the channel mask 451 // FIXME FCC_8 Android and 8-channel positional assumptions here 452 switch (pDataFormat->mPCM.channelMask) { 453 case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT: 454 if (2 != pDataFormat->mPCM.numChannels) { 455 result = SL_RESULT_PARAMETER_INVALID; 456 } 457 break; 458 case SL_SPEAKER_FRONT_LEFT: 459 case SL_SPEAKER_FRONT_RIGHT: 460 case SL_SPEAKER_FRONT_CENTER: 461 if (1 != pDataFormat->mPCM.numChannels) { 462 result = SL_RESULT_PARAMETER_INVALID; 463 } 464 break; 465 #ifdef ANDROID 466 case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER: 467 if (3 != pDataFormat->mPCM.numChannels) { 468 result = SL_RESULT_PARAMETER_INVALID; 469 } 470 break; 471 case SL_ANDROID_SPEAKER_QUAD: 472 if (4 != pDataFormat->mPCM.numChannels) { 473 result = SL_RESULT_PARAMETER_INVALID; 474 } 475 break; 476 case SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER: 477 if (5 != pDataFormat->mPCM.numChannels) { 478 result = SL_RESULT_PARAMETER_INVALID; 479 } 480 break; 481 case SL_ANDROID_SPEAKER_5DOT1: 482 if (6 != pDataFormat->mPCM.numChannels) { 483 result = SL_RESULT_PARAMETER_INVALID; 484 } 485 break; 486 case SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_BACK_CENTER: 487 if (7 != pDataFormat->mPCM.numChannels) { 488 result = SL_RESULT_PARAMETER_INVALID; 489 } 490 break; 491 case SL_ANDROID_SPEAKER_7DOT1: 492 if (8 != pDataFormat->mPCM.numChannels) { 493 result = SL_RESULT_PARAMETER_INVALID; 494 } 495 break; 496 #endif 497 case 0: { 498 // According to OpenSL ES 1.0.1 section 9.1.7 SLDataFormat_PCM, "a default 499 // setting of zero indicates stereo format (i.e. the setting is equivalent to 500 // SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT)." 501 // 502 // ANDROID SPECIFIC BEHAVIOR. 503 // We fill in the appropriate mask to the number indicated by numChannels. 504 // The default of front left rather than center for mono may be non-intuitive, 505 // but the left channel is the first channel for stereo or multichannel content. 506 SLuint32 mask = channelCountToMask(pDataFormat->mPCM.numChannels); 507 if (mask == UNKNOWN_CHANNELMASK) { 508 result = SL_RESULT_PARAMETER_INVALID; 509 } else { 510 pDataFormat->mPCM.channelMask = mask; 511 } 512 } break; 513 default: 514 result = SL_RESULT_PARAMETER_INVALID; 515 break; 516 } 517 if (SL_RESULT_SUCCESS != result) { 518 SL_LOGE("%s: channelMask=0x%x numChannels=%u", name, 519 pDataFormat->mPCM.channelMask, pDataFormat->mPCM.numChannels); 520 break; 521 } 522 523 // check the endianness / byte order 524 switch (pDataFormat->mPCM.endianness) { 525 case SL_BYTEORDER_LITTLEENDIAN: 526 case SL_BYTEORDER_BIGENDIAN: 527 break; 528 // native is proposed but not yet in spec 529 default: 530 result = SL_RESULT_PARAMETER_INVALID; 531 break; 532 } 533 if (SL_RESULT_SUCCESS != result) { 534 SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness); 535 break; 536 } 537 538 // here if all checks passed successfully 539 540 } while(0); 541 break; 542 543 case SL_DATAFORMAT_MIME: 544 pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat; 545 if (NULL != pDataFormat->mMIME.mimeType) { 546 // NTH check address for validity 547 size_t len = strlen((const char *) pDataFormat->mMIME.mimeType); 548 SLchar *myMIME = (SLchar *) malloc(len + 1); 549 if (NULL == myMIME) { 550 result = SL_RESULT_MEMORY_FAILURE; 551 } else { 552 memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1); 553 // make sure MIME string was not modified asynchronously 554 if ('\0' != myMIME[len]) { 555 free(myMIME); 556 myMIME = NULL; 557 result = SL_RESULT_PRECONDITIONS_VIOLATED; 558 } 559 } 560 pDataFormat->mMIME.mimeType = myMIME; 561 } 562 break; 563 564 case XA_DATAFORMAT_RAWIMAGE: 565 pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat; 566 switch (pDataFormat->mRawImage.colorFormat) { 567 case XA_COLORFORMAT_MONOCHROME: 568 case XA_COLORFORMAT_8BITRGB332: 569 case XA_COLORFORMAT_12BITRGB444: 570 case XA_COLORFORMAT_16BITARGB4444: 571 case XA_COLORFORMAT_16BITARGB1555: 572 case XA_COLORFORMAT_16BITRGB565: 573 case XA_COLORFORMAT_16BITBGR565: 574 case XA_COLORFORMAT_18BITRGB666: 575 case XA_COLORFORMAT_18BITARGB1665: 576 case XA_COLORFORMAT_19BITARGB1666: 577 case XA_COLORFORMAT_24BITRGB888: 578 case XA_COLORFORMAT_24BITBGR888: 579 case XA_COLORFORMAT_24BITARGB1887: 580 case XA_COLORFORMAT_25BITARGB1888: 581 case XA_COLORFORMAT_32BITBGRA8888: 582 case XA_COLORFORMAT_32BITARGB8888: 583 case XA_COLORFORMAT_YUV411PLANAR: 584 case XA_COLORFORMAT_YUV420PLANAR: 585 case XA_COLORFORMAT_YUV420SEMIPLANAR: 586 case XA_COLORFORMAT_YUV422PLANAR: 587 case XA_COLORFORMAT_YUV422SEMIPLANAR: 588 case XA_COLORFORMAT_YCBYCR: 589 case XA_COLORFORMAT_YCRYCB: 590 case XA_COLORFORMAT_CBYCRY: 591 case XA_COLORFORMAT_CRYCBY: 592 case XA_COLORFORMAT_YUV444INTERLEAVED: 593 case XA_COLORFORMAT_RAWBAYER8BIT: 594 case XA_COLORFORMAT_RAWBAYER10BIT: 595 case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED: 596 case XA_COLORFORMAT_L2: 597 case XA_COLORFORMAT_L4: 598 case XA_COLORFORMAT_L8: 599 case XA_COLORFORMAT_L16: 600 case XA_COLORFORMAT_L24: 601 case XA_COLORFORMAT_L32: 602 case XA_COLORFORMAT_18BITBGR666: 603 case XA_COLORFORMAT_24BITARGB6666: 604 case XA_COLORFORMAT_24BITABGR6666: 605 break; 606 case XA_COLORFORMAT_UNUSED: 607 default: 608 result = XA_RESULT_PARAMETER_INVALID; 609 SL_LOGE("%s: unsupported color format %d", name, 610 pDataFormat->mRawImage.colorFormat); 611 break; 612 } 613 // no checks for height, width, or stride 614 break; 615 616 default: 617 result = SL_RESULT_PARAMETER_INVALID; 618 SL_LOGE("%s: formatType=%u", name, (unsigned) formatType); 619 break; 620 621 } 622 623 // make sure format type was not modified asynchronously 624 if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) { 625 SL_LOGE("%s: formatType changed from %u to %u", name, formatType, 626 pDataFormat->mFormatType); 627 result = SL_RESULT_PRECONDITIONS_VIOLATED; 628 } 629 630 } 631 632 // Verify that the data format type is allowed in this context 633 if (SL_RESULT_SUCCESS == result) { 634 SLuint32 actualMask; 635 switch (formatType) { 636 case SL_DATAFORMAT_NULL: 637 case SL_DATAFORMAT_MIME: 638 case SL_DATAFORMAT_PCM: 639 case SL_ANDROID_DATAFORMAT_PCM_EX: 640 case XA_DATAFORMAT_RAWIMAGE: 641 actualMask = 1L << formatType; 642 break; 643 default: 644 assert(false); 645 actualMask = 0L; 646 break; 647 } 648 if (!(allowedDataFormatMask & actualMask)) { 649 SL_LOGE("%s: data format %d not allowed", name, formatType); 650 result = SL_RESULT_CONTENT_UNSUPPORTED; 651 } 652 } 653 654 return result; 655 } 656 657 658 /** \brief Check interface ID compatibility with respect to a particular source 659 * and sink data locator format 660 */ 661 662 SLresult checkSourceSinkVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat, 663 const DataLocatorFormat *pSinkDataLocatorFormat, 664 const ClassTable *clazz, unsigned requiredMask) { 665 int index; 666 switch (pSrcDataLocatorFormat->mLocator.mLocatorType) { 667 case SL_DATALOCATOR_URI: 668 #ifdef ANDROID 669 case SL_DATALOCATOR_ANDROIDFD: 670 #endif 671 // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode 672 // so we don't prevent the retrieval of the BufferQueue interfaces for those sources 673 switch (pSinkDataLocatorFormat->mLocator.mLocatorType) { 674 case SL_DATALOCATOR_BUFFERQUEUE: 675 #ifdef ANDROID 676 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 677 #endif 678 break; 679 default: 680 // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf 681 // if the data sink is not a buffer queue 682 index = clazz->mMPH_to_index[MPH_BUFFERQUEUE]; 683 #ifdef ANDROID 684 assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]); 685 #endif 686 if (0 <= index) { 687 if (requiredMask & (1 << index)) { 688 SL_LOGE("can't require SL_IID_BUFFERQUEUE " 689 #ifdef ANDROID 690 "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE " 691 #endif 692 "with a non-buffer queue data sink"); 693 return SL_RESULT_FEATURE_UNSUPPORTED; 694 } 695 } 696 break; 697 } 698 break; 699 700 case SL_DATALOCATOR_BUFFERQUEUE: 701 #ifdef ANDROID 702 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 703 #endif 704 // can't require SLSeekItf if data source is a buffer queue 705 index = clazz->mMPH_to_index[MPH_SEEK]; 706 if (0 <= index) { 707 if (requiredMask & (1 << index)) { 708 SL_LOGE("can't require SL_IID_SEEK with a buffer queue data source"); 709 return SL_RESULT_FEATURE_UNSUPPORTED; 710 } 711 } 712 // can't require SLMuteSoloItf if data source is a mono buffer queue 713 index = clazz->mMPH_to_index[MPH_MUTESOLO]; 714 if (0 <= index) { 715 if ((requiredMask & (1 << index)) && 716 (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) && 717 (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) { 718 SL_LOGE("can't require SL_IID_MUTESOLO with a mono buffer queue data source"); 719 return SL_RESULT_FEATURE_UNSUPPORTED; 720 } 721 } 722 break; 723 724 #ifdef ANDROID 725 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 726 // can't require SLSeekItf if data source is an Android buffer queue 727 index = clazz->mMPH_to_index[MPH_SEEK]; 728 if (0 <= index) { 729 if (requiredMask & (1 << index)) { 730 SL_LOGE("can't require SL_IID_SEEK with a SL_DATALOCATOR_ANDROIDBUFFERQUEUE "\ 731 "source"); 732 return SL_RESULT_FEATURE_UNSUPPORTED; 733 } 734 } 735 switch (pSinkDataLocatorFormat->mLocator.mLocatorType) { 736 // for use-case AAC decode from SLAndroidBufferQueueItf with AAC ADTS data 737 case SL_DATALOCATOR_BUFFERQUEUE: 738 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 739 break; 740 // for use-case audio playback from SLAndroidBufferQueueItf with MP2TS data 741 case SL_DATALOCATOR_OUTPUTMIX: 742 break; 743 default: 744 SL_LOGE("Invalid sink for SL_DATALOCATOR_ANDROIDBUFFERQUEUE source"); 745 return SL_RESULT_FEATURE_UNSUPPORTED; 746 break; 747 } 748 break; 749 #endif 750 case SL_DATALOCATOR_ADDRESS: 751 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 752 case XA_DATALOCATOR_NATIVEDISPLAY: 753 // any special checks here??? 754 default: 755 // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf 756 // if the data source is not a buffer queue 757 index = clazz->mMPH_to_index[MPH_BUFFERQUEUE]; 758 #ifdef ANDROID 759 assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]); 760 #endif 761 if (0 <= index) { 762 if (requiredMask & (1 << index)) { 763 SL_LOGE("can't require SL_IID_BUFFERQUEUE " 764 #ifdef ANDROID 765 "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE " 766 #endif 767 "with a non-buffer queue data source"); 768 return SL_RESULT_FEATURE_UNSUPPORTED; 769 } 770 } 771 break; 772 } 773 return SL_RESULT_SUCCESS; 774 } 775 776 777 /** \brief Free the local deep copy of a data format */ 778 779 static void freeDataFormat(DataFormat *pDataFormat) 780 { 781 switch (pDataFormat->mFormatType) { 782 case SL_DATAFORMAT_MIME: 783 if (NULL != pDataFormat->mMIME.mimeType) { 784 free(pDataFormat->mMIME.mimeType); 785 pDataFormat->mMIME.mimeType = NULL; 786 } 787 break; 788 case SL_ANDROID_DATAFORMAT_PCM_EX: 789 case SL_DATAFORMAT_PCM: 790 case XA_DATAFORMAT_RAWIMAGE: 791 case SL_DATAFORMAT_NULL: 792 break; 793 default: 794 // an invalid data format is caught earlier during the copy 795 assert(false); 796 break; 797 } 798 } 799 800 801 /** \brief Check a data source and make local deep copy */ 802 803 SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc, 804 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 805 SLuint32 allowedDataFormatMask) 806 { 807 assert(NULL != name && NULL != pDataLocatorFormat); 808 pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 809 pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 810 811 if (NULL == pDataSrc) { 812 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 813 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 814 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 815 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 816 return SL_RESULT_SUCCESS; 817 } 818 SL_LOGE("%s: data source cannot be NULL", name); 819 return SL_RESULT_PARAMETER_INVALID; 820 } 821 SLDataSource myDataSrc = *pDataSrc; 822 SLresult result; 823 result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator, 824 allowedDataLocatorMask); 825 if (SL_RESULT_SUCCESS != result) { 826 return result; 827 } 828 829 switch (pDataLocatorFormat->mLocator.mLocatorType) { 830 case SL_DATALOCATOR_URI: 831 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 832 break; 833 case SL_DATALOCATOR_ADDRESS: 834 case SL_DATALOCATOR_BUFFERQUEUE: 835 allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX; 836 break; 837 // Per the spec, the pFormat field is ignored in some cases 838 case SL_DATALOCATOR_IODEVICE: 839 myDataSrc.pFormat = NULL; 840 // fall through 841 case SL_DATALOCATOR_NULL: 842 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 843 allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 844 break; 845 case SL_DATALOCATOR_OUTPUTMIX: 846 case XA_DATALOCATOR_NATIVEDISPLAY: 847 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 848 break; 849 #ifdef ANDROID 850 case SL_DATALOCATOR_ANDROIDFD: 851 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 852 break; 853 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 854 allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX; 855 break; 856 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 857 allowedDataFormatMask &= DATAFORMAT_MASK_MIME;; 858 break; 859 #endif 860 default: 861 // invalid data locator type is caught earlier 862 assert(false); 863 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 864 break; 865 } 866 867 result = checkDataFormat(name, myDataSrc.pFormat, &pDataLocatorFormat->mFormat, 868 allowedDataFormatMask); 869 if (SL_RESULT_SUCCESS != result) { 870 freeDataLocator(&pDataLocatorFormat->mLocator); 871 return result; 872 } 873 874 return SL_RESULT_SUCCESS; 875 } 876 877 878 /** \brief Check a data sink and make local deep copy */ 879 880 SLresult checkDataSink(const char *name, const SLDataSink *pDataSink, 881 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 882 SLuint32 allowedDataFormatMask) 883 { 884 assert(NULL != name && NULL != pDataLocatorFormat); 885 pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 886 pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 887 888 if (NULL == pDataSink) { 889 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 890 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 891 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 892 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 893 return SL_RESULT_SUCCESS; 894 } 895 SL_LOGE("%s: data sink cannot be NULL", name); 896 return SL_RESULT_PARAMETER_INVALID; 897 } 898 SLDataSink myDataSink = *pDataSink; 899 SLresult result; 900 result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator, 901 allowedDataLocatorMask); 902 if (SL_RESULT_SUCCESS != result) { 903 return result; 904 } 905 906 switch (pDataLocatorFormat->mLocator.mLocatorType) { 907 case SL_DATALOCATOR_URI: 908 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 909 break; 910 case SL_DATALOCATOR_ADDRESS: 911 case SL_DATALOCATOR_BUFFERQUEUE: 912 allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX; 913 break; 914 // Per the spec, the pFormat field is ignored in some cases 915 case SL_DATALOCATOR_IODEVICE: 916 case SL_DATALOCATOR_OUTPUTMIX: 917 case XA_DATALOCATOR_NATIVEDISPLAY: 918 myDataSink.pFormat = NULL; 919 // fall through 920 case SL_DATALOCATOR_NULL: 921 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 922 allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 923 break; 924 #ifdef ANDROID 925 case SL_DATALOCATOR_ANDROIDFD: 926 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 927 break; 928 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 929 allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX; 930 break; 931 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 932 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 933 break; 934 #endif 935 default: 936 // invalid data locator type is caught earlier 937 assert(false); 938 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 939 break; 940 } 941 942 result = checkDataFormat(name, myDataSink.pFormat, &pDataLocatorFormat->mFormat, 943 allowedDataFormatMask); 944 if (SL_RESULT_SUCCESS != result) { 945 freeDataLocator(&pDataLocatorFormat->mLocator); 946 return result; 947 } 948 949 return SL_RESULT_SUCCESS; 950 } 951 952 953 /** \brief Free the local deep copy of a data locator format */ 954 955 void freeDataLocatorFormat(DataLocatorFormat *dlf) 956 { 957 assert(NULL != dlf); 958 freeDataLocator(&dlf->mLocator); 959 freeDataFormat(&dlf->mFormat); 960 } 961