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