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
IsInterfaceInitialized(IObject * this,unsigned MPH)30 bool IsInterfaceInitialized(IObject *this, unsigned MPH)
31 {
32 assert(NULL != this);
33 assert( /* (MPH_MIN <= MPH) && */ (MPH < (unsigned) MPH_MAX));
34 const ClassTable *class__ = this->mClass;
35 assert(NULL != class__);
36 int index;
37 if (0 > (index = class__->mMPH_to_index[MPH])) {
38 return false;
39 }
40 assert(MAX_INDEX >= class__->mInterfaceCount);
41 assert(class__->mInterfaceCount > (unsigned) index);
42 switch (this->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
IObjectToObjectID(IObject * this)54 SLuint32 IObjectToObjectID(IObject *this)
55 {
56 assert(NULL != this);
57 return this->mClass->mObjectID;
58 }
59
60
61 /** \brief Acquire a strong reference to an object.
62 * Check that object has the specified "object ID" (which is really a class ID) and is in the
63 * realized state. If so, then acquire a strong reference to it and return true.
64 * Otherwise return false.
65 */
66
AcquireStrongRef(IObject * object,SLuint32 expectedObjectID)67 SLresult AcquireStrongRef(IObject *object, SLuint32 expectedObjectID)
68 {
69 if (NULL == object) {
70 return SL_RESULT_PARAMETER_INVALID;
71 }
72 // NTH additional validity checks on address here
73 SLresult result;
74 object_lock_exclusive(object);
75 SLuint32 actualObjectID = IObjectToObjectID(object);
76 if (expectedObjectID != actualObjectID) {
77 SL_LOGE("object %p has object ID %lu but expected %lu", object, actualObjectID,
78 expectedObjectID);
79 result = SL_RESULT_PARAMETER_INVALID;
80 } else if (SL_OBJECT_STATE_REALIZED != object->mState) {
81 SL_LOGE("object %p with object ID %lu is not realized", object, actualObjectID);
82 result = SL_RESULT_PRECONDITIONS_VIOLATED;
83 } else {
84 ++object->mStrongRefCount;
85 result = SL_RESULT_SUCCESS;
86 }
87 object_unlock_exclusive(object);
88 return result;
89 }
90
91
92 /** \brief Release a strong reference to an object.
93 * Entry condition: the object is locked.
94 * Exit condition: the object is unlocked.
95 * Finishes the destroy if needed.
96 */
97
ReleaseStrongRefAndUnlockExclusive(IObject * object)98 void ReleaseStrongRefAndUnlockExclusive(IObject *object)
99 {
100 #ifdef USE_DEBUG
101 assert(pthread_equal(pthread_self(), object->mOwner));
102 #endif
103 assert(0 < object->mStrongRefCount);
104 if ((0 == --object->mStrongRefCount) && (SL_OBJECT_STATE_DESTROYING == object->mState)) {
105 // FIXME do the destroy here - merge with IDestroy
106 // but can't do this until we move Destroy to the sync thread
107 // as Destroy is now a blocking operation, and to avoid a race
108 } else {
109 object_unlock_exclusive(object);
110 }
111 }
112
113
114 /** \brief Release a strong reference to an object.
115 * Entry condition: the object is unlocked.
116 * Exit condition: the object is unlocked.
117 * Finishes the destroy if needed.
118 */
119
ReleaseStrongRef(IObject * object)120 void ReleaseStrongRef(IObject *object)
121 {
122 assert(NULL != object);
123 object_lock_exclusive(object);
124 ReleaseStrongRefAndUnlockExclusive(object);
125 }
126
127
128 /** \brief Convert POSIX pthread error code to OpenSL ES result code */
129
err_to_result(int err)130 SLresult err_to_result(int err)
131 {
132 if (EAGAIN == err || ENOMEM == err) {
133 return SL_RESULT_RESOURCE_ERROR;
134 }
135 if (0 != err) {
136 return SL_RESULT_INTERNAL_ERROR;
137 }
138 return SL_RESULT_SUCCESS;
139 }
140
141
142 /** \brief Check the interface IDs passed into a Create operation */
143
checkInterfaces(const ClassTable * class__,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired,unsigned * pExposedMask)144 SLresult checkInterfaces(const ClassTable *class__, SLuint32 numInterfaces,
145 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired, unsigned *pExposedMask)
146 {
147 assert(NULL != class__ && NULL != pExposedMask);
148 // Initially no interfaces are exposed
149 unsigned exposedMask = 0;
150 const struct iid_vtable *interfaces = class__->mInterfaces;
151 SLuint32 interfaceCount = class__->mInterfaceCount;
152 SLuint32 i;
153 // Expose all implicit interfaces
154 for (i = 0; i < interfaceCount; ++i) {
155 switch (interfaces[i].mInterface) {
156 case INTERFACE_IMPLICIT:
157 case INTERFACE_IMPLICIT_PREREALIZE:
158 // there must be an initialization hook present
159 if (NULL != MPH_init_table[interfaces[i].mMPH].mInit) {
160 exposedMask |= 1 << i;
161 }
162 break;
163 case INTERFACE_EXPLICIT:
164 case INTERFACE_DYNAMIC:
165 case INTERFACE_UNAVAILABLE:
166 case INTERFACE_EXPLICIT_PREREALIZE:
167 break;
168 default:
169 assert(false);
170 break;
171 }
172 }
173 if (0 < numInterfaces) {
174 if (NULL == pInterfaceIds || NULL == pInterfaceRequired) {
175 return SL_RESULT_PARAMETER_INVALID;
176 }
177 bool anyRequiredButUnsupported = false;
178 // Loop for each requested interface
179 for (i = 0; i < numInterfaces; ++i) {
180 SLInterfaceID iid = pInterfaceIds[i];
181 if (NULL == iid) {
182 return SL_RESULT_PARAMETER_INVALID;
183 }
184 int MPH, index;
185 if ((0 > (MPH = IID_to_MPH(iid))) ||
186 // there must be an initialization hook present
187 (NULL == MPH_init_table[MPH].mInit) ||
188 (0 > (index = class__->mMPH_to_index[MPH])) ||
189 (INTERFACE_UNAVAILABLE == interfaces[index].mInterface)) {
190 // Here if interface was not found, or is not available for this object type
191 if (pInterfaceRequired[i]) {
192 // Application said it required the interface, so give up
193 SL_LOGE("class %s interface %lu required but unavailable MPH=%d",
194 class__->mName, i, MPH);
195 anyRequiredButUnsupported = true;
196 }
197 // Application said it didn't really need the interface, so ignore with warning
198 SL_LOGW("class %s interface %lu requested but unavailable MPH=%d",
199 class__->mName, i, MPH);
200 continue;
201 }
202 // The requested interface was both found and available, so expose it
203 exposedMask |= (1 << index);
204 // Note that we ignore duplicate requests, including equal and aliased IDs
205 }
206 if (anyRequiredButUnsupported) {
207 return SL_RESULT_FEATURE_UNSUPPORTED;
208 }
209 }
210 *pExposedMask = exposedMask;
211 return SL_RESULT_SUCCESS;
212 }
213
214
215 /** \brief Helper shared by decoder and encoder */
216
GetCodecCapabilities(SLuint32 codecId,SLuint32 * pIndex,SLAudioCodecDescriptor * pDescriptor,const CodecDescriptor * codecDescriptors)217 SLresult GetCodecCapabilities(SLuint32 codecId, SLuint32 *pIndex,
218 SLAudioCodecDescriptor *pDescriptor, const CodecDescriptor *codecDescriptors)
219 {
220 if (NULL == pIndex) {
221 return SL_RESULT_PARAMETER_INVALID;
222 }
223 const CodecDescriptor *cd = codecDescriptors;
224 SLuint32 index;
225 if (NULL == pDescriptor) {
226 for (index = 0 ; NULL != cd->mDescriptor; ++cd) {
227 if (cd->mCodecID == codecId) {
228 ++index;
229 }
230 }
231 *pIndex = index;
232 return SL_RESULT_SUCCESS;
233 }
234 index = *pIndex;
235 for ( ; NULL != cd->mDescriptor; ++cd) {
236 if (cd->mCodecID == codecId) {
237 if (0 == index) {
238 *pDescriptor = *cd->mDescriptor;
239 #if 0 // Temporary workaround for Khronos bug 6331
240 if (0 < pDescriptor->numSampleRatesSupported) {
241 // The malloc is not in the 1.0.1 specification
242 SLmilliHertz *temp = (SLmilliHertz *) malloc(sizeof(SLmilliHertz) *
243 pDescriptor->numSampleRatesSupported);
244 assert(NULL != temp);
245 memcpy(temp, pDescriptor->pSampleRatesSupported, sizeof(SLmilliHertz) *
246 pDescriptor->numSampleRatesSupported);
247 pDescriptor->pSampleRatesSupported = temp;
248 } else {
249 pDescriptor->pSampleRatesSupported = NULL;
250 }
251 #endif
252 return SL_RESULT_SUCCESS;
253 }
254 --index;
255 }
256 }
257 return SL_RESULT_PARAMETER_INVALID;
258 }
259
260
261 /** \brief Check a data locator and make local deep copy */
262
checkDataLocator(void * pLocator,DataLocator * pDataLocator)263 static SLresult checkDataLocator(void *pLocator, DataLocator *pDataLocator)
264 {
265 if (NULL == pLocator) {
266 pDataLocator->mLocatorType = SL_DATALOCATOR_NULL;
267 return SL_RESULT_SUCCESS;
268 }
269 SLresult result;
270 SLuint32 locatorType = *(SLuint32 *)pLocator;
271 switch (locatorType) {
272
273 case SL_DATALOCATOR_ADDRESS:
274 pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator;
275 // if length is greater than zero, then the address must be non-NULL
276 if ((0 < pDataLocator->mAddress.length) && (NULL == pDataLocator->mAddress.pAddress)) {
277 SL_LOGE("pAddress is NULL");
278 return SL_RESULT_PARAMETER_INVALID;
279 }
280 break;
281
282 case SL_DATALOCATOR_BUFFERQUEUE:
283 #ifdef ANDROID
284 // This is an alias that is _not_ converted; the rest of the code must check for both locator
285 // types. That's because it is only an alias for audio players, not audio recorder objects
286 // so we have to remember the distinction.
287 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
288 #endif
289 pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator;
290 // number of buffers must be specified, there is no default value, and must not be excessive
291 if (!((1 <= pDataLocator->mBufferQueue.numBuffers) &&
292 (pDataLocator->mBufferQueue.numBuffers <= 255))) {
293 SL_LOGE("numBuffers=%u", (unsigned) pDataLocator->mBufferQueue.numBuffers);
294 return SL_RESULT_PARAMETER_INVALID;
295 }
296 break;
297
298 case SL_DATALOCATOR_IODEVICE:
299 {
300 pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator;
301 SLuint32 deviceType = pDataLocator->mIODevice.deviceType;
302 SLObjectItf device = pDataLocator->mIODevice.device;
303 if (NULL != device) {
304 pDataLocator->mIODevice.deviceID = 0;
305 SLuint32 expectedObjectID;
306 switch (deviceType) {
307 case SL_IODEVICE_LEDARRAY:
308 expectedObjectID = SL_OBJECTID_LEDDEVICE;
309 break;
310 case SL_IODEVICE_VIBRA:
311 expectedObjectID = SL_OBJECTID_VIBRADEVICE;
312 break;
313 // audio input and audio output cannot be specified via objects
314 case SL_IODEVICE_AUDIOINPUT:
315 // worse yet, an SL_IODEVICE enum constant for audio output does not exist yet
316 // case SL_IODEVICE_AUDIOOUTPUT:
317 default:
318 SL_LOGE("invalid deviceType %lu", deviceType);
319 pDataLocator->mIODevice.device = NULL;
320 return SL_RESULT_PARAMETER_INVALID;
321 }
322 // check that device has the correct object ID and is realized,
323 // and acquire a strong reference to it
324 result = AcquireStrongRef((IObject *) device, expectedObjectID);
325 if (SL_RESULT_SUCCESS != result) {
326 SL_LOGE("locator type is IODEVICE, but device field %p has wrong object ID or is " \
327 "not realized", device);
328 pDataLocator->mIODevice.device = NULL;
329 return result;
330 }
331 } else {
332 SLuint32 deviceID = pDataLocator->mIODevice.deviceID;
333 switch (deviceType) {
334 case SL_IODEVICE_LEDARRAY:
335 if (SL_DEFAULTDEVICEID_LED != deviceID) {
336 SL_LOGE("invalid LED deviceID %lu", deviceID);
337 return SL_RESULT_PARAMETER_INVALID;
338 }
339 break;
340 case SL_IODEVICE_VIBRA:
341 if (SL_DEFAULTDEVICEID_VIBRA != deviceID) {
342 SL_LOGE("invalid vibra deviceID %lu", deviceID);
343 return SL_RESULT_PARAMETER_INVALID;
344 }
345 break;
346 case SL_IODEVICE_AUDIOINPUT:
347 if (SL_DEFAULTDEVICEID_AUDIOINPUT != deviceID) {
348 SL_LOGE("invalid audio input deviceID %lu", deviceID);
349 return SL_RESULT_PARAMETER_INVALID;
350 }
351 break;
352 default:
353 SL_LOGE("invalid deviceType %lu", deviceType);
354 return SL_RESULT_PARAMETER_INVALID;
355 }
356 }
357 }
358 break;
359
360 case SL_DATALOCATOR_MIDIBUFFERQUEUE:
361 pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator;
362 if (0 == pDataLocator->mMIDIBufferQueue.tpqn) {
363 pDataLocator->mMIDIBufferQueue.tpqn = 192;
364 }
365 // number of buffers must be specified, there is no default value, and must not be excessive
366 if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) &&
367 (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) {
368 SL_LOGE("invalid MIDI buffer queue");
369 return SL_RESULT_PARAMETER_INVALID;
370 }
371 break;
372
373 case SL_DATALOCATOR_OUTPUTMIX:
374 pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator;
375 // check that output mix object has the correct object ID and is realized,
376 // and acquire a strong reference to it
377 result = AcquireStrongRef((IObject *) pDataLocator->mOutputMix.outputMix,
378 SL_OBJECTID_OUTPUTMIX);
379 if (SL_RESULT_SUCCESS != result) {
380 SL_LOGE("locatorType is SL_DATALOCATOR_OUTPUTMIX, but outputMix field %p does not " \
381 "refer to an SL_OBJECTID_OUTPUTMIX or the output mix is not realized", \
382 pDataLocator->mOutputMix.outputMix);
383 pDataLocator->mOutputMix.outputMix = NULL;
384 return result;
385 }
386 break;
387
388 case SL_DATALOCATOR_URI:
389 {
390 pDataLocator->mURI = *(SLDataLocator_URI *)pLocator;
391 if (NULL == pDataLocator->mURI.URI) {
392 SL_LOGE("invalid URI");
393 return SL_RESULT_PARAMETER_INVALID;
394 }
395 // NTH verify URI address for validity
396 size_t len = strlen((const char *) pDataLocator->mURI.URI);
397 SLchar *myURI = (SLchar *) malloc(len + 1);
398 if (NULL == myURI) {
399 pDataLocator->mURI.URI = NULL;
400 return SL_RESULT_MEMORY_FAILURE;
401 }
402 memcpy(myURI, pDataLocator->mURI.URI, len + 1);
403 // Verify that another thread didn't change the NUL-terminator after we used it
404 // to determine length of string to copy. It's OK if the string became shorter.
405 if ('\0' != myURI[len]) {
406 free(myURI);
407 pDataLocator->mURI.URI = NULL;
408 return SL_RESULT_PARAMETER_INVALID;
409 }
410 pDataLocator->mURI.URI = myURI;
411 }
412 break;
413
414 #ifdef ANDROID
415 case SL_DATALOCATOR_ANDROIDFD:
416 {
417 pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator;
418 SL_LOGV("Data locator FD: fd=%ld offset=%lld length=%lld", pDataLocator->mFD.fd,
419 pDataLocator->mFD.offset, pDataLocator->mFD.length);
420 // NTH check against process fd limit
421 if (0 > pDataLocator->mFD.fd) {
422 return SL_RESULT_PARAMETER_INVALID;
423 }
424 }
425 break;
426 #endif
427
428 default:
429 SL_LOGE("invalid locatorType %lu", locatorType);
430 return SL_RESULT_PARAMETER_INVALID;
431 }
432
433 // Verify that another thread didn't change the locatorType field after we used it
434 // to determine sizeof struct to copy.
435 if (locatorType != pDataLocator->mLocatorType) {
436 return SL_RESULT_PARAMETER_INVALID;
437 }
438 return SL_RESULT_SUCCESS;
439 }
440
441
442 /** \brief Free the local deep copy of a data locator */
443
freeDataLocator(DataLocator * pDataLocator)444 static void freeDataLocator(DataLocator *pDataLocator)
445 {
446 switch (pDataLocator->mLocatorType) {
447 case SL_DATALOCATOR_URI:
448 if (NULL != pDataLocator->mURI.URI) {
449 free(pDataLocator->mURI.URI);
450 pDataLocator->mURI.URI = NULL;
451 }
452 pDataLocator->mURI.URI = NULL;
453 break;
454 case SL_DATALOCATOR_IODEVICE:
455 if (NULL != pDataLocator->mIODevice.device) {
456 ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device);
457 pDataLocator->mIODevice.device = NULL;
458 }
459 break;
460 case SL_DATALOCATOR_OUTPUTMIX:
461 if (NULL != pDataLocator->mOutputMix.outputMix) {
462 ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix);
463 pDataLocator->mOutputMix.outputMix = NULL;
464 }
465 break;
466 default:
467 break;
468 }
469 }
470
471
472 /** \brief Check a data format and make local deep copy */
473
checkDataFormat(void * pFormat,DataFormat * pDataFormat)474 static SLresult checkDataFormat(void *pFormat, DataFormat *pDataFormat)
475 {
476 SLresult result = SL_RESULT_SUCCESS;
477
478 if (NULL == pFormat) {
479 pDataFormat->mFormatType = SL_DATAFORMAT_NULL;
480 } else {
481 SLuint32 formatType = *(SLuint32 *)pFormat;
482 switch (formatType) {
483
484 case SL_DATAFORMAT_PCM:
485 pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat;
486 do {
487
488 // check the channel count
489 switch (pDataFormat->mPCM.numChannels) {
490 case 1: // mono
491 case 2: // stereo
492 break;
493 case 0: // unknown
494 result = SL_RESULT_PARAMETER_INVALID;
495 break;
496 default: // multi-channel
497 result = SL_RESULT_CONTENT_UNSUPPORTED;
498 break;
499 }
500 if (SL_RESULT_SUCCESS != result) {
501 SL_LOGE("numChannels=%u", (unsigned) pDataFormat->mPCM.numChannels);
502 break;
503 }
504
505 // check the sampling rate
506 switch (pDataFormat->mPCM.samplesPerSec) {
507 case SL_SAMPLINGRATE_8:
508 case SL_SAMPLINGRATE_11_025:
509 case SL_SAMPLINGRATE_12:
510 case SL_SAMPLINGRATE_16:
511 case SL_SAMPLINGRATE_22_05:
512 case SL_SAMPLINGRATE_24:
513 case SL_SAMPLINGRATE_32:
514 case SL_SAMPLINGRATE_44_1:
515 case SL_SAMPLINGRATE_48:
516 case SL_SAMPLINGRATE_64:
517 case SL_SAMPLINGRATE_88_2:
518 case SL_SAMPLINGRATE_96:
519 case SL_SAMPLINGRATE_192:
520 break;
521 case 0:
522 result = SL_RESULT_PARAMETER_INVALID;
523 break;
524 default:
525 result = SL_RESULT_CONTENT_UNSUPPORTED;
526 break;
527 }
528 if (SL_RESULT_SUCCESS != result) {
529 SL_LOGE("samplesPerSec=%u", (unsigned) pDataFormat->mPCM.samplesPerSec);
530 break;
531 }
532
533 // check the sample bit depth
534 switch (pDataFormat->mPCM.bitsPerSample) {
535 case SL_PCMSAMPLEFORMAT_FIXED_8:
536 case SL_PCMSAMPLEFORMAT_FIXED_16:
537 break;
538 case SL_PCMSAMPLEFORMAT_FIXED_20:
539 case SL_PCMSAMPLEFORMAT_FIXED_24:
540 case SL_PCMSAMPLEFORMAT_FIXED_28:
541 case SL_PCMSAMPLEFORMAT_FIXED_32:
542 result = SL_RESULT_CONTENT_UNSUPPORTED;
543 break;
544 default:
545 result = SL_RESULT_PARAMETER_INVALID;
546 break;
547 }
548 if (SL_RESULT_SUCCESS != result) {
549 SL_LOGE("bitsPerSample=%u", (unsigned) pDataFormat->mPCM.bitsPerSample);
550 break;
551 }
552
553 // check the container bit depth
554 if (pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) {
555 result = SL_RESULT_PARAMETER_INVALID;
556 } else if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) {
557 result = SL_RESULT_CONTENT_UNSUPPORTED;
558 }
559 if (SL_RESULT_SUCCESS != result) {
560 SL_LOGE("containerSize=%u, bitsPerSample=%u",
561 (unsigned) pDataFormat->mPCM.containerSize,
562 (unsigned) pDataFormat->mPCM.bitsPerSample);
563 break;
564 }
565
566 // check the channel mask
567 switch (pDataFormat->mPCM.channelMask) {
568 case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT:
569 if (2 != pDataFormat->mPCM.numChannels) {
570 result = SL_RESULT_PARAMETER_INVALID;
571 }
572 break;
573 case SL_SPEAKER_FRONT_LEFT:
574 case SL_SPEAKER_FRONT_RIGHT:
575 case SL_SPEAKER_FRONT_CENTER:
576 if (1 != pDataFormat->mPCM.numChannels) {
577 result = SL_RESULT_PARAMETER_INVALID;
578 }
579 break;
580 case 0:
581 pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ?
582 SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER;
583 break;
584 default:
585 result = SL_RESULT_PARAMETER_INVALID;
586 break;
587 }
588 if (SL_RESULT_SUCCESS != result) {
589 SL_LOGE("channelMask=0x%lx numChannels=%lu", pDataFormat->mPCM.channelMask,
590 pDataFormat->mPCM.numChannels);
591 break;
592 }
593
594 // check the endianness / byte order
595 switch (pDataFormat->mPCM.endianness) {
596 case SL_BYTEORDER_LITTLEENDIAN:
597 case SL_BYTEORDER_BIGENDIAN:
598 break;
599 // native is proposed but not yet in spec
600 default:
601 result = SL_RESULT_PARAMETER_INVALID;
602 break;
603 }
604 if (SL_RESULT_SUCCESS != result) {
605 SL_LOGE("endianness=%u", (unsigned) pDataFormat->mPCM.endianness);
606 break;
607 }
608
609 // here if all checks passed successfully
610
611 } while(0);
612 break;
613
614 case SL_DATAFORMAT_MIME:
615 pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat;
616 if (NULL != pDataFormat->mMIME.mimeType) {
617 // NTH check address for validity
618 size_t len = strlen((const char *) pDataFormat->mMIME.mimeType);
619 SLchar *myMIME = (SLchar *) malloc(len + 1);
620 if (NULL == myMIME) {
621 result = SL_RESULT_MEMORY_FAILURE;
622 } else {
623 memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1);
624 // make sure MIME string was not modified asynchronously
625 if ('\0' != myMIME[len]) {
626 free(myMIME);
627 myMIME = NULL;
628 result = SL_RESULT_PRECONDITIONS_VIOLATED;
629 }
630 }
631 pDataFormat->mMIME.mimeType = myMIME;
632 }
633 break;
634
635 default:
636 result = SL_RESULT_PARAMETER_INVALID;
637 SL_LOGE("formatType=%u", (unsigned) formatType);
638 break;
639
640 }
641
642 // make sure format type was not modified asynchronously
643 if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) {
644 result = SL_RESULT_PRECONDITIONS_VIOLATED;
645 }
646
647 }
648
649 return result;
650 }
651
652
653 /** \brief Check interface ID compatibility with respect to a particular data locator format */
654
checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat * pDataLocatorFormat,const ClassTable * class__,unsigned exposedMask)655 SLresult checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat *pDataLocatorFormat,
656 const ClassTable *class__, unsigned exposedMask) {
657 int index;
658 switch (pDataLocatorFormat->mLocator.mLocatorType) {
659 case SL_DATALOCATOR_BUFFERQUEUE:
660 #ifdef ANDROID
661 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
662 #endif
663 // can't request SLSeekItf if data source is a buffer queue
664 index = class__->mMPH_to_index[MPH_SEEK];
665 if (0 <= index) {
666 if (exposedMask & (1 << index)) {
667 SL_LOGE("can't request SL_IID_SEEK with a buffer queue data source");
668 return SL_RESULT_FEATURE_UNSUPPORTED;
669 }
670 }
671 // can't request SLMuteSoloItf if data source is a mono buffer queue
672 index = class__->mMPH_to_index[MPH_MUTESOLO];
673 if (0 <= index) {
674 if ((exposedMask & (1 << index)) &&
675 (SL_DATAFORMAT_PCM == pDataLocatorFormat->mFormat.mFormatType) &&
676 (1 == pDataLocatorFormat->mFormat.mPCM.numChannels)) {
677 SL_LOGE("can't request SL_IID_MUTESOLO with a mono buffer queue data source");
678 return SL_RESULT_FEATURE_UNSUPPORTED;
679 }
680 }
681 break;
682 default:
683 // can't request SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
684 // if the data source is not a buffer queue
685 index = class__->mMPH_to_index[MPH_BUFFERQUEUE];
686 #ifdef ANDROID
687 assert(index == class__->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
688 #endif
689 if (0 <= index) {
690 if (exposedMask & (1 << index)) {
691 SL_LOGE("can't request SL_IID_BUFFERQUEUE "
692 #ifdef ANDROID
693 "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
694 #endif
695 "with a non-buffer queue data source");
696 return SL_RESULT_FEATURE_UNSUPPORTED;
697 }
698 }
699 break;
700 }
701 return SL_RESULT_SUCCESS;
702 }
703
704
705 /** \brief Free the local deep copy of a data format */
706
freeDataFormat(DataFormat * pDataFormat)707 static void freeDataFormat(DataFormat *pDataFormat)
708 {
709 switch (pDataFormat->mFormatType) {
710 case SL_DATAFORMAT_MIME:
711 if (NULL != pDataFormat->mMIME.mimeType) {
712 free(pDataFormat->mMIME.mimeType);
713 pDataFormat->mMIME.mimeType = NULL;
714 }
715 break;
716 default:
717 break;
718 }
719 }
720
721
722 /** \brief Check a data source and make local deep copy */
723
checkDataSource(const SLDataSource * pDataSrc,DataLocatorFormat * pDataLocatorFormat)724 SLresult checkDataSource(const SLDataSource *pDataSrc, DataLocatorFormat *pDataLocatorFormat)
725 {
726 if (NULL == pDataSrc) {
727 SL_LOGE("pDataSrc NULL");
728 return SL_RESULT_PARAMETER_INVALID;
729 }
730 SLDataSource myDataSrc = *pDataSrc;
731 SLresult result;
732 result = checkDataLocator(myDataSrc.pLocator, &pDataLocatorFormat->mLocator);
733 if (SL_RESULT_SUCCESS != result) {
734 return result;
735 }
736 switch (pDataLocatorFormat->mLocator.mLocatorType) {
737
738 case SL_DATALOCATOR_URI:
739 case SL_DATALOCATOR_ADDRESS:
740 case SL_DATALOCATOR_BUFFERQUEUE:
741 case SL_DATALOCATOR_MIDIBUFFERQUEUE:
742 #ifdef ANDROID
743 case SL_DATALOCATOR_ANDROIDFD:
744 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
745 #endif
746 result = checkDataFormat(myDataSrc.pFormat, &pDataLocatorFormat->mFormat);
747 if (SL_RESULT_SUCCESS != result) {
748 freeDataLocator(&pDataLocatorFormat->mLocator);
749 return result;
750 }
751 break;
752
753 case SL_DATALOCATOR_NULL:
754 case SL_DATALOCATOR_OUTPUTMIX:
755 default:
756 // invalid but fall through; the invalid locator will be caught later
757 SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType);
758 // keep going
759
760 case SL_DATALOCATOR_IODEVICE:
761 // for these data locator types, ignore the pFormat as it might be uninitialized
762 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
763 break;
764 }
765
766 pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator;
767 pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat;
768 return SL_RESULT_SUCCESS;
769 }
770
771
772 /** \brief Check a data sink and make local deep copy */
773
checkDataSink(const SLDataSink * pDataSink,DataLocatorFormat * pDataLocatorFormat,SLuint32 objType)774 SLresult checkDataSink(const SLDataSink *pDataSink, DataLocatorFormat *pDataLocatorFormat,
775 SLuint32 objType)
776 {
777 if (NULL == pDataSink) {
778 SL_LOGE("pDataSink NULL");
779 return SL_RESULT_PARAMETER_INVALID;
780 }
781 SLDataSink myDataSink = *pDataSink;
782 SLresult result;
783 result = checkDataLocator(myDataSink.pLocator, &pDataLocatorFormat->mLocator);
784 if (SL_RESULT_SUCCESS != result) {
785 return result;
786 }
787 switch (pDataLocatorFormat->mLocator.mLocatorType) {
788
789 case SL_DATALOCATOR_URI:
790 case SL_DATALOCATOR_ADDRESS:
791 result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat);
792 if (SL_RESULT_SUCCESS != result) {
793 freeDataLocator(&pDataLocatorFormat->mLocator);
794 return result;
795 }
796 break;
797
798 case SL_DATALOCATOR_BUFFERQUEUE:
799 #ifdef ANDROID
800 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
801 #endif
802 if (SL_OBJECTID_AUDIOPLAYER == objType) {
803 SL_LOGE("buffer queue can't be used as data sink for audio player");
804 result = SL_RESULT_PARAMETER_INVALID;
805 } else if (SL_OBJECTID_AUDIORECORDER == objType) {
806 #ifdef ANDROID
807 if (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE !=
808 pDataLocatorFormat->mLocator.mLocatorType) {
809 SL_LOGE("audio recorder source locator must be SL_DATALOCATOR_ANDROIDBUFFERQUEUE");
810 result = SL_RESULT_PARAMETER_INVALID;
811 } else {
812 result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat);
813 }
814 #else
815 SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType);
816 result = SL_RESULT_PARAMETER_INVALID;
817 #endif
818 }
819 if (SL_RESULT_SUCCESS != result) {
820 freeDataLocator(&pDataLocatorFormat->mLocator);
821 return result;
822 }
823 break;
824
825 case SL_DATALOCATOR_NULL:
826 case SL_DATALOCATOR_MIDIBUFFERQUEUE:
827 default:
828 // invalid but fall through; the invalid locator will be caught later
829 SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType);
830 // keep going
831
832 case SL_DATALOCATOR_IODEVICE:
833 case SL_DATALOCATOR_OUTPUTMIX:
834 // for these data locator types, ignore the pFormat as it might be uninitialized
835 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
836 break;
837 }
838
839 pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator;
840 pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat;
841 return SL_RESULT_SUCCESS;
842 }
843
844
845 /** \brief Free the local deep copy of a data locator format */
846
freeDataLocatorFormat(DataLocatorFormat * dlf)847 void freeDataLocatorFormat(DataLocatorFormat *dlf)
848 {
849 freeDataLocator(&dlf->mLocator);
850 freeDataFormat(&dlf->mFormat);
851 }
852
853
854 /* Interface initialization hooks */
855
856 extern void
857 I3DCommit_init(void *),
858 I3DDoppler_init(void *),
859 I3DGrouping_init(void *),
860 I3DLocation_init(void *),
861 I3DMacroscopic_init(void *),
862 I3DSource_init(void *),
863 IAndroidConfiguration_init(void *),
864 IAndroidEffect_init(void *),
865 IAndroidEffectCapabilities_init(void *),
866 IAndroidEffectSend_init(void *),
867 IAudioDecoderCapabilities_init(void *),
868 IAudioEncoder_init(void *),
869 IAudioEncoderCapabilities_init(void *),
870 IAudioIODeviceCapabilities_init(void *),
871 IBassBoost_init(void *),
872 IBufferQueue_init(void *),
873 IDeviceVolume_init(void *),
874 IDynamicInterfaceManagement_init(void *),
875 IDynamicSource_init(void *),
876 IEffectSend_init(void *),
877 IEngine_init(void *),
878 IEngineCapabilities_init(void *),
879 IEnvironmentalReverb_init(void *),
880 IEqualizer_init(void *),
881 ILEDArray_init(void *),
882 IMIDIMessage_init(void *),
883 IMIDIMuteSolo_init(void *),
884 IMIDITempo_init(void *),
885 IMIDITime_init(void *),
886 IMetadataExtraction_init(void *),
887 IMetadataTraversal_init(void *),
888 IMuteSolo_init(void *),
889 IObject_init(void *),
890 IOutputMix_init(void *),
891 IOutputMixExt_init(void *),
892 IPitch_init(void *),
893 IPlay_init(void *),
894 IPlaybackRate_init(void *),
895 IPrefetchStatus_init(void *),
896 IPresetReverb_init(void *),
897 IRatePitch_init(void *),
898 IRecord_init(void *),
899 ISeek_init(void *),
900 IThreadSync_init(void *),
901 IVibra_init(void *),
902 IVirtualizer_init(void *),
903 IVisualization_init(void *),
904 IVolume_init(void *);
905
906 extern void
907 I3DGrouping_deinit(void *),
908 IAndroidEffect_deinit(void *),
909 IAndroidEffectCapabilities_deinit(void *),
910 IBassBoost_deinit(void *),
911 IBufferQueue_deinit(void *),
912 IEngine_deinit(void *),
913 IEnvironmentalReverb_deinit(void *),
914 IEqualizer_deinit(void *),
915 IObject_deinit(void *),
916 IPresetReverb_deinit(void *),
917 IThreadSync_deinit(void *),
918 IVirtualizer_deinit(void *);
919
920 extern bool
921 IAndroidEffectCapabilities_Expose(void *),
922 IBassBoost_Expose(void *),
923 IEnvironmentalReverb_Expose(void *),
924 IEqualizer_Expose(void *),
925 IPresetReverb_Expose(void *),
926 IVirtualizer_Expose(void *);
927
928 #if !(USE_PROFILES & USE_PROFILES_MUSIC)
929 #define IDynamicSource_init NULL
930 #define IMetadataExtraction_init NULL
931 #define IMetadataTraversal_init NULL
932 #define IVisualization_init NULL
933 #endif
934
935 #if !(USE_PROFILES & USE_PROFILES_GAME)
936 #define I3DCommit_init NULL
937 #define I3DDoppler_init NULL
938 #define I3DGrouping_init NULL
939 #define I3DLocation_init NULL
940 #define I3DMacroscopic_init NULL
941 #define I3DSource_init NULL
942 #define IMIDIMessage_init NULL
943 #define IMIDIMuteSolo_init NULL
944 #define IMIDITempo_init NULL
945 #define IMIDITime_init NULL
946 #define IPitch_init NULL
947 #define IRatePitch_init NULL
948 #define I3DGrouping_deinit NULL
949 #endif
950
951 #if !(USE_PROFILES & USE_PROFILES_BASE)
952 #define IAudioDecoderCapabilities_init NULL
953 #define IAudioEncoderCapabilities_init NULL
954 #define IAudioEncoder_init NULL
955 #define IAudioIODeviceCapabilities_init NULL
956 #define IDeviceVolume_init NULL
957 #define IEngineCapabilities_init NULL
958 #define IThreadSync_init NULL
959 #define IThreadSync_deinit NULL
960 #endif
961
962 #if !(USE_PROFILES & USE_PROFILES_OPTIONAL)
963 #define ILEDArray_init NULL
964 #define IVibra_init NULL
965 #endif
966
967 #ifndef ANDROID
968 #define IAndroidConfiguration_init NULL
969 #define IAndroidEffect_init NULL
970 #define IAndroidEffectCapabilities_init NULL
971 #define IAndroidEffectSend_init NULL
972 #define IAndroidEffect_deinit NULL
973 #define IAndroidEffectCapabilities_deinit NULL
974 #define IAndroidEffectCapabilities_Expose NULL
975 #endif
976
977 #ifndef USE_OUTPUTMIXEXT
978 #define IOutputMixExt_init NULL
979 #endif
980
981
982 /*static*/ const struct MPH_init MPH_init_table[MPH_MAX] = {
983 { /* MPH_3DCOMMIT, */ I3DCommit_init, NULL, NULL, NULL, NULL },
984 { /* MPH_3DDOPPLER, */ I3DDoppler_init, NULL, NULL, NULL, NULL },
985 { /* MPH_3DGROUPING, */ I3DGrouping_init, NULL, I3DGrouping_deinit, NULL, NULL },
986 { /* MPH_3DLOCATION, */ I3DLocation_init, NULL, NULL, NULL, NULL },
987 { /* MPH_3DMACROSCOPIC, */ I3DMacroscopic_init, NULL, NULL, NULL, NULL },
988 { /* MPH_3DSOURCE, */ I3DSource_init, NULL, NULL, NULL, NULL },
989 { /* MPH_AUDIODECODERCAPABILITIES, */ IAudioDecoderCapabilities_init, NULL, NULL, NULL, NULL },
990 { /* MPH_AUDIOENCODER, */ IAudioEncoder_init, NULL, NULL, NULL, NULL },
991 { /* MPH_AUDIOENCODERCAPABILITIES, */ IAudioEncoderCapabilities_init, NULL, NULL, NULL, NULL },
992 { /* MPH_AUDIOIODEVICECAPABILITIES, */ IAudioIODeviceCapabilities_init, NULL, NULL, NULL,
993 NULL },
994 { /* MPH_BASSBOOST, */ IBassBoost_init, NULL, IBassBoost_deinit, IBassBoost_Expose, NULL },
995 { /* MPH_BUFFERQUEUE, */ IBufferQueue_init, NULL, IBufferQueue_deinit, NULL, NULL },
996 { /* MPH_DEVICEVOLUME, */ IDeviceVolume_init, NULL, NULL, NULL, NULL },
997 { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ IDynamicInterfaceManagement_init, NULL, NULL, NULL,
998 NULL },
999 { /* MPH_DYNAMICSOURCE, */ IDynamicSource_init, NULL, NULL, NULL, NULL },
1000 { /* MPH_EFFECTSEND, */ IEffectSend_init, NULL, NULL, NULL, NULL },
1001 { /* MPH_ENGINE, */ IEngine_init, NULL, IEngine_deinit, NULL, NULL },
1002 { /* MPH_ENGINECAPABILITIES, */ IEngineCapabilities_init, NULL, NULL, NULL, NULL },
1003 { /* MPH_ENVIRONMENTALREVERB, */ IEnvironmentalReverb_init, NULL, IEnvironmentalReverb_deinit,
1004 IEnvironmentalReverb_Expose, NULL },
1005 { /* MPH_EQUALIZER, */ IEqualizer_init, NULL, IEqualizer_deinit, IEqualizer_Expose, NULL },
1006 { /* MPH_LED, */ ILEDArray_init, NULL, NULL, NULL, NULL },
1007 { /* MPH_METADATAEXTRACTION, */ IMetadataExtraction_init, NULL, NULL, NULL, NULL },
1008 { /* MPH_METADATATRAVERSAL, */ IMetadataTraversal_init, NULL, NULL, NULL, NULL },
1009 { /* MPH_MIDIMESSAGE, */ IMIDIMessage_init, NULL, NULL, NULL, NULL },
1010 { /* MPH_MIDITIME, */ IMIDITime_init, NULL, NULL, NULL, NULL },
1011 { /* MPH_MIDITEMPO, */ IMIDITempo_init, NULL, NULL, NULL, NULL },
1012 { /* MPH_MIDIMUTESOLO, */ IMIDIMuteSolo_init, NULL, NULL, NULL, NULL },
1013 { /* MPH_MUTESOLO, */ IMuteSolo_init, NULL, NULL, NULL, NULL },
1014 { /* MPH_NULL, */ NULL, NULL, NULL, NULL, NULL },
1015 { /* MPH_OBJECT, */ IObject_init, NULL, IObject_deinit, NULL, NULL },
1016 { /* MPH_OUTPUTMIX, */ IOutputMix_init, NULL, NULL, NULL, NULL },
1017 { /* MPH_PITCH, */ IPitch_init, NULL, NULL, NULL, NULL },
1018 { /* MPH_PLAY, */ IPlay_init, NULL, NULL, NULL, NULL },
1019 { /* MPH_PLAYBACKRATE, */ IPlaybackRate_init, NULL, NULL, NULL, NULL },
1020 { /* MPH_PREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL, NULL, NULL },
1021 { /* MPH_PRESETREVERB, */ IPresetReverb_init, NULL, IPresetReverb_deinit,
1022 IPresetReverb_Expose, NULL },
1023 { /* MPH_RATEPITCH, */ IRatePitch_init, NULL, NULL, NULL, NULL },
1024 { /* MPH_RECORD, */ IRecord_init, NULL, NULL, NULL, NULL },
1025 { /* MPH_SEEK, */ ISeek_init, NULL, NULL, NULL, NULL },
1026 { /* MPH_THREADSYNC, */ IThreadSync_init, NULL, IThreadSync_deinit, NULL, NULL },
1027 { /* MPH_VIBRA, */ IVibra_init, NULL, NULL, NULL, NULL },
1028 { /* MPH_VIRTUALIZER, */ IVirtualizer_init, NULL, IVirtualizer_deinit, IVirtualizer_Expose,
1029 NULL },
1030 { /* MPH_VISUALIZATION, */ IVisualization_init, NULL, NULL, NULL, NULL },
1031 { /* MPH_VOLUME, */ IVolume_init, NULL, NULL, NULL, NULL },
1032 { /* MPH_OUTPUTMIXEXT, */ IOutputMixExt_init, NULL, NULL, NULL, NULL },
1033 { /* MPH_ANDROIDEFFECT */ IAndroidEffect_init, NULL, IAndroidEffect_deinit, NULL, NULL },
1034 { /* MPH_ANDROIDEFFECTCAPABILITIES */ IAndroidEffectCapabilities_init, NULL,
1035 IAndroidEffectCapabilities_deinit, IAndroidEffectCapabilities_Expose, NULL },
1036 { /* MPH_ANDROIDEFFECTSEND */ IAndroidEffectSend_init, NULL, NULL, NULL, NULL },
1037 { /* MPH_ANDROIDCONFIGURATION */ IAndroidConfiguration_init, NULL, NULL, NULL, NULL },
1038 { /* MPH_ANDROIDSIMPLEBUFFERQUEUE, */ IBufferQueue_init /* alias */, NULL, NULL, NULL, NULL }
1039 };
1040
1041
1042 /** \brief Construct a new instance of the specified class, exposing selected interfaces */
1043
construct(const ClassTable * class__,unsigned exposedMask,SLEngineItf engine)1044 IObject *construct(const ClassTable *class__, unsigned exposedMask, SLEngineItf engine)
1045 {
1046 IObject *this;
1047 // Do not change this to malloc; we depend on the object being memset to zero
1048 this = (IObject *) calloc(1, class__->mSize);
1049 if (NULL != this) {
1050 SL_LOGV("construct %s at %p", class__->mName, this);
1051 unsigned lossOfControlMask = 0;
1052 // a NULL engine means we are constructing the engine
1053 IEngine *thisEngine = (IEngine *) engine;
1054 if (NULL == thisEngine) {
1055 thisEngine = &((CEngine *) this)->mEngine;
1056 } else {
1057 interface_lock_exclusive(thisEngine);
1058 if (MAX_INSTANCE <= thisEngine->mInstanceCount) {
1059 SL_LOGE("Too many objects");
1060 interface_unlock_exclusive(thisEngine);
1061 free(this);
1062 return NULL;
1063 }
1064 // pre-allocate a pending slot, but don't assign bit from mInstanceMask yet
1065 ++thisEngine->mInstanceCount;
1066 assert(((unsigned) ~0) != thisEngine->mInstanceMask);
1067 interface_unlock_exclusive(thisEngine);
1068 // const, no lock needed
1069 if (thisEngine->mLossOfControlGlobal) {
1070 lossOfControlMask = ~0;
1071 }
1072 }
1073 this->mLossOfControlMask = lossOfControlMask;
1074 this->mClass = class__;
1075 this->mEngine = thisEngine;
1076 const struct iid_vtable *x = class__->mInterfaces;
1077 SLuint8 *interfaceStateP = this->mInterfaceStates;
1078 SLuint32 index;
1079 for (index = 0; index < class__->mInterfaceCount; ++index, ++x, exposedMask >>= 1) {
1080 SLuint8 state;
1081 // initialize all interfaces with init hooks, even if not exposed
1082 const struct MPH_init *mi = &MPH_init_table[x->mMPH];
1083 VoidHook init = mi->mInit;
1084 if (NULL != init) {
1085 void *self = (char *) this + x->mOffset;
1086 // IObject does not have an mThis, so [1] is not always defined
1087 if (index) {
1088 ((IObject **) self)[1] = this;
1089 }
1090 // call the initialization hook
1091 (*init)(self);
1092 // IObject does not require a call to GetInterface
1093 if (index) {
1094 // This trickery invalidates the v-table until GetInterface
1095 ((size_t *) self)[0] ^= ~0;
1096 }
1097 // if interface is exposed, also call the optional expose hook
1098 BoolHook expose;
1099 state = (exposedMask & 1) && ((NULL == (expose = mi->mExpose)) || (*expose)(self)) ?
1100 INTERFACE_EXPOSED : INTERFACE_INITIALIZED;
1101 // FIXME log or report to application if an expose hook on a
1102 // required explicit interface fails at creation time
1103 } else {
1104 state = INTERFACE_UNINITIALIZED;
1105 }
1106 *interfaceStateP++ = state;
1107 }
1108 // note that the new object is not yet published; creator must call IObject_Publish
1109 }
1110 return this;
1111 }
1112
1113
1114 /* This implementation supports at most one engine */
1115
1116 static CEngine *theOneTrueEngine = NULL;
1117 static pthread_mutex_t theOneTrueMutex = PTHREAD_MUTEX_INITIALIZER;
1118
1119
1120 /** \brief Called by dlopen when .so is loaded */
1121
onDlOpen(void)1122 __attribute__((constructor)) static void onDlOpen(void)
1123 {
1124 }
1125
1126
1127 /** \brief Called by dlclose when .so is unloaded */
1128
onDlClose(void)1129 __attribute__((destructor)) static void onDlClose(void)
1130 {
1131 if (NULL != theOneTrueEngine) {
1132 SL_LOGE("Object::Destroy omitted for engine %p", theOneTrueEngine);
1133 }
1134 }
1135
1136 /** \brief Called by IObject::Destroy after engine is destroyed. The parameter refers to the
1137 * previous engine, which is now undefined memory.
1138 */
1139
CEngine_Destroyed(CEngine * self)1140 void CEngine_Destroyed(CEngine *self)
1141 {
1142 int ok;
1143 ok = pthread_mutex_lock(&theOneTrueMutex);
1144 assert(0 == ok);
1145 assert(self == theOneTrueEngine);
1146 theOneTrueEngine = NULL;
1147 ok = pthread_mutex_unlock(&theOneTrueMutex);
1148 assert(0 == ok);
1149 }
1150
1151
1152 /* Initial global entry points */
1153
1154
1155 /** \brief slCreateEngine Function */
1156
slCreateEngine(SLObjectItf * pEngine,SLuint32 numOptions,const SLEngineOption * pEngineOptions,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)1157 SLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
1158 const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
1159 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
1160 {
1161 SL_ENTER_GLOBAL
1162
1163 int ok;
1164 ok = pthread_mutex_lock(&theOneTrueMutex);
1165 assert(0 == ok);
1166
1167 do {
1168
1169 #ifdef ANDROID
1170 android::ProcessState::self()->startThreadPool();
1171 #ifndef USE_BACKPORT
1172 android::DataSource::RegisterDefaultSniffers();
1173 #endif
1174 #endif
1175
1176 if (NULL == pEngine) {
1177 result = SL_RESULT_PARAMETER_INVALID;
1178 break;
1179 }
1180 *pEngine = NULL;
1181
1182 if (NULL != theOneTrueEngine) {
1183 SL_LOGE("slCreateEngine while another engine %p is active", theOneTrueEngine);
1184 result = SL_RESULT_RESOURCE_ERROR;
1185 break;
1186 }
1187
1188 if ((0 < numOptions) && (NULL == pEngineOptions)) {
1189 SL_LOGE("numOptions=%lu and pEngineOptions=NULL", numOptions);
1190 result = SL_RESULT_PARAMETER_INVALID;
1191 break;
1192 }
1193
1194 // default values
1195 SLboolean threadSafe = SL_BOOLEAN_TRUE;
1196 SLboolean lossOfControlGlobal = SL_BOOLEAN_FALSE;
1197
1198 // process engine options
1199 SLuint32 i;
1200 const SLEngineOption *option = pEngineOptions;
1201 result = SL_RESULT_SUCCESS;
1202 for (i = 0; i < numOptions; ++i, ++option) {
1203 switch (option->feature) {
1204 case SL_ENGINEOPTION_THREADSAFE:
1205 threadSafe = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize
1206 break;
1207 case SL_ENGINEOPTION_LOSSOFCONTROL:
1208 lossOfControlGlobal = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize
1209 break;
1210 default:
1211 SL_LOGE("unknown engine option: feature=%lu data=%lu",
1212 option->feature, option->data);
1213 result = SL_RESULT_PARAMETER_INVALID;
1214 break;
1215 }
1216 }
1217 if (SL_RESULT_SUCCESS != result) {
1218 break;
1219 }
1220
1221 unsigned exposedMask;
1222 const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE);
1223 assert(NULL != pCEngine_class);
1224 result = checkInterfaces(pCEngine_class, numInterfaces,
1225 pInterfaceIds, pInterfaceRequired, &exposedMask);
1226 if (SL_RESULT_SUCCESS != result) {
1227 break;
1228 }
1229
1230 CEngine *this = (CEngine *) construct(pCEngine_class, exposedMask, NULL);
1231 if (NULL == this) {
1232 result = SL_RESULT_MEMORY_FAILURE;
1233 break;
1234 }
1235
1236 // initialize fields not associated with an interface
1237 memset(&this->mSyncThread, 0, sizeof(pthread_t));
1238 // initialize fields related to an interface
1239 this->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0;
1240 this->mEngine.mLossOfControlGlobal = lossOfControlGlobal;
1241 this->mEngineCapabilities.mThreadSafe = threadSafe;
1242 IObject_Publish(&this->mObject);
1243 theOneTrueEngine = this;
1244 // return the new engine object
1245 *pEngine = &this->mObject.mItf;
1246
1247 } while(0);
1248
1249 ok = pthread_mutex_unlock(&theOneTrueMutex);
1250 assert(0 == ok);
1251
1252 SL_LEAVE_GLOBAL
1253 }
1254
1255
1256 /** \brief slQueryNumSupportedEngineInterfaces Function */
1257
slQueryNumSupportedEngineInterfaces(SLuint32 * pNumSupportedInterfaces)1258 SLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(SLuint32 *pNumSupportedInterfaces)
1259 {
1260 SL_ENTER_GLOBAL
1261
1262 if (NULL == pNumSupportedInterfaces) {
1263 result = SL_RESULT_PARAMETER_INVALID;
1264 } else {
1265 const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE);
1266 assert(NULL != class__);
1267 SLuint32 count = 0;
1268 SLuint32 i;
1269 for (i = 0; i < class__->mInterfaceCount; ++i) {
1270 switch (class__->mInterfaces[i].mInterface) {
1271 case INTERFACE_IMPLICIT:
1272 case INTERFACE_IMPLICIT_PREREALIZE:
1273 case INTERFACE_EXPLICIT:
1274 case INTERFACE_EXPLICIT_PREREALIZE:
1275 case INTERFACE_DYNAMIC:
1276 ++count;
1277 break;
1278 case INTERFACE_UNAVAILABLE:
1279 break;
1280 default:
1281 assert(false);
1282 break;
1283 }
1284 }
1285 *pNumSupportedInterfaces = count;
1286 result = SL_RESULT_SUCCESS;
1287 }
1288
1289 SL_LEAVE_GLOBAL
1290 }
1291
1292
1293 /** \brief slQuerySupportedEngineInterfaces Function */
1294
slQuerySupportedEngineInterfaces(SLuint32 index,SLInterfaceID * pInterfaceId)1295 SLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId)
1296 {
1297 SL_ENTER_GLOBAL
1298
1299 if (NULL == pInterfaceId) {
1300 result = SL_RESULT_PARAMETER_INVALID;
1301 } else {
1302 *pInterfaceId = NULL;
1303 const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE);
1304 assert(NULL != class__);
1305 result = SL_RESULT_PARAMETER_INVALID; // will be reset later
1306 SLuint32 i;
1307 for (i = 0; i < class__->mInterfaceCount; ++i) {
1308 switch (class__->mInterfaces[i].mInterface) {
1309 case INTERFACE_IMPLICIT:
1310 case INTERFACE_IMPLICIT_PREREALIZE:
1311 case INTERFACE_EXPLICIT:
1312 case INTERFACE_EXPLICIT_PREREALIZE:
1313 case INTERFACE_DYNAMIC:
1314 break;
1315 case INTERFACE_UNAVAILABLE:
1316 continue;
1317 default:
1318 assert(false);
1319 break;
1320 }
1321 if (index == 0) {
1322 // The engine has no aliases, but if it did, this would return only the primary
1323 *pInterfaceId = &SL_IID_array[class__->mInterfaces[i].mMPH];
1324 result = SL_RESULT_SUCCESS;
1325 break;
1326 }
1327 --index;
1328 }
1329 }
1330
1331 SL_LEAVE_GLOBAL
1332 }
1333