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 /* OpenSL ES private and global functions not associated with an interface or class */ 18 19 #include "sles_allinclusive.h" 20 21 22 /** \brief Return true if the specified interface exists and has been initialized for this object. 23 * Returns false if the class does not support this kind of interface, or the class supports the 24 * interface but this particular object has not had the interface exposed at object creation time 25 * or by DynamicInterface::AddInterface. Note that the return value is not affected by whether 26 * the application has requested access to the interface with Object::GetInterface. Assumes on 27 * entry that the object is locked for either shared or exclusive access. 28 */ 29 30 bool IsInterfaceInitialized(IObject *thiz, unsigned MPH) 31 { 32 assert(NULL != thiz); 33 assert( /* (MPH_MIN <= MPH) && */ (MPH < (unsigned) MPH_MAX)); 34 const ClassTable *clazz = thiz->mClass; 35 assert(NULL != clazz); 36 int index; 37 if (0 > (index = clazz->mMPH_to_index[MPH])) { 38 return false; 39 } 40 assert(MAX_INDEX >= clazz->mInterfaceCount); 41 assert(clazz->mInterfaceCount > (unsigned) index); 42 switch (thiz->mInterfaceStates[index]) { 43 case INTERFACE_EXPOSED: 44 case INTERFACE_ADDED: 45 return true; 46 default: 47 return false; 48 } 49 } 50 51 52 /** \brief Map an IObject to it's "object ID" (which is really a class ID) */ 53 54 SLuint32 IObjectToObjectID(IObject *thiz) 55 { 56 assert(NULL != thiz); 57 // Note this returns the OpenSL ES object ID in preference to the OpenMAX AL if both available 58 const ClassTable *clazz = thiz->mClass; 59 assert(NULL != clazz); 60 SLuint32 id = clazz->mSLObjectID; 61 if (!id) { 62 id = clazz->mXAObjectID; 63 } 64 return id; 65 } 66 67 68 /** \brief Acquire a strong reference to an object. 69 * Check that object has the specified "object ID" (which is really a class ID) and is in the 70 * realized state. If so, then acquire a strong reference to it and return true. 71 * Otherwise return false. 72 */ 73 74 SLresult AcquireStrongRef(IObject *object, SLuint32 expectedObjectID) 75 { 76 if (NULL == object) { 77 return SL_RESULT_PARAMETER_INVALID; 78 } 79 // NTH additional validity checks on address here 80 SLresult result; 81 object_lock_exclusive(object); 82 SLuint32 actualObjectID = IObjectToObjectID(object); 83 if (expectedObjectID != actualObjectID) { 84 SL_LOGE("object %p has object ID %u but expected %u", object, actualObjectID, 85 expectedObjectID); 86 result = SL_RESULT_PARAMETER_INVALID; 87 } else if (SL_OBJECT_STATE_REALIZED != object->mState) { 88 SL_LOGE("object %p with object ID %u is not realized", object, actualObjectID); 89 result = SL_RESULT_PRECONDITIONS_VIOLATED; 90 } else { 91 ++object->mStrongRefCount; 92 result = SL_RESULT_SUCCESS; 93 } 94 object_unlock_exclusive(object); 95 return result; 96 } 97 98 99 /** \brief Release a strong reference to an object. 100 * Entry condition: the object is locked. 101 * Exit condition: the object is unlocked. 102 * Finishes the destroy if needed. 103 */ 104 105 void ReleaseStrongRefAndUnlockExclusive(IObject *object) 106 { 107 #ifdef USE_DEBUG 108 assert(pthread_equal(pthread_self(), object->mOwner)); 109 #endif 110 assert(0 < object->mStrongRefCount); 111 if ((0 == --object->mStrongRefCount) && (SL_OBJECT_STATE_DESTROYING == object->mState)) { 112 // FIXME do the destroy here - merge with IDestroy 113 // but can't do this until we move Destroy to the sync thread 114 // as Destroy is now a blocking operation, and to avoid a race 115 } else { 116 object_unlock_exclusive(object); 117 } 118 } 119 120 121 /** \brief Release a strong reference to an object. 122 * Entry condition: the object is unlocked. 123 * Exit condition: the object is unlocked. 124 * Finishes the destroy if needed. 125 */ 126 127 void ReleaseStrongRef(IObject *object) 128 { 129 assert(NULL != object); 130 object_lock_exclusive(object); 131 ReleaseStrongRefAndUnlockExclusive(object); 132 } 133 134 135 /** \brief Convert POSIX pthread error code to OpenSL ES result code */ 136 137 SLresult err_to_result(int err) 138 { 139 if (EAGAIN == err || ENOMEM == err) { 140 return SL_RESULT_RESOURCE_ERROR; 141 } 142 if (0 != err) { 143 return SL_RESULT_INTERNAL_ERROR; 144 } 145 return SL_RESULT_SUCCESS; 146 } 147 148 149 /** \brief Check the interface IDs passed into a Create operation */ 150 151 SLresult checkInterfaces(const ClassTable *clazz, SLuint32 numInterfaces, 152 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired, 153 unsigned *pExposedMask, unsigned *pRequiredMask) 154 { 155 assert(NULL != clazz && NULL != pExposedMask); 156 // Initially no interfaces are exposed 157 unsigned exposedMask = 0; 158 unsigned requiredMask = 0; 159 const struct iid_vtable *interfaces = clazz->mInterfaces; 160 SLuint32 interfaceCount = clazz->mInterfaceCount; 161 SLuint32 i; 162 // Expose all implicit interfaces 163 for (i = 0; i < interfaceCount; ++i) { 164 switch (interfaces[i].mInterface) { 165 case INTERFACE_IMPLICIT: 166 case INTERFACE_IMPLICIT_PREREALIZE: 167 // there must be an initialization hook present 168 if (NULL != MPH_init_table[interfaces[i].mMPH].mInit) { 169 exposedMask |= 1 << i; 170 } 171 break; 172 case INTERFACE_EXPLICIT: 173 case INTERFACE_DYNAMIC: 174 case INTERFACE_UNAVAILABLE: 175 case INTERFACE_EXPLICIT_PREREALIZE: 176 break; 177 default: 178 assert(false); 179 break; 180 } 181 } 182 if (0 < numInterfaces) { 183 if (NULL == pInterfaceIds || NULL == pInterfaceRequired) { 184 return SL_RESULT_PARAMETER_INVALID; 185 } 186 bool anyRequiredButUnsupported = false; 187 // Loop for each requested interface 188 for (i = 0; i < numInterfaces; ++i) { 189 SLInterfaceID iid = pInterfaceIds[i]; 190 if (NULL == iid) { 191 return SL_RESULT_PARAMETER_INVALID; 192 } 193 SLboolean isRequired = pInterfaceRequired[i]; 194 int MPH, index; 195 if ((0 > (MPH = IID_to_MPH(iid))) || 196 // there must be an initialization hook present 197 (NULL == MPH_init_table[MPH].mInit) || 198 (0 > (index = clazz->mMPH_to_index[MPH])) || 199 (INTERFACE_UNAVAILABLE == interfaces[index].mInterface)) { 200 // Here if interface was not found, or is not available for this object type 201 if (isRequired) { 202 // Application said it required the interface, so give up 203 SL_LOGE("class %s interface %u required but unavailable MPH=%d", 204 clazz->mName, i, MPH); 205 anyRequiredButUnsupported = true; 206 } 207 // Application said it didn't really need the interface, so ignore with warning 208 SL_LOGW("class %s interface %u requested but unavailable MPH=%d", 209 clazz->mName, i, MPH); 210 continue; 211 } 212 if (isRequired) { 213 requiredMask |= (1 << index); 214 } 215 // The requested interface was both found and available, so expose it 216 exposedMask |= (1 << index); 217 // Note that we ignore duplicate requests, including equal and aliased IDs 218 } 219 if (anyRequiredButUnsupported) { 220 return SL_RESULT_FEATURE_UNSUPPORTED; 221 } 222 } 223 *pExposedMask = exposedMask; 224 if (NULL != pRequiredMask) { 225 *pRequiredMask = requiredMask; 226 } 227 return SL_RESULT_SUCCESS; 228 } 229 230 231 /* Interface initialization hooks */ 232 233 extern void 234 I3DCommit_init(void *), 235 I3DDoppler_init(void *), 236 I3DGrouping_init(void *), 237 I3DLocation_init(void *), 238 I3DMacroscopic_init(void *), 239 I3DSource_init(void *), 240 IAndroidAcousticEchoCancellation_init(void *), 241 IAndroidAutomaticGainControl_init(void *), 242 IAndroidConfiguration_init(void *), 243 IAndroidEffect_init(void *), 244 IAndroidEffectCapabilities_init(void *), 245 IAndroidEffectSend_init(void *), 246 IAndroidBufferQueue_init(void *), 247 IAudioDecoderCapabilities_init(void *), 248 IAudioEncoder_init(void *), 249 IAudioEncoderCapabilities_init(void *), 250 IAudioIODeviceCapabilities_init(void *), 251 IBassBoost_init(void *), 252 IBufferQueue_init(void *), 253 IDeviceVolume_init(void *), 254 IDynamicInterfaceManagement_init(void *), 255 IDynamicSource_init(void *), 256 IEffectSend_init(void *), 257 IEngine_init(void *), 258 IEngineCapabilities_init(void *), 259 IEnvironmentalReverb_init(void *), 260 IEqualizer_init(void *), 261 ILEDArray_init(void *), 262 IMIDIMessage_init(void *), 263 IMIDIMuteSolo_init(void *), 264 IMIDITempo_init(void *), 265 IMIDITime_init(void *), 266 IMetadataExtraction_init(void *), 267 IMetadataTraversal_init(void *), 268 IMuteSolo_init(void *), 269 IAndroidNoiseSuppression_init(void *), 270 IObject_init(void *), 271 IOutputMix_init(void *), 272 IOutputMixExt_init(void *), 273 IPitch_init(void *), 274 IPlay_init(void *), 275 IPlaybackRate_init(void *), 276 IPrefetchStatus_init(void *), 277 IPresetReverb_init(void *), 278 IRatePitch_init(void *), 279 IRecord_init(void *), 280 ISeek_init(void *), 281 IThreadSync_init(void *), 282 IVibra_init(void *), 283 IVirtualizer_init(void *), 284 IVisualization_init(void *), 285 IVolume_init(void *); 286 287 extern void 288 I3DGrouping_deinit(void *), 289 IAndroidAcousticEchoCancellation_deinit(void *), 290 IAndroidAutomaticGainControl_deinit(void *), 291 IAndroidEffect_deinit(void *), 292 IAndroidEffectCapabilities_deinit(void *), 293 IAndroidBufferQueue_deinit(void *), 294 IAndroidNoiseSuppression_deinit(void*), 295 IBassBoost_deinit(void *), 296 IBufferQueue_deinit(void *), 297 IEngine_deinit(void *), 298 IEnvironmentalReverb_deinit(void *), 299 IEqualizer_deinit(void *), 300 IObject_deinit(void *), 301 IPresetReverb_deinit(void *), 302 IThreadSync_deinit(void *), 303 IVirtualizer_deinit(void *); 304 305 extern bool 306 IAndroidAcousticEchoCancellation_Expose(void *), 307 IAndroidAutomaticGainControl_Expose(void *), 308 IAndroidEffectCapabilities_Expose(void *), 309 IAndroidNoiseSuppression_Expose(void *), 310 IBassBoost_Expose(void *), 311 IEnvironmentalReverb_Expose(void *), 312 IEqualizer_Expose(void *), 313 IPresetReverb_Expose(void *), 314 IVirtualizer_Expose(void *); 315 316 extern void 317 IXAEngine_init(void *), 318 IStreamInformation_init(void*), 319 IVideoDecoderCapabilities_init(void *); 320 321 extern void 322 IXAEngine_deinit(void *), 323 IStreamInformation_deinit(void *), 324 IVideoDecoderCapabilities_deinit(void *); 325 326 extern bool 327 IVideoDecoderCapabilities_expose(void *); 328 329 #if !(USE_PROFILES & USE_PROFILES_MUSIC) 330 #define IDynamicSource_init NULL 331 #define IMetadataTraversal_init NULL 332 #define IVisualization_init NULL 333 #endif 334 335 #if !(USE_PROFILES & USE_PROFILES_GAME) 336 #define I3DCommit_init NULL 337 #define I3DDoppler_init NULL 338 #define I3DGrouping_init NULL 339 #define I3DLocation_init NULL 340 #define I3DMacroscopic_init NULL 341 #define I3DSource_init NULL 342 #define IMIDIMessage_init NULL 343 #define IMIDIMuteSolo_init NULL 344 #define IMIDITempo_init NULL 345 #define IMIDITime_init NULL 346 #define IPitch_init NULL 347 #define IRatePitch_init NULL 348 #define I3DGrouping_deinit NULL 349 #endif 350 351 #if !(USE_PROFILES & USE_PROFILES_BASE) 352 #define IAudioDecoderCapabilities_init NULL 353 #define IAudioEncoderCapabilities_init NULL 354 #define IAudioEncoder_init NULL 355 #define IAudioIODeviceCapabilities_init NULL 356 #define IDeviceVolume_init NULL 357 #define IEngineCapabilities_init NULL 358 #define IThreadSync_init NULL 359 #define IThreadSync_deinit NULL 360 #endif 361 362 #if !(USE_PROFILES & USE_PROFILES_OPTIONAL) 363 #define ILEDArray_init NULL 364 #define IVibra_init NULL 365 #endif 366 367 #ifndef ANDROID 368 #define IAndroidConfiguration_init NULL 369 #define IAndroidEffect_init NULL 370 #define IAndroidEffectCapabilities_init NULL 371 #define IAndroidEffectSend_init NULL 372 #define IAndroidEffect_deinit NULL 373 #define IAndroidEffectCapabilities_deinit NULL 374 #define IAndroidEffectCapabilities_Expose NULL 375 #define IAndroidBufferQueue_init NULL 376 #define IStreamInformation_init NULL 377 #define IAndroidBufferQueue_deinit NULL 378 #define IStreamInformation_deinit NULL 379 #endif 380 381 #ifndef USE_OUTPUTMIXEXT 382 #define IOutputMixExt_init NULL 383 #endif 384 385 386 /*static*/ const struct MPH_init MPH_init_table[MPH_MAX] = { 387 { /* MPH_3DCOMMIT, */ I3DCommit_init, NULL, NULL, NULL, NULL }, 388 { /* MPH_3DDOPPLER, */ I3DDoppler_init, NULL, NULL, NULL, NULL }, 389 { /* MPH_3DGROUPING, */ I3DGrouping_init, NULL, I3DGrouping_deinit, NULL, NULL }, 390 { /* MPH_3DLOCATION, */ I3DLocation_init, NULL, NULL, NULL, NULL }, 391 { /* MPH_3DMACROSCOPIC, */ I3DMacroscopic_init, NULL, NULL, NULL, NULL }, 392 { /* MPH_3DSOURCE, */ I3DSource_init, NULL, NULL, NULL, NULL }, 393 { /* MPH_AUDIODECODERCAPABILITIES, */ IAudioDecoderCapabilities_init, NULL, NULL, NULL, NULL }, 394 { /* MPH_AUDIOENCODER, */ IAudioEncoder_init, NULL, NULL, NULL, NULL }, 395 { /* MPH_AUDIOENCODERCAPABILITIES, */ IAudioEncoderCapabilities_init, NULL, NULL, NULL, NULL }, 396 { /* MPH_AUDIOIODEVICECAPABILITIES, */ IAudioIODeviceCapabilities_init, NULL, NULL, NULL, 397 NULL }, 398 { /* MPH_BASSBOOST, */ IBassBoost_init, NULL, IBassBoost_deinit, IBassBoost_Expose, NULL }, 399 { /* MPH_BUFFERQUEUE, */ IBufferQueue_init, NULL, IBufferQueue_deinit, NULL, NULL }, 400 { /* MPH_DEVICEVOLUME, */ IDeviceVolume_init, NULL, NULL, NULL, NULL }, 401 { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ IDynamicInterfaceManagement_init, NULL, NULL, NULL, 402 NULL }, 403 { /* MPH_DYNAMICSOURCE, */ IDynamicSource_init, NULL, NULL, NULL, NULL }, 404 { /* MPH_EFFECTSEND, */ IEffectSend_init, NULL, NULL, NULL, NULL }, 405 { /* MPH_ENGINE, */ IEngine_init, NULL, IEngine_deinit, NULL, NULL }, 406 { /* MPH_ENGINECAPABILITIES, */ IEngineCapabilities_init, NULL, NULL, NULL, NULL }, 407 { /* MPH_ENVIRONMENTALREVERB, */ IEnvironmentalReverb_init, NULL, IEnvironmentalReverb_deinit, 408 IEnvironmentalReverb_Expose, NULL }, 409 { /* MPH_EQUALIZER, */ IEqualizer_init, NULL, IEqualizer_deinit, IEqualizer_Expose, NULL }, 410 { /* MPH_LED, */ ILEDArray_init, NULL, NULL, NULL, NULL }, 411 { /* MPH_METADATAEXTRACTION, */ IMetadataExtraction_init, NULL, NULL, NULL, NULL }, 412 { /* MPH_METADATATRAVERSAL, */ IMetadataTraversal_init, NULL, NULL, NULL, NULL }, 413 { /* MPH_MIDIMESSAGE, */ IMIDIMessage_init, NULL, NULL, NULL, NULL }, 414 { /* MPH_MIDITIME, */ IMIDITime_init, NULL, NULL, NULL, NULL }, 415 { /* MPH_MIDITEMPO, */ IMIDITempo_init, NULL, NULL, NULL, NULL }, 416 { /* MPH_MIDIMUTESOLO, */ IMIDIMuteSolo_init, NULL, NULL, NULL, NULL }, 417 { /* MPH_MUTESOLO, */ IMuteSolo_init, NULL, NULL, NULL, NULL }, 418 { /* MPH_NULL, */ NULL, NULL, NULL, NULL, NULL }, 419 { /* MPH_OBJECT, */ IObject_init, NULL, IObject_deinit, NULL, NULL }, 420 { /* MPH_OUTPUTMIX, */ IOutputMix_init, NULL, NULL, NULL, NULL }, 421 { /* MPH_PITCH, */ IPitch_init, NULL, NULL, NULL, NULL }, 422 { /* MPH_PLAY, */ IPlay_init, NULL, NULL, NULL, NULL }, 423 { /* MPH_PLAYBACKRATE, */ IPlaybackRate_init, NULL, NULL, NULL, NULL }, 424 { /* MPH_PREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL, NULL, NULL }, 425 { /* MPH_PRESETREVERB, */ IPresetReverb_init, NULL, IPresetReverb_deinit, 426 IPresetReverb_Expose, NULL }, 427 { /* MPH_RATEPITCH, */ IRatePitch_init, NULL, NULL, NULL, NULL }, 428 { /* MPH_RECORD, */ IRecord_init, NULL, NULL, NULL, NULL }, 429 { /* MPH_SEEK, */ ISeek_init, NULL, NULL, NULL, NULL }, 430 { /* MPH_THREADSYNC, */ IThreadSync_init, NULL, IThreadSync_deinit, NULL, NULL }, 431 { /* MPH_VIBRA, */ IVibra_init, NULL, NULL, NULL, NULL }, 432 { /* MPH_VIRTUALIZER, */ IVirtualizer_init, NULL, IVirtualizer_deinit, IVirtualizer_Expose, 433 NULL }, 434 { /* MPH_VISUALIZATION, */ IVisualization_init, NULL, NULL, NULL, NULL }, 435 { /* MPH_VOLUME, */ IVolume_init, NULL, NULL, NULL, NULL }, 436 // Wilhelm desktop extended interfaces 437 { /* MPH_OUTPUTMIXEXT, */ IOutputMixExt_init, NULL, NULL, NULL, NULL }, 438 // Android API level 9 extended interfaces 439 { /* MPH_ANDROIDEFFECT */ IAndroidEffect_init, NULL, IAndroidEffect_deinit, NULL, NULL }, 440 { /* MPH_ANDROIDEFFECTCAPABILITIES */ IAndroidEffectCapabilities_init, NULL, 441 IAndroidEffectCapabilities_deinit, IAndroidEffectCapabilities_Expose, NULL }, 442 { /* MPH_ANDROIDEFFECTSEND */ IAndroidEffectSend_init, NULL, NULL, NULL, NULL }, 443 { /* MPH_ANDROIDCONFIGURATION */ IAndroidConfiguration_init, NULL, NULL, NULL, NULL }, 444 { /* MPH_ANDROIDSIMPLEBUFFERQUEUE */ IBufferQueue_init /* alias */, NULL, NULL, NULL, NULL }, 445 // Android API level 10 extended interfaces 446 { /* MPH_ANDROIDBUFFERQUEUESOURCE */ IAndroidBufferQueue_init, NULL, IAndroidBufferQueue_deinit, 447 NULL, NULL }, 448 // OpenMAX AL 1.0.1 interfaces 449 { /* MPH_XAAUDIODECODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 450 { /* MPH_XAAUDIOENCODER */ NULL, NULL, NULL, NULL, NULL }, 451 { /* MPH_XAAUDIOENCODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 452 { /* MPH_XAAUDIOIODEVICECAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 453 { /* MPH_XACAMERA */ NULL, NULL, NULL, NULL, NULL }, 454 { /* MPH_XACAMERACAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 455 { /* MPH_XACONFIGEXTENSION */ NULL, NULL, NULL, NULL, NULL }, 456 { /* MPH_XADEVICEVOLUME */ NULL, NULL, NULL, NULL, NULL }, 457 { /* MPH_XADYNAMICINTERFACEMANAGEMENT 59 */ NULL, NULL, NULL, NULL, NULL }, 458 { /* MPH_XADYNAMICSOURCE */ NULL, NULL, NULL, NULL, NULL }, 459 { /* MPH_XAENGINE */ IXAEngine_init, NULL, IXAEngine_deinit, NULL, NULL }, 460 { /* MPH_XAEQUALIZER */ NULL, NULL, NULL, NULL, NULL }, 461 { /* MPH_XAIMAGECONTROLS */ NULL, NULL, NULL, NULL, NULL }, 462 { /* MPH_XAIMAGEDECODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 463 { /* MPH_XAIMAGEEFFECTS */ NULL, NULL, NULL, NULL, NULL }, 464 { /* MPH_XAIMAGEENCODER */ NULL, NULL, NULL, NULL, NULL }, 465 { /* MPH_XAIMAGEENCODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 466 { /* MPH_XALED */ NULL, NULL, NULL, NULL, NULL }, 467 { /* MPH_XAMETADATAEXTRACTION */ NULL, NULL, NULL, NULL, NULL }, 468 { /* MPH_XAMETADATAINSERTION */ NULL, NULL, NULL, NULL, NULL }, 469 { /* MPH_XAMETADATATRAVERSAL */ NULL, NULL, NULL, NULL, NULL }, 470 // { /* MPH_XANULL */ NULL, NULL, NULL, NULL, NULL }, 471 { /* MPH_XAOBJECT */ IObject_init, NULL, IObject_deinit, NULL, NULL }, 472 { /* MPH_XAOUTPUTMIX */ NULL, NULL, NULL, NULL, NULL }, 473 { /* MPH_XAPLAY */ IPlay_init, NULL, NULL, NULL, NULL }, 474 { /* MPH_XAPLAYBACKRATE */ NULL, NULL, NULL, NULL, NULL }, 475 { /* MPH_XAPREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL, NULL, NULL }, 476 { /* MPH_XARADIO */ NULL, NULL, NULL, NULL, NULL }, 477 { /* MPH_XARDS */ NULL, NULL, NULL, NULL, NULL }, 478 { /* MPH_XARECORD */ NULL, NULL, NULL, NULL, NULL }, 479 { /* MPH_XASEEK */ ISeek_init, NULL, NULL, NULL, NULL }, 480 { /* MPH_XASNAPSHOT */ NULL, NULL, NULL, NULL, NULL }, 481 { /* MPH_XASTREAMINFORMATION */ IStreamInformation_init, NULL, IStreamInformation_deinit, 482 NULL, NULL }, 483 { /* MPH_XATHREADSYNC */ NULL, NULL, NULL, NULL, NULL }, 484 { /* MPH_XAVIBRA */ NULL, NULL, NULL, NULL, NULL }, 485 { /* MPH_XAVIDEODECODERCAPABILITIES */ IVideoDecoderCapabilities_init, NULL, 486 IVideoDecoderCapabilities_deinit, IVideoDecoderCapabilities_expose, NULL }, 487 { /* MPH_XAVIDEOENCODER */ NULL, NULL, NULL, NULL, NULL }, 488 { /* MPH_XAVIDEOENCODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, 489 { /* MPH_XAVIDEOPOSTPROCESSING */ NULL, NULL, NULL, NULL, NULL }, 490 { /* MPH_XAVOLUME, */ IVolume_init, NULL, NULL, NULL, NULL }, 491 { /* MPH_ANDROIDACOUSTICECHOCANCELLATION, */ IAndroidAcousticEchoCancellation_init, NULL, 492 IAndroidAcousticEchoCancellation_deinit, IAndroidAcousticEchoCancellation_Expose, 493 NULL }, 494 { /* MPH_ANDROIDAUTOMATICGAINCONTROL, */ IAndroidAutomaticGainControl_init, NULL, 495 IAndroidAutomaticGainControl_deinit, IAndroidAutomaticGainControl_Expose, NULL }, 496 { /* MPH_ANDROIDNOISESUPPRESSION, */ IAndroidNoiseSuppression_init, NULL, 497 IAndroidNoiseSuppression_deinit, IAndroidNoiseSuppression_Expose, NULL }, 498 }; 499 500 501 /** \brief Construct a new instance of the specified class, exposing selected interfaces */ 502 503 IObject *construct(const ClassTable *clazz, unsigned exposedMask, SLEngineItf engine) 504 { 505 IObject *thiz; 506 // Do not change this to malloc; we depend on the object being memset to zero 507 thiz = (IObject *) calloc(1, clazz->mSize); 508 if (NULL != thiz) { 509 SL_LOGV("construct %s at %p", clazz->mName, thiz); 510 unsigned lossOfControlMask = 0; 511 // a NULL engine means we are constructing the engine 512 IEngine *thisEngine = (IEngine *) engine; 513 if (NULL == thisEngine) { 514 // thisEngine = &((CEngine *) thiz)->mEngine; 515 thiz->mEngine = (CEngine *) thiz; 516 } else { 517 thiz->mEngine = (CEngine *) thisEngine->mThis; 518 interface_lock_exclusive(thisEngine); 519 if (MAX_INSTANCE <= thisEngine->mInstanceCount) { 520 SL_LOGE("Too many objects"); 521 interface_unlock_exclusive(thisEngine); 522 free(thiz); 523 return NULL; 524 } 525 // pre-allocate a pending slot, but don't assign bit from mInstanceMask yet 526 ++thisEngine->mInstanceCount; 527 assert(((unsigned) ~0) != thisEngine->mInstanceMask); 528 interface_unlock_exclusive(thisEngine); 529 // const, no lock needed 530 if (thisEngine->mLossOfControlGlobal) { 531 lossOfControlMask = ~0; 532 } 533 } 534 thiz->mLossOfControlMask = lossOfControlMask; 535 thiz->mClass = clazz; 536 const struct iid_vtable *x = clazz->mInterfaces; 537 SLuint8 *interfaceStateP = thiz->mInterfaceStates; 538 SLuint32 index; 539 for (index = 0; index < clazz->mInterfaceCount; ++index, ++x, exposedMask >>= 1) { 540 SLuint8 state; 541 // initialize all interfaces with init hooks, even if not exposed 542 const struct MPH_init *mi = &MPH_init_table[x->mMPH]; 543 VoidHook init = mi->mInit; 544 if (NULL != init) { 545 void *self = (char *) thiz + x->mOffset; 546 // IObject does not have an mThis, so [1] is not always defined 547 if (index) { 548 ((IObject **) self)[1] = thiz; 549 } 550 // call the initialization hook 551 (*init)(self); 552 // IObject does not require a call to GetInterface 553 if (index) { 554 // This trickery invalidates the v-table until GetInterface 555 ((size_t *) self)[0] ^= ~0; 556 } 557 // if interface is exposed, also call the optional expose hook 558 BoolHook expose; 559 state = (exposedMask & 1) && ((NULL == (expose = mi->mExpose)) || (*expose)(self)) ? 560 INTERFACE_EXPOSED : INTERFACE_INITIALIZED; 561 // FIXME log or report to application if an expose hook on a 562 // required explicit interface fails at creation time 563 } else { 564 state = INTERFACE_UNINITIALIZED; 565 } 566 *interfaceStateP++ = state; 567 } 568 // note that the new object is not yet published; creator must call IObject_Publish 569 } 570 return thiz; 571 } 572