data.c revision a8179ea15c4ff78db589d742b135649f0eda7ef2
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 * data locator format 594 */ 595 596SLresult checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat, 597 const ClassTable *clazz, unsigned exposedMask) { 598 int index; 599 switch (pSrcDataLocatorFormat->mLocator.mLocatorType) { 600 case SL_DATALOCATOR_URI: 601#ifdef ANDROID 602 case SL_DATALOCATOR_ANDROIDFD: 603#endif 604 // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode 605 // so we don't prevent the retrieval of the BufferQueue interfaces for those sources 606 break; 607 608 case SL_DATALOCATOR_BUFFERQUEUE: 609#ifdef ANDROID 610 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 611#endif 612 // can't request SLSeekItf if data source is a buffer queue 613 index = clazz->mMPH_to_index[MPH_SEEK]; 614 if (0 <= index) { 615 if (exposedMask & (1 << index)) { 616 SL_LOGE("can't request SL_IID_SEEK with a buffer queue data source"); 617 return SL_RESULT_FEATURE_UNSUPPORTED; 618 } 619 } 620 // can't request SLMuteSoloItf if data source is a mono buffer queue 621 index = clazz->mMPH_to_index[MPH_MUTESOLO]; 622 if (0 <= index) { 623 if ((exposedMask & (1 << index)) && 624 (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) && 625 (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) { 626 SL_LOGE("can't request SL_IID_MUTESOLO with a mono buffer queue data source"); 627 return SL_RESULT_FEATURE_UNSUPPORTED; 628 } 629 } 630 break; 631 632#ifdef ANDROID 633 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 634#endif 635 case SL_DATALOCATOR_ADDRESS: 636 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 637 case XA_DATALOCATOR_NATIVEDISPLAY: 638 // any special checks here??? 639 default: 640 // can't request SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf 641 // if the data source is not a buffer queue 642 index = clazz->mMPH_to_index[MPH_BUFFERQUEUE]; 643#ifdef ANDROID 644 assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]); 645#endif 646 if (0 <= index) { 647 if (exposedMask & (1 << index)) { 648 SL_LOGE("can't request SL_IID_BUFFERQUEUE " 649#ifdef ANDROID 650 "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE " 651#endif 652 "with a non-buffer queue data source"); 653 return SL_RESULT_FEATURE_UNSUPPORTED; 654 } 655 } 656 break; 657 } 658 return SL_RESULT_SUCCESS; 659} 660 661 662/** \brief Free the local deep copy of a data format */ 663 664static void freeDataFormat(DataFormat *pDataFormat) 665{ 666 switch (pDataFormat->mFormatType) { 667 case SL_DATAFORMAT_MIME: 668 if (NULL != pDataFormat->mMIME.mimeType) { 669 free(pDataFormat->mMIME.mimeType); 670 pDataFormat->mMIME.mimeType = NULL; 671 } 672 break; 673 case SL_DATAFORMAT_PCM: 674 case XA_DATAFORMAT_RAWIMAGE: 675 case SL_DATAFORMAT_NULL: 676 break; 677 default: 678 // an invalid data format is caught earlier during the copy 679 assert(false); 680 break; 681 } 682} 683 684 685/** \brief Check a data source and make local deep copy */ 686 687SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc, 688 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 689 SLuint32 allowedDataFormatMask) 690{ 691 assert(NULL != name && NULL != pDataLocatorFormat); 692 pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 693 pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 694 695 if (NULL == pDataSrc) { 696 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 697 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 698 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 699 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 700 return SL_RESULT_SUCCESS; 701 } 702 SL_LOGE("%s: data source cannot be NULL", name); 703 return SL_RESULT_PARAMETER_INVALID; 704 } 705 SLDataSource myDataSrc = *pDataSrc; 706 SLresult result; 707 result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator, 708 allowedDataLocatorMask); 709 if (SL_RESULT_SUCCESS != result) { 710 return result; 711 } 712 713 switch (pDataLocatorFormat->mLocator.mLocatorType) { 714 case SL_DATALOCATOR_URI: 715 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 716 break; 717 case SL_DATALOCATOR_ADDRESS: 718 case SL_DATALOCATOR_BUFFERQUEUE: 719 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 720 break; 721 // Per the spec, the pFormat field is ignored in some cases 722 case SL_DATALOCATOR_IODEVICE: 723 myDataSrc.pFormat = NULL; 724 // fall through 725 case SL_DATALOCATOR_NULL: 726 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 727 allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 728 break; 729 case SL_DATALOCATOR_OUTPUTMIX: 730 case XA_DATALOCATOR_NATIVEDISPLAY: 731 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 732 break; 733#ifdef ANDROID 734 case SL_DATALOCATOR_ANDROIDFD: 735 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 736 break; 737 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 738 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 739 break; 740 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 741 allowedDataFormatMask &= DATAFORMAT_MASK_MIME;; 742 break; 743#endif 744 default: 745 // invalid data locator type is caught earlier 746 assert(false); 747 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 748 break; 749 } 750 751 result = checkDataFormat(name, myDataSrc.pFormat, &pDataLocatorFormat->mFormat, 752 allowedDataFormatMask); 753 if (SL_RESULT_SUCCESS != result) { 754 freeDataLocator(&pDataLocatorFormat->mLocator); 755 return result; 756 } 757 758 return SL_RESULT_SUCCESS; 759} 760 761 762/** \brief Check a data sink and make local deep copy */ 763 764SLresult checkDataSink(const char *name, const SLDataSink *pDataSink, 765 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 766 SLuint32 allowedDataFormatMask) 767{ 768 assert(NULL != name && NULL != pDataLocatorFormat); 769 pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 770 pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 771 772 if (NULL == pDataSink) { 773 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 774 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 775 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 776 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 777 return SL_RESULT_SUCCESS; 778 } 779 SL_LOGE("%s: data sink cannot be NULL", name); 780 return SL_RESULT_PARAMETER_INVALID; 781 } 782 SLDataSink myDataSink = *pDataSink; 783 SLresult result; 784 result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator, 785 allowedDataLocatorMask); 786 if (SL_RESULT_SUCCESS != result) { 787 return result; 788 } 789 790 switch (pDataLocatorFormat->mLocator.mLocatorType) { 791 case SL_DATALOCATOR_URI: 792 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 793 break; 794 case SL_DATALOCATOR_ADDRESS: 795 case SL_DATALOCATOR_BUFFERQUEUE: 796 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 797 break; 798 // Per the spec, the pFormat field is ignored in some cases 799 case SL_DATALOCATOR_IODEVICE: 800 case SL_DATALOCATOR_OUTPUTMIX: 801 case XA_DATALOCATOR_NATIVEDISPLAY: 802 myDataSink.pFormat = NULL; 803 // fall through 804 case SL_DATALOCATOR_NULL: 805 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 806 allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 807 break; 808#ifdef ANDROID 809 case SL_DATALOCATOR_ANDROIDFD: 810 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 811 break; 812 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 813 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 814 break; 815 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 816 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 817 break; 818#endif 819 default: 820 // invalid data locator type is caught earlier 821 assert(false); 822 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 823 break; 824 } 825 826 result = checkDataFormat(name, myDataSink.pFormat, &pDataLocatorFormat->mFormat, 827 allowedDataFormatMask); 828 if (SL_RESULT_SUCCESS != result) { 829 freeDataLocator(&pDataLocatorFormat->mLocator); 830 return result; 831 } 832 833 return SL_RESULT_SUCCESS; 834} 835 836 837/** \brief Free the local deep copy of a data locator format */ 838 839void freeDataLocatorFormat(DataLocatorFormat *dlf) 840{ 841 assert(NULL != dlf); 842 freeDataLocator(&dlf->mLocator); 843 freeDataFormat(&dlf->mFormat); 844} 845