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