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