data.c revision ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8
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=%lu", 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=%lu", 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=%lu", 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=%lu", 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=%lu", 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=%lu", 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=%lu 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=%ld", 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 // if hDisplay is NULL, then hWindow is NDK C ANativeWindow * 174 // if hDisplay is non-NULL, then: 175 // hWindow is JNI jobject Surface or SurfaceTexture 176 // hDisplay is JNIENV * 177 if (pDataLocator->mNativeDisplay.hWindow == NULL) { 178 SL_LOGE("%s: hWindow must be non-NULL", name); 179 result = SL_RESULT_PARAMETER_INVALID; 180 } 181 break; 182 183 case SL_DATALOCATOR_URI: 184 { 185 pDataLocator->mURI = *(SLDataLocator_URI *)pLocator; 186 if (NULL == pDataLocator->mURI.URI) { 187 SL_LOGE("%s: invalid URI=NULL", name); 188 result = SL_RESULT_PARAMETER_INVALID; 189 } 190 // NTH verify URI address for validity 191 size_t len = strlen((const char *) pDataLocator->mURI.URI); 192 SLchar *myURI = (SLchar *) malloc(len + 1); 193 if (NULL == myURI) { 194 result = SL_RESULT_MEMORY_FAILURE; 195 } else { 196 memcpy(myURI, pDataLocator->mURI.URI, len + 1); 197 // Verify that another thread didn't change the NUL-terminator after we used it 198 // to determine length of string to copy. It's OK if the string became shorter. 199 if ('\0' != myURI[len]) { 200 free(myURI); 201 myURI = NULL; 202 result = SL_RESULT_PARAMETER_INVALID; 203 } 204 } 205 pDataLocator->mURI.URI = myURI; 206 } 207 break; 208 209#ifdef ANDROID 210 case SL_DATALOCATOR_ANDROIDFD: 211 { 212 pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator; 213 SL_LOGV("%s: fd=%ld offset=%lld length=%lld", name, pDataLocator->mFD.fd, 214 pDataLocator->mFD.offset, pDataLocator->mFD.length); 215 // NTH check against process fd limit 216 if (0 > pDataLocator->mFD.fd) { 217 SL_LOGE("%s: fd=%ld\n", name, pDataLocator->mFD.fd); 218 result = SL_RESULT_PARAMETER_INVALID; 219 } 220 break; 221 } 222 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 223 { 224 pDataLocator->mABQ = *(SLDataLocator_AndroidBufferQueue*)pLocator; 225 // number of buffers must be specified, there is no default value, and can't be too big 226 if (!((1 <= pDataLocator->mBufferQueue.numBuffers) && 227 (pDataLocator->mBufferQueue.numBuffers <= 255))) { 228 SL_LOGE("%s: numBuffers=%lu", name, pDataLocator->mABQ.numBuffers); 229 result = SL_RESULT_PARAMETER_INVALID; 230 } 231 break; 232 } 233#endif 234 235 case SL_DATALOCATOR_NULL: // a NULL pointer is allowed, but not a pointer to NULL 236 default: 237 SL_LOGE("%s: locatorType=%lu", name, locatorType); 238 result = SL_RESULT_PARAMETER_INVALID; 239 } 240 241 // Verify that another thread didn't change the locatorType field after we used it 242 // to determine sizeof struct to copy. 243 if ((SL_RESULT_SUCCESS == result) && (locatorType != pDataLocator->mLocatorType)) { 244 SL_LOGE("%s: locatorType changed from %lu to %lu", name, locatorType, 245 pDataLocator->mLocatorType); 246 result = SL_RESULT_PRECONDITIONS_VIOLATED; 247 } 248 249 } 250 251 // Verify that the data locator type is allowed in this context 252 if (SL_RESULT_SUCCESS == result) { 253 SLuint32 actualMask; 254 switch (locatorType) { 255 case SL_DATALOCATOR_NULL: 256 case SL_DATALOCATOR_URI: 257 case SL_DATALOCATOR_ADDRESS: 258 case SL_DATALOCATOR_IODEVICE: 259 case SL_DATALOCATOR_OUTPUTMIX: 260 case XA_DATALOCATOR_NATIVEDISPLAY: 261 case SL_DATALOCATOR_BUFFERQUEUE: 262 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 263 actualMask = 1L << locatorType; 264 break; 265#ifdef ANDROID 266 case SL_DATALOCATOR_ANDROIDFD: 267 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 268 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 269 actualMask = 0x100L << (locatorType - SL_DATALOCATOR_ANDROIDFD); 270 break; 271#endif 272 default: 273 assert(false); 274 actualMask = 0L; 275 break; 276 } 277 if (!(allowedDataLocatorMask & actualMask)) { 278 SL_LOGE("%s: data locator type 0x%lx not allowed", name, locatorType); 279 result = SL_RESULT_CONTENT_UNSUPPORTED; 280 } 281 } 282 283 return result; 284} 285 286 287/** \brief Free the local deep copy of a data locator */ 288 289static void freeDataLocator(DataLocator *pDataLocator) 290{ 291 switch (pDataLocator->mLocatorType) { 292 case SL_DATALOCATOR_NULL: 293 case SL_DATALOCATOR_ADDRESS: 294 case SL_DATALOCATOR_BUFFERQUEUE: 295 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 296 case XA_DATALOCATOR_NATIVEDISPLAY: 297 break; 298 case SL_DATALOCATOR_URI: 299 if (NULL != pDataLocator->mURI.URI) { 300 free(pDataLocator->mURI.URI); 301 pDataLocator->mURI.URI = NULL; 302 } 303 pDataLocator->mURI.URI = NULL; 304 break; 305 case SL_DATALOCATOR_IODEVICE: 306 if (NULL != pDataLocator->mIODevice.device) { 307 ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device); 308 pDataLocator->mIODevice.device = NULL; 309 } 310 break; 311 case SL_DATALOCATOR_OUTPUTMIX: 312 if (NULL != pDataLocator->mOutputMix.outputMix) { 313 ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix); 314 pDataLocator->mOutputMix.outputMix = NULL; 315 } 316 break; 317#ifdef ANDROID 318 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 319 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 320 case SL_DATALOCATOR_ANDROIDFD: 321 break; 322#endif 323 default: 324 // an invalid data locator is caught earlier when making the copy 325 assert(false); 326 break; 327 } 328} 329 330 331/** \brief Check a data format and make local deep copy */ 332 333static SLresult checkDataFormat(const char *name, void *pFormat, DataFormat *pDataFormat, 334 SLuint32 allowedDataFormatMask) 335{ 336 assert(NULL != name && NULL != pDataFormat); 337 SLresult result = SL_RESULT_SUCCESS; 338 339 SLuint32 formatType; 340 if (NULL == pFormat) { 341 pDataFormat->mFormatType = formatType = SL_DATAFORMAT_NULL; 342 } else { 343 formatType = *(SLuint32 *)pFormat; 344 switch (formatType) { 345 346 case SL_DATAFORMAT_PCM: 347 pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat; 348 do { 349 350 // check the channel count 351 switch (pDataFormat->mPCM.numChannels) { 352 case 1: // mono 353 case 2: // stereo 354 break; 355 case 0: // unknown 356 result = SL_RESULT_PARAMETER_INVALID; 357 break; 358 default: // multi-channel 359 result = SL_RESULT_CONTENT_UNSUPPORTED; 360 break; 361 } 362 if (SL_RESULT_SUCCESS != result) { 363 SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels); 364 break; 365 } 366 367 // check the sampling rate 368 switch (pDataFormat->mPCM.samplesPerSec) { 369 case SL_SAMPLINGRATE_8: 370 case SL_SAMPLINGRATE_11_025: 371 case SL_SAMPLINGRATE_12: 372 case SL_SAMPLINGRATE_16: 373 case SL_SAMPLINGRATE_22_05: 374 case SL_SAMPLINGRATE_24: 375 case SL_SAMPLINGRATE_32: 376 case SL_SAMPLINGRATE_44_1: 377 case SL_SAMPLINGRATE_48: 378 case SL_SAMPLINGRATE_64: 379 case SL_SAMPLINGRATE_88_2: 380 case SL_SAMPLINGRATE_96: 381 case SL_SAMPLINGRATE_192: 382 break; 383 case 0: 384 result = SL_RESULT_PARAMETER_INVALID; 385 break; 386 default: 387 result = SL_RESULT_CONTENT_UNSUPPORTED; 388 break; 389 } 390 if (SL_RESULT_SUCCESS != result) { 391 SL_LOGE("%s: samplesPerSec=%lu", name, pDataFormat->mPCM.samplesPerSec); 392 break; 393 } 394 395 // check the sample bit depth 396 switch (pDataFormat->mPCM.bitsPerSample) { 397 case SL_PCMSAMPLEFORMAT_FIXED_8: 398 case SL_PCMSAMPLEFORMAT_FIXED_16: 399 break; 400 case SL_PCMSAMPLEFORMAT_FIXED_20: 401 case SL_PCMSAMPLEFORMAT_FIXED_24: 402 case SL_PCMSAMPLEFORMAT_FIXED_28: 403 case SL_PCMSAMPLEFORMAT_FIXED_32: 404 result = SL_RESULT_CONTENT_UNSUPPORTED; 405 break; 406 default: 407 result = SL_RESULT_PARAMETER_INVALID; 408 break; 409 } 410 if (SL_RESULT_SUCCESS != result) { 411 SL_LOGE("%s: bitsPerSample=%lu", name, pDataFormat->mPCM.bitsPerSample); 412 break; 413 } 414 415 // check the container bit depth 416 if (pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) { 417 result = SL_RESULT_PARAMETER_INVALID; 418 } else if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) { 419 result = SL_RESULT_CONTENT_UNSUPPORTED; 420 } 421 if (SL_RESULT_SUCCESS != result) { 422 SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name, 423 (unsigned) pDataFormat->mPCM.containerSize, 424 (unsigned) pDataFormat->mPCM.bitsPerSample); 425 break; 426 } 427 428 // check the channel mask 429 switch (pDataFormat->mPCM.channelMask) { 430 case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT: 431 if (2 != pDataFormat->mPCM.numChannels) { 432 result = SL_RESULT_PARAMETER_INVALID; 433 } 434 break; 435 case SL_SPEAKER_FRONT_LEFT: 436 case SL_SPEAKER_FRONT_RIGHT: 437 case SL_SPEAKER_FRONT_CENTER: 438 if (1 != pDataFormat->mPCM.numChannels) { 439 result = SL_RESULT_PARAMETER_INVALID; 440 } 441 break; 442 case 0: 443 pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ? 444 SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER; 445 break; 446 default: 447 result = SL_RESULT_PARAMETER_INVALID; 448 break; 449 } 450 if (SL_RESULT_SUCCESS != result) { 451 SL_LOGE("%s: channelMask=0x%lx numChannels=%lu", name, 452 pDataFormat->mPCM.channelMask, pDataFormat->mPCM.numChannels); 453 break; 454 } 455 456 // check the endianness / byte order 457 switch (pDataFormat->mPCM.endianness) { 458 case SL_BYTEORDER_LITTLEENDIAN: 459 case SL_BYTEORDER_BIGENDIAN: 460 break; 461 // native is proposed but not yet in spec 462 default: 463 result = SL_RESULT_PARAMETER_INVALID; 464 break; 465 } 466 if (SL_RESULT_SUCCESS != result) { 467 SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness); 468 break; 469 } 470 471 // here if all checks passed successfully 472 473 } while(0); 474 break; 475 476 case SL_DATAFORMAT_MIME: 477 pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat; 478 if (NULL != pDataFormat->mMIME.mimeType) { 479 // NTH check address for validity 480 size_t len = strlen((const char *) pDataFormat->mMIME.mimeType); 481 SLchar *myMIME = (SLchar *) malloc(len + 1); 482 if (NULL == myMIME) { 483 result = SL_RESULT_MEMORY_FAILURE; 484 } else { 485 memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1); 486 // make sure MIME string was not modified asynchronously 487 if ('\0' != myMIME[len]) { 488 free(myMIME); 489 myMIME = NULL; 490 result = SL_RESULT_PRECONDITIONS_VIOLATED; 491 } 492 } 493 pDataFormat->mMIME.mimeType = myMIME; 494 } 495 break; 496 497 case XA_DATAFORMAT_RAWIMAGE: 498 pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat; 499 switch (pDataFormat->mRawImage.colorFormat) { 500 case XA_COLORFORMAT_MONOCHROME: 501 case XA_COLORFORMAT_8BITRGB332: 502 case XA_COLORFORMAT_12BITRGB444: 503 case XA_COLORFORMAT_16BITARGB4444: 504 case XA_COLORFORMAT_16BITARGB1555: 505 case XA_COLORFORMAT_16BITRGB565: 506 case XA_COLORFORMAT_16BITBGR565: 507 case XA_COLORFORMAT_18BITRGB666: 508 case XA_COLORFORMAT_18BITARGB1665: 509 case XA_COLORFORMAT_19BITARGB1666: 510 case XA_COLORFORMAT_24BITRGB888: 511 case XA_COLORFORMAT_24BITBGR888: 512 case XA_COLORFORMAT_24BITARGB1887: 513 case XA_COLORFORMAT_25BITARGB1888: 514 case XA_COLORFORMAT_32BITBGRA8888: 515 case XA_COLORFORMAT_32BITARGB8888: 516 case XA_COLORFORMAT_YUV411PLANAR: 517 case XA_COLORFORMAT_YUV420PLANAR: 518 case XA_COLORFORMAT_YUV420SEMIPLANAR: 519 case XA_COLORFORMAT_YUV422PLANAR: 520 case XA_COLORFORMAT_YUV422SEMIPLANAR: 521 case XA_COLORFORMAT_YCBYCR: 522 case XA_COLORFORMAT_YCRYCB: 523 case XA_COLORFORMAT_CBYCRY: 524 case XA_COLORFORMAT_CRYCBY: 525 case XA_COLORFORMAT_YUV444INTERLEAVED: 526 case XA_COLORFORMAT_RAWBAYER8BIT: 527 case XA_COLORFORMAT_RAWBAYER10BIT: 528 case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED: 529 case XA_COLORFORMAT_L2: 530 case XA_COLORFORMAT_L4: 531 case XA_COLORFORMAT_L8: 532 case XA_COLORFORMAT_L16: 533 case XA_COLORFORMAT_L24: 534 case XA_COLORFORMAT_L32: 535 case XA_COLORFORMAT_18BITBGR666: 536 case XA_COLORFORMAT_24BITARGB6666: 537 case XA_COLORFORMAT_24BITABGR6666: 538 break; 539 case XA_COLORFORMAT_UNUSED: 540 default: 541 result = XA_RESULT_PARAMETER_INVALID; 542 SL_LOGE("%s: unsupported color format %ld", name, 543 pDataFormat->mRawImage.colorFormat); 544 break; 545 } 546 // no checks for height, width, or stride 547 break; 548 549 default: 550 result = SL_RESULT_PARAMETER_INVALID; 551 SL_LOGE("%s: formatType=%u", name, (unsigned) formatType); 552 break; 553 554 } 555 556 // make sure format type was not modified asynchronously 557 if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) { 558 SL_LOGE("%s: formatType changed from %lu to %lu", name, formatType, 559 pDataFormat->mFormatType); 560 result = SL_RESULT_PRECONDITIONS_VIOLATED; 561 } 562 563 } 564 565 // Verify that the data format type is allowed in this context 566 if (SL_RESULT_SUCCESS == result) { 567 SLuint32 actualMask; 568 switch (formatType) { 569 case SL_DATAFORMAT_NULL: 570 case SL_DATAFORMAT_MIME: 571 case SL_DATAFORMAT_PCM: 572 case XA_DATAFORMAT_RAWIMAGE: 573 actualMask = 1L << formatType; 574 break; 575 default: 576 assert(false); 577 actualMask = 0L; 578 break; 579 } 580 if (!(allowedDataFormatMask & actualMask)) { 581 SL_LOGE("%s: data format %ld not allowed", name, formatType); 582 result = SL_RESULT_CONTENT_UNSUPPORTED; 583 } 584 } 585 586 return result; 587} 588 589 590/** \brief Check interface ID compatibility with respect to a particular source 591 * data locator format 592 */ 593 594SLresult checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat, 595 const ClassTable *clazz, unsigned exposedMask) { 596 int index; 597 switch (pSrcDataLocatorFormat->mLocator.mLocatorType) { 598 case SL_DATALOCATOR_URI: 599#ifdef ANDROID 600 case SL_DATALOCATOR_ANDROIDFD: 601#endif 602 // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode 603 // so we don't prevent the retrieval of the BufferQueue interfaces for those sources 604 break; 605 606 case SL_DATALOCATOR_BUFFERQUEUE: 607#ifdef ANDROID 608 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 609#endif 610 // can't request SLSeekItf if data source is a buffer queue 611 index = clazz->mMPH_to_index[MPH_SEEK]; 612 if (0 <= index) { 613 if (exposedMask & (1 << index)) { 614 SL_LOGE("can't request SL_IID_SEEK with a buffer queue data source"); 615 return SL_RESULT_FEATURE_UNSUPPORTED; 616 } 617 } 618 // can't request SLMuteSoloItf if data source is a mono buffer queue 619 index = clazz->mMPH_to_index[MPH_MUTESOLO]; 620 if (0 <= index) { 621 if ((exposedMask & (1 << index)) && 622 (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) && 623 (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) { 624 SL_LOGE("can't request SL_IID_MUTESOLO with a mono buffer queue data source"); 625 return SL_RESULT_FEATURE_UNSUPPORTED; 626 } 627 } 628 break; 629 630#ifdef ANDROID 631 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 632#endif 633 case SL_DATALOCATOR_ADDRESS: 634 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 635 case XA_DATALOCATOR_NATIVEDISPLAY: 636 // any special checks here??? 637 default: 638 // can't request SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf 639 // if the data source is not a buffer queue 640 index = clazz->mMPH_to_index[MPH_BUFFERQUEUE]; 641#ifdef ANDROID 642 assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]); 643#endif 644 if (0 <= index) { 645 if (exposedMask & (1 << index)) { 646 SL_LOGE("can't request SL_IID_BUFFERQUEUE " 647#ifdef ANDROID 648 "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE " 649#endif 650 "with a non-buffer queue data source"); 651 return SL_RESULT_FEATURE_UNSUPPORTED; 652 } 653 } 654 break; 655 } 656 return SL_RESULT_SUCCESS; 657} 658 659 660/** \brief Free the local deep copy of a data format */ 661 662static void freeDataFormat(DataFormat *pDataFormat) 663{ 664 switch (pDataFormat->mFormatType) { 665 case SL_DATAFORMAT_MIME: 666 if (NULL != pDataFormat->mMIME.mimeType) { 667 free(pDataFormat->mMIME.mimeType); 668 pDataFormat->mMIME.mimeType = NULL; 669 } 670 break; 671 case SL_DATAFORMAT_PCM: 672 case XA_DATAFORMAT_RAWIMAGE: 673 case SL_DATAFORMAT_NULL: 674 break; 675 default: 676 // an invalid data format is caught earlier during the copy 677 assert(false); 678 break; 679 } 680} 681 682 683/** \brief Check a data source and make local deep copy */ 684 685SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc, 686 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 687 SLuint32 allowedDataFormatMask) 688{ 689 assert(NULL != name && NULL != pDataLocatorFormat); 690 pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 691 pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 692 693 if (NULL == pDataSrc) { 694 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 695 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 696 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 697 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 698 return SL_RESULT_SUCCESS; 699 } 700 SL_LOGE("%s: data source cannot be NULL", name); 701 return SL_RESULT_PARAMETER_INVALID; 702 } 703 SLDataSource myDataSrc = *pDataSrc; 704 SLresult result; 705 result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator, 706 allowedDataLocatorMask); 707 if (SL_RESULT_SUCCESS != result) { 708 return result; 709 } 710 711 switch (pDataLocatorFormat->mLocator.mLocatorType) { 712 case SL_DATALOCATOR_URI: 713 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 714 break; 715 case SL_DATALOCATOR_ADDRESS: 716 case SL_DATALOCATOR_BUFFERQUEUE: 717 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 718 break; 719 // Per the spec, the pFormat field is ignored in some cases 720 case SL_DATALOCATOR_IODEVICE: 721 myDataSrc.pFormat = NULL; 722 // fall through 723 case SL_DATALOCATOR_NULL: 724 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 725 allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 726 break; 727 case SL_DATALOCATOR_OUTPUTMIX: 728 case XA_DATALOCATOR_NATIVEDISPLAY: 729 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 730 break; 731#ifdef ANDROID 732 case SL_DATALOCATOR_ANDROIDFD: 733 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 734 break; 735 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 736 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 737 break; 738 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 739 allowedDataFormatMask &= DATAFORMAT_MASK_MIME;; 740 break; 741#endif 742 default: 743 // invalid data locator type is caught earlier 744 assert(false); 745 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 746 break; 747 } 748 749 result = checkDataFormat(name, myDataSrc.pFormat, &pDataLocatorFormat->mFormat, 750 allowedDataFormatMask); 751 if (SL_RESULT_SUCCESS != result) { 752 freeDataLocator(&pDataLocatorFormat->mLocator); 753 return result; 754 } 755 756 return SL_RESULT_SUCCESS; 757} 758 759 760/** \brief Check a data sink and make local deep copy */ 761 762SLresult checkDataSink(const char *name, const SLDataSink *pDataSink, 763 DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask, 764 SLuint32 allowedDataFormatMask) 765{ 766 assert(NULL != name && NULL != pDataLocatorFormat); 767 pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 768 pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 769 770 if (NULL == pDataSink) { 771 pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL; 772 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 773 if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) && 774 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) { 775 return SL_RESULT_SUCCESS; 776 } 777 SL_LOGE("%s: data sink cannot be NULL", name); 778 return SL_RESULT_PARAMETER_INVALID; 779 } 780 SLDataSink myDataSink = *pDataSink; 781 SLresult result; 782 result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator, 783 allowedDataLocatorMask); 784 if (SL_RESULT_SUCCESS != result) { 785 return result; 786 } 787 788 switch (pDataLocatorFormat->mLocator.mLocatorType) { 789 case SL_DATALOCATOR_URI: 790 allowedDataFormatMask &= DATAFORMAT_MASK_MIME; 791 break; 792 case SL_DATALOCATOR_ADDRESS: 793 case SL_DATALOCATOR_BUFFERQUEUE: 794 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 795 break; 796 // Per the spec, the pFormat field is ignored in some cases 797 case SL_DATALOCATOR_IODEVICE: 798 case SL_DATALOCATOR_OUTPUTMIX: 799 case XA_DATALOCATOR_NATIVEDISPLAY: 800 myDataSink.pFormat = NULL; 801 // fall through 802 case SL_DATALOCATOR_NULL: 803 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 804 allowedDataFormatMask &= DATAFORMAT_MASK_NULL; 805 break; 806#ifdef ANDROID 807 case SL_DATALOCATOR_ANDROIDFD: 808 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 809 break; 810 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 811 allowedDataFormatMask &= DATAFORMAT_MASK_PCM; 812 break; 813 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 814 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 815 break; 816#endif 817 default: 818 // invalid data locator type is caught earlier 819 assert(false); 820 allowedDataFormatMask = DATAFORMAT_MASK_NONE; 821 break; 822 } 823 824 result = checkDataFormat(name, myDataSink.pFormat, &pDataLocatorFormat->mFormat, 825 allowedDataFormatMask); 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 Free the local deep copy of a data locator format */ 836 837void freeDataLocatorFormat(DataLocatorFormat *dlf) 838{ 839 assert(NULL != dlf); 840 freeDataLocator(&dlf->mLocator); 841 freeDataFormat(&dlf->mFormat); 842} 843