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