Home | History | Annotate | Download | only in itf
      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 /* Engine implementation */
     18 
     19 #include <endian.h>
     20 #include "sles_allinclusive.h"
     21 
     22 
     23 /* Utility functions */
     24 
     25 static SLresult initializeBufferQueueMembers(CAudioPlayer *ap) {
     26     // inline allocation of circular mArray, up to a typical max
     27     if (BUFFER_HEADER_TYPICAL >= ap->mBufferQueue.mNumBuffers) {
     28         ap->mBufferQueue.mArray = ap->mBufferQueue.mTypical;
     29     } else {
     30         // Avoid possible integer overflow during multiplication; this arbitrary
     31         // maximum is big enough to not interfere with real applications, but
     32         // small enough to not overflow.
     33         if (ap->mBufferQueue.mNumBuffers >= 256) {
     34             return SL_RESULT_MEMORY_FAILURE;
     35         }
     36         ap->mBufferQueue.mArray = (BufferHeader *)
     37                 malloc((ap->mBufferQueue.mNumBuffers + 1) * sizeof(BufferHeader));
     38         if (NULL == ap->mBufferQueue.mArray) {
     39             return SL_RESULT_MEMORY_FAILURE;
     40         }
     41     }
     42     ap->mBufferQueue.mFront = ap->mBufferQueue.mArray;
     43     ap->mBufferQueue.mRear = ap->mBufferQueue.mArray;
     44     return SL_RESULT_SUCCESS;
     45 }
     46 
     47 #ifdef ANDROID
     48 static SLresult initializeAndroidBufferQueueMembers(CAudioPlayer *ap) {
     49     // Avoid possible integer overflow during multiplication; this arbitrary
     50     // maximum is big enough to not interfere with real applications, but
     51     // small enough to not overflow.
     52     if (ap->mAndroidBufferQueue.mNumBuffers >= 256) {
     53         return SL_RESULT_MEMORY_FAILURE;
     54     }
     55     ap->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *)
     56             malloc( (ap->mAndroidBufferQueue.mNumBuffers + 1) * sizeof(AdvancedBufferHeader));
     57     if (NULL == ap->mAndroidBufferQueue.mBufferArray) {
     58         return SL_RESULT_MEMORY_FAILURE;
     59     } else {
     60 
     61         // initialize ABQ buffer type
     62         // assert below has been checked in android_audioPlayer_checkSourceSink
     63         assert(SL_DATAFORMAT_MIME == ap->mDataSource.mFormat.mFormatType);
     64         switch (ap->mDataSource.mFormat.mMIME.containerType) {
     65           case SL_CONTAINERTYPE_MPEG_TS:
     66             ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;
     67             break;
     68           case SL_CONTAINERTYPE_AAC:
     69           case SL_CONTAINERTYPE_RAW: {
     70             const char* mime = (char*)ap->mDataSource.mFormat.mMIME.mimeType;
     71             if ((mime != NULL) && !(strcasecmp(mime, (const char *)SL_ANDROID_MIME_AACADTS) &&
     72                     strcasecmp(mime, ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK))) {
     73                 ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeAacadts;
     74             } else {
     75                 ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
     76                 SL_LOGE("CreateAudioPlayer: Invalid buffer type in Android Buffer Queue");
     77                 return SL_RESULT_CONTENT_UNSUPPORTED;
     78             }
     79           } break;
     80           default:
     81             ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
     82             SL_LOGE("CreateAudioPlayer: Invalid buffer type in Android Buffer Queue");
     83             return SL_RESULT_CONTENT_UNSUPPORTED;
     84         }
     85 
     86         ap->mAndroidBufferQueue.mFront = ap->mAndroidBufferQueue.mBufferArray;
     87         ap->mAndroidBufferQueue.mRear  = ap->mAndroidBufferQueue.mBufferArray;
     88     }
     89 
     90     return SL_RESULT_SUCCESS;
     91 }
     92 #endif
     93 
     94 
     95 static SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
     96     SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
     97 {
     98     SL_ENTER_INTERFACE
     99 
    100 #if USE_PROFILES & USE_PROFILES_OPTIONAL
    101     if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_LED != deviceID)) {
    102         result = SL_RESULT_PARAMETER_INVALID;
    103     } else {
    104         *pDevice = NULL;
    105         unsigned exposedMask;
    106         const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE);
    107         if (NULL == pCLEDDevice_class) {
    108             result = SL_RESULT_FEATURE_UNSUPPORTED;
    109         } else {
    110             result = checkInterfaces(pCLEDDevice_class, numInterfaces, pInterfaceIds,
    111                 pInterfaceRequired, &exposedMask, NULL);
    112         }
    113         if (SL_RESULT_SUCCESS == result) {
    114             CLEDDevice *thiz = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self);
    115             if (NULL == thiz) {
    116                 result = SL_RESULT_MEMORY_FAILURE;
    117             } else {
    118                 thiz->mDeviceID = deviceID;
    119                 IObject_Publish(&thiz->mObject);
    120                 // return the new LED object
    121                 *pDevice = &thiz->mObject.mItf;
    122             }
    123         }
    124     }
    125 #else
    126     result = SL_RESULT_FEATURE_UNSUPPORTED;
    127 #endif
    128 
    129     SL_LEAVE_INTERFACE
    130 }
    131 
    132 
    133 static SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
    134     SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
    135 {
    136     SL_ENTER_INTERFACE
    137 
    138 #if USE_PROFILES & USE_PROFILES_OPTIONAL
    139     if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_VIBRA != deviceID)) {
    140         result = SL_RESULT_PARAMETER_INVALID;
    141     } else {
    142         *pDevice = NULL;
    143         unsigned exposedMask;
    144         const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE);
    145         if (NULL == pCVibraDevice_class) {
    146             result = SL_RESULT_FEATURE_UNSUPPORTED;
    147         } else {
    148             result = checkInterfaces(pCVibraDevice_class, numInterfaces,
    149                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
    150         }
    151         if (SL_RESULT_SUCCESS == result) {
    152             CVibraDevice *thiz = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self);
    153             if (NULL == thiz) {
    154                 result = SL_RESULT_MEMORY_FAILURE;
    155             } else {
    156                 thiz->mDeviceID = deviceID;
    157                 IObject_Publish(&thiz->mObject);
    158                 // return the new vibra object
    159                 *pDevice = &thiz->mObject.mItf;
    160             }
    161         }
    162     }
    163 #else
    164     result = SL_RESULT_FEATURE_UNSUPPORTED;
    165 #endif
    166 
    167     SL_LEAVE_INTERFACE
    168 }
    169 
    170 
    171 static SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
    172     SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
    173     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
    174 {
    175     SL_ENTER_INTERFACE
    176 
    177     if (NULL == pPlayer) {
    178        result = SL_RESULT_PARAMETER_INVALID;
    179     } else {
    180         *pPlayer = NULL;
    181         unsigned exposedMask, requiredMask;
    182         const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER);
    183         assert(NULL != pCAudioPlayer_class);
    184         result = checkInterfaces(pCAudioPlayer_class, numInterfaces,
    185             pInterfaceIds, pInterfaceRequired, &exposedMask, &requiredMask);
    186         if (SL_RESULT_SUCCESS == result) {
    187 
    188             // Construct our new AudioPlayer instance
    189             CAudioPlayer *thiz = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self);
    190             if (NULL == thiz) {
    191                 result = SL_RESULT_MEMORY_FAILURE;
    192             } else {
    193 
    194                 do {
    195 
    196                     // Initialize private fields not associated with an interface
    197 
    198                     // Default data source in case of failure in checkDataSource
    199                     thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
    200                     thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL;
    201 
    202                     // Default data sink in case of failure in checkDataSink
    203                     thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
    204                     thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL;
    205 
    206                     // Default is no per-channel mute or solo
    207                     thiz->mMuteMask = 0;
    208                     thiz->mSoloMask = 0;
    209 
    210                     // Will be set soon for PCM buffer queues, or later by platform-specific code
    211                     // during Realize or Prefetch
    212                     thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
    213                     thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
    214 
    215                     // More default values, in case destructor needs to be called early
    216                     thiz->mDirectLevel = 0; // no attenuation
    217 #ifdef USE_OUTPUTMIXEXT
    218                     thiz->mTrack = NULL;
    219                     thiz->mGains[0] = 1.0f;
    220                     thiz->mGains[1] = 1.0f;
    221                     thiz->mDestroyRequested = SL_BOOLEAN_FALSE;
    222 #endif
    223 #ifdef USE_SNDFILE
    224                     thiz->mSndFile.mPathname = NULL;
    225                     thiz->mSndFile.mSNDFILE = NULL;
    226                     memset(&thiz->mSndFile.mSfInfo, 0, sizeof(SF_INFO));
    227                     memset(&thiz->mSndFile.mMutex, 0, sizeof(pthread_mutex_t));
    228                     thiz->mSndFile.mEOF = SL_BOOLEAN_FALSE;
    229                     thiz->mSndFile.mWhich = 0;
    230                     memset(thiz->mSndFile.mBuffer, 0, sizeof(thiz->mSndFile.mBuffer));
    231 #endif
    232 #ifdef ANDROID
    233                     // placement new (explicit constructor)
    234                     // FIXME unnecessary once those fields are encapsulated in one class, rather
    235                     //   than a structure
    236                     //###(void) new (&thiz->mAudioTrack) android::sp<android::AudioTrack>();
    237                     (void) new (&thiz->mTrackPlayer) android::sp<android::TrackPlayerBase>();
    238                     (void) new (&thiz->mCallbackProtector)
    239                             android::sp<android::CallbackProtector>();
    240                     (void) new (&thiz->mAuxEffect) android::sp<android::AudioEffect>();
    241                     (void) new (&thiz->mAPlayer) android::sp<android::GenericPlayer>();
    242                     // Android-specific POD fields are initialized in android_audioPlayer_create,
    243                     // and assume calloc or memset 0 during allocation
    244 #endif
    245 
    246                     // Check the source and sink parameters against generic constraints,
    247                     // and make a local copy of all parameters in case other application threads
    248                     // change memory concurrently.
    249 
    250                     result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
    251                             DATALOCATOR_MASK_URI | DATALOCATOR_MASK_ADDRESS |
    252                             DATALOCATOR_MASK_BUFFERQUEUE
    253 #ifdef ANDROID
    254                             | DATALOCATOR_MASK_ANDROIDFD | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
    255                             | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
    256 #endif
    257                             , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX);
    258 
    259                     if (SL_RESULT_SUCCESS != result) {
    260                         break;
    261                     }
    262 
    263                     result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink,
    264                             DATALOCATOR_MASK_OUTPUTMIX                  // for playback
    265 #ifdef ANDROID
    266                             | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE // for decode to a BQ
    267                             | DATALOCATOR_MASK_BUFFERQUEUE              // for decode to a BQ
    268 #endif
    269                             , DATAFORMAT_MASK_NULL
    270 #ifdef ANDROID
    271                             | DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX  // for decode to PCM
    272 #endif
    273                             );
    274                     if (SL_RESULT_SUCCESS != result) {
    275                         break;
    276                     }
    277 
    278                     // It would be unsafe to ever refer to the application pointers again
    279                     pAudioSrc = NULL;
    280                     pAudioSnk = NULL;
    281 
    282                     // Check that the requested interfaces are compatible with data source and sink
    283                     result = checkSourceSinkVsInterfacesCompatibility(&thiz->mDataSource,
    284                             &thiz->mDataSink, pCAudioPlayer_class, requiredMask);
    285                     if (SL_RESULT_SUCCESS != result) {
    286                         break;
    287                     }
    288 
    289                     // copy the buffer queue count from source locator (for playback) / from the
    290                     // sink locator (for decode on ANDROID build) to the buffer queue interface
    291                     // we have already range-checked the value down to a smaller width
    292                     SLuint16 nbBuffers = 0;
    293                     bool usesAdvancedBufferHeaders = false;
    294                     bool usesSimpleBufferQueue = false;
    295                     // creating an AudioPlayer which decodes AAC ADTS buffers to a PCM buffer queue
    296                     //  will cause usesAdvancedBufferHeaders and usesSimpleBufferQueue to be true
    297                     switch (thiz->mDataSource.mLocator.mLocatorType) {
    298                     case SL_DATALOCATOR_BUFFERQUEUE:
    299 #ifdef ANDROID
    300                     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    301 #endif
    302                         usesSimpleBufferQueue = true;
    303                         nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mBufferQueue.numBuffers;
    304                         assert(SL_DATAFORMAT_PCM == thiz->mDataSource.mFormat.mFormatType
    305                                 || SL_ANDROID_DATAFORMAT_PCM_EX
    306                                     == thiz->mDataSource.mFormat.mFormatType);
    307                         thiz->mNumChannels = thiz->mDataSource.mFormat.mPCM.numChannels;
    308                         thiz->mSampleRateMilliHz = thiz->mDataSource.mFormat.mPCM.samplesPerSec;
    309                         break;
    310 #ifdef ANDROID
    311                     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    312                         usesAdvancedBufferHeaders = true;
    313                         nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mABQ.numBuffers;
    314                         thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers;
    315                         break;
    316 #endif
    317                     default:
    318                         nbBuffers = 0;
    319                         break;
    320                     }
    321 #ifdef ANDROID
    322                     switch (thiz->mDataSink.mLocator.mLocatorType) {
    323                     case SL_DATALOCATOR_BUFFERQUEUE:
    324                     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    325                         usesSimpleBufferQueue = true;
    326                         nbBuffers = thiz->mDataSink.mLocator.mBufferQueue.numBuffers;
    327                         assert(SL_DATAFORMAT_PCM == thiz->mDataSink.mFormat.mFormatType
    328                                 || SL_ANDROID_DATAFORMAT_PCM_EX
    329                                     == thiz->mDataSink.mFormat.mFormatType);
    330                         // FIXME The values specified by the app are meaningless. We get the
    331                         // real values from the decoder.  But the data sink checks currently require
    332                         // that the app specify these useless values.  Needs doc/fix.
    333                         // Instead use the "unknown" values, as needed by prepare completion.
    334                         // thiz->mNumChannels = thiz->mDataSink.mFormat.mPCM.numChannels;
    335                         // thiz->mSampleRateMilliHz = thiz->mDataSink.mFormat.mPCM.samplesPerSec;
    336                         thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
    337                         thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
    338                         break;
    339                     default:
    340                         // leave nbBuffers unchanged
    341                         break;
    342                     }
    343 #endif
    344                     thiz->mBufferQueue.mNumBuffers = nbBuffers;
    345 
    346                     // check the audio source and sink parameters against platform support
    347 #ifdef ANDROID
    348                     result = android_audioPlayer_checkSourceSink(thiz);
    349                     if (SL_RESULT_SUCCESS != result) {
    350                         break;
    351                     }
    352 #endif
    353 
    354 #ifdef USE_SNDFILE
    355                     result = SndFile_checkAudioPlayerSourceSink(thiz);
    356                     if (SL_RESULT_SUCCESS != result) {
    357                         break;
    358                     }
    359 #endif
    360 
    361 #ifdef USE_OUTPUTMIXEXT
    362                     result = IOutputMixExt_checkAudioPlayerSourceSink(thiz);
    363                     if (SL_RESULT_SUCCESS != result) {
    364                         break;
    365                     }
    366 #endif
    367 
    368                     // Allocate memory for buffer queue
    369                     if (usesAdvancedBufferHeaders) {
    370 #ifdef ANDROID
    371                         // locator is SL_DATALOCATOR_ANDROIDBUFFERQUEUE
    372                         result = initializeAndroidBufferQueueMembers(thiz);
    373 #else
    374                         assert(false);
    375 #endif
    376                     }
    377 
    378                     if (usesSimpleBufferQueue) {
    379                         // locator is SL_DATALOCATOR_BUFFERQUEUE
    380                         //         or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
    381                         result = initializeBufferQueueMembers(thiz);
    382                     }
    383 
    384                     // used to store the data source of our audio player
    385                     thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource;
    386 
    387                     // platform-specific initialization
    388 #ifdef ANDROID
    389                     android_audioPlayer_create(thiz);
    390 #endif
    391 
    392                 } while (0);
    393 
    394                 if (SL_RESULT_SUCCESS != result) {
    395                     IObject_Destroy(&thiz->mObject.mItf);
    396                 } else {
    397                     IObject_Publish(&thiz->mObject);
    398                     // return the new audio player object
    399                     *pPlayer = &thiz->mObject.mItf;
    400                 }
    401 
    402             }
    403         }
    404 
    405     }
    406 
    407     SL_LEAVE_INTERFACE
    408 }
    409 
    410 
    411 static SLresult IEngine_CreateAudioRecorder(SLEngineItf self, SLObjectItf *pRecorder,
    412     SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
    413     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
    414 {
    415     SL_ENTER_INTERFACE
    416 
    417 #if (USE_PROFILES & USE_PROFILES_OPTIONAL) || defined(ANDROID)
    418     if (NULL == pRecorder) {
    419         result = SL_RESULT_PARAMETER_INVALID;
    420     } else {
    421         *pRecorder = NULL;
    422         unsigned exposedMask;
    423         const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER);
    424         if (NULL == pCAudioRecorder_class) {
    425             result = SL_RESULT_FEATURE_UNSUPPORTED;
    426         } else {
    427             result = checkInterfaces(pCAudioRecorder_class, numInterfaces,
    428                     pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
    429         }
    430 
    431         if (SL_RESULT_SUCCESS == result) {
    432 
    433             // Construct our new AudioRecorder instance
    434             CAudioRecorder *thiz = (CAudioRecorder *) construct(pCAudioRecorder_class, exposedMask,
    435                     self);
    436             if (NULL == thiz) {
    437                 result = SL_RESULT_MEMORY_FAILURE;
    438             } else {
    439 
    440                 do {
    441 
    442                     // Initialize fields not associated with any interface
    443 
    444                     // Default data source in case of failure in checkDataSource
    445                     thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
    446                     thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL;
    447 
    448                     // Default data sink in case of failure in checkDataSink
    449                     thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
    450                     thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL;
    451 
    452                     // These fields are set to real values by
    453                     // android_audioRecorder_checkSourceSink.  Note that the data sink is
    454                     // always PCM buffer queue, so we know the channel count and sample rate early.
    455                     thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
    456                     thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
    457 #ifdef ANDROID
    458                     // placement new (explicit constructor)
    459                     // FIXME unnecessary once those fields are encapsulated in one class, rather
    460                     //   than a structure
    461                     (void) new (&thiz->mAudioRecord) android::sp<android::AudioRecord>();
    462                     (void) new (&thiz->mCallbackProtector)
    463                             android::sp<android::CallbackProtector>();
    464                     thiz->mRecordSource = AUDIO_SOURCE_DEFAULT;
    465 #endif
    466 
    467                     // Check the source and sink parameters, and make a local copy of all parameters
    468                     result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
    469                             DATALOCATOR_MASK_IODEVICE, DATAFORMAT_MASK_NULL);
    470                     if (SL_RESULT_SUCCESS != result) {
    471                         break;
    472                     }
    473                     result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink,
    474                             DATALOCATOR_MASK_URI
    475 #ifdef ANDROID
    476                             | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
    477 #endif
    478                             , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX
    479                     );
    480                     if (SL_RESULT_SUCCESS != result) {
    481                         break;
    482                     }
    483 
    484                     // It would be unsafe to ever refer to the application pointers again
    485                     pAudioSrc = NULL;
    486                     pAudioSnk = NULL;
    487 
    488                     // check the audio source and sink parameters against platform support
    489 #ifdef ANDROID
    490                     result = android_audioRecorder_checkSourceSink(thiz);
    491                     if (SL_RESULT_SUCCESS != result) {
    492                         SL_LOGE("Cannot create AudioRecorder: invalid source or sink");
    493                         break;
    494                     }
    495 #endif
    496 
    497 #ifdef ANDROID
    498                     // Allocate memory for buffer queue
    499                     SLuint32 locatorType = thiz->mDataSink.mLocator.mLocatorType;
    500                     if (locatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE) {
    501                         thiz->mBufferQueue.mNumBuffers =
    502                             thiz->mDataSink.mLocator.mBufferQueue.numBuffers;
    503                         // inline allocation of circular Buffer Queue mArray, up to a typical max
    504                         if (BUFFER_HEADER_TYPICAL >= thiz->mBufferQueue.mNumBuffers) {
    505                             thiz->mBufferQueue.mArray = thiz->mBufferQueue.mTypical;
    506                         } else {
    507                             // Avoid possible integer overflow during multiplication; this arbitrary
    508                             // maximum is big enough to not interfere with real applications, but
    509                             // small enough to not overflow.
    510                             if (thiz->mBufferQueue.mNumBuffers >= 256) {
    511                                 result = SL_RESULT_MEMORY_FAILURE;
    512                                 break;
    513                             }
    514                             thiz->mBufferQueue.mArray = (BufferHeader *) malloc((thiz->mBufferQueue.
    515                                     mNumBuffers + 1) * sizeof(BufferHeader));
    516                             if (NULL == thiz->mBufferQueue.mArray) {
    517                                 result = SL_RESULT_MEMORY_FAILURE;
    518                                 break;
    519                             }
    520                         }
    521                         thiz->mBufferQueue.mFront = thiz->mBufferQueue.mArray;
    522                         thiz->mBufferQueue.mRear = thiz->mBufferQueue.mArray;
    523                     }
    524 #endif
    525 
    526                     // platform-specific initialization
    527 #ifdef ANDROID
    528                     android_audioRecorder_create(thiz);
    529 #endif
    530 
    531                 } while (0);
    532 
    533                 if (SL_RESULT_SUCCESS != result) {
    534                     IObject_Destroy(&thiz->mObject.mItf);
    535                 } else {
    536                     IObject_Publish(&thiz->mObject);
    537                     // return the new audio recorder object
    538                     *pRecorder = &thiz->mObject.mItf;
    539                 }
    540             }
    541 
    542         }
    543 
    544     }
    545 #else
    546     result = SL_RESULT_FEATURE_UNSUPPORTED;
    547 #endif
    548 
    549     SL_LEAVE_INTERFACE
    550 }
    551 
    552 
    553 static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
    554     SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
    555     SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
    556     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
    557 {
    558     SL_ENTER_INTERFACE
    559 
    560 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE)
    561     if ((NULL == pPlayer) || (NULL == pMIDISrc) || (NULL == pAudioOutput)) {
    562         result = SL_RESULT_PARAMETER_INVALID;
    563     } else {
    564         *pPlayer = NULL;
    565         unsigned exposedMask;
    566         const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER);
    567         if (NULL == pCMidiPlayer_class) {
    568             result = SL_RESULT_FEATURE_UNSUPPORTED;
    569         } else {
    570             result = checkInterfaces(pCMidiPlayer_class, numInterfaces,
    571                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
    572         }
    573         if (SL_RESULT_SUCCESS == result) {
    574             CMidiPlayer *thiz = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self);
    575             if (NULL == thiz) {
    576                 result = SL_RESULT_MEMORY_FAILURE;
    577             } else {
    578 #if 0
    579                 "pMIDISrc", pMIDISrc, URI | MIDIBUFFERQUEUE, NONE
    580                 "pBankSrc", pBanksrc, NULL | URI | ADDRESS, NULL
    581                 "pAudioOutput", pAudioOutput, OUTPUTMIX, NULL
    582                 "pVibra", pVibra, NULL | IODEVICE, NULL
    583                 "pLEDArray", pLEDArray, NULL | IODEVICE, NULL
    584 #endif
    585                 // a fake value - why not use value from IPlay_init? what does CT check for?
    586                 thiz->mPlay.mDuration = 0;
    587                 IObject_Publish(&thiz->mObject);
    588                 // return the new MIDI player object
    589                 *pPlayer = &thiz->mObject.mItf;
    590             }
    591         }
    592     }
    593 #else
    594     result = SL_RESULT_FEATURE_UNSUPPORTED;
    595 #endif
    596 
    597     SL_LEAVE_INTERFACE
    598 }
    599 
    600 
    601 static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
    602     SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
    603 {
    604     SL_ENTER_INTERFACE
    605 
    606 #if USE_PROFILES & USE_PROFILES_GAME
    607     if (NULL == pListener) {
    608         result = SL_RESULT_PARAMETER_INVALID;
    609     } else {
    610         *pListener = NULL;
    611         unsigned exposedMask;
    612         const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER);
    613         if (NULL == pCListener_class) {
    614             result = SL_RESULT_FEATURE_UNSUPPORTED;
    615         } else {
    616             result = checkInterfaces(pCListener_class, numInterfaces,
    617                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
    618         }
    619         if (SL_RESULT_SUCCESS == result) {
    620             CListener *thiz = (CListener *) construct(pCListener_class, exposedMask, self);
    621             if (NULL == thiz) {
    622                 result = SL_RESULT_MEMORY_FAILURE;
    623             } else {
    624                 IObject_Publish(&thiz->mObject);
    625                 // return the new 3D listener object
    626                 *pListener = &thiz->mObject.mItf;
    627             }
    628         }
    629     }
    630 #else
    631     result = SL_RESULT_FEATURE_UNSUPPORTED;
    632 #endif
    633 
    634     SL_LEAVE_INTERFACE
    635 }
    636 
    637 
    638 static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces,
    639     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
    640 {
    641     SL_ENTER_INTERFACE
    642 
    643 #if USE_PROFILES & USE_PROFILES_GAME
    644     if (NULL == pGroup) {
    645         result = SL_RESULT_PARAMETER_INVALID;
    646     } else {
    647         *pGroup = NULL;
    648         unsigned exposedMask;
    649         const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP);
    650         if (NULL == pC3DGroup_class) {
    651             result = SL_RESULT_FEATURE_UNSUPPORTED;
    652         } else {
    653             result = checkInterfaces(pC3DGroup_class, numInterfaces,
    654                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
    655         }
    656         if (SL_RESULT_SUCCESS == result) {
    657             C3DGroup *thiz = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self);
    658             if (NULL == thiz) {
    659                 result = SL_RESULT_MEMORY_FAILURE;
    660             } else {
    661                 thiz->mMemberMask = 0;
    662                 IObject_Publish(&thiz->mObject);
    663                 // return the new 3D group object
    664                 *pGroup = &thiz->mObject.mItf;
    665             }
    666         }
    667     }
    668 #else
    669     result = SL_RESULT_FEATURE_UNSUPPORTED;
    670 #endif
    671 
    672     SL_LEAVE_INTERFACE
    673 }
    674 
    675 
    676 static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces,
    677     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
    678 {
    679     SL_ENTER_INTERFACE
    680 
    681     if (NULL == pMix) {
    682         result = SL_RESULT_PARAMETER_INVALID;
    683     } else {
    684         *pMix = NULL;
    685         unsigned exposedMask;
    686         const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX);
    687         assert(NULL != pCOutputMix_class);
    688         result = checkInterfaces(pCOutputMix_class, numInterfaces,
    689             pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
    690         if (SL_RESULT_SUCCESS == result) {
    691             COutputMix *thiz = (COutputMix *) construct(pCOutputMix_class, exposedMask, self);
    692             if (NULL == thiz) {
    693                 result = SL_RESULT_MEMORY_FAILURE;
    694             } else {
    695 #ifdef ANDROID
    696                 android_outputMix_create(thiz);
    697 #endif
    698 #ifdef USE_SDL
    699                 IEngine *thisEngine = &thiz->mObject.mEngine->mEngine;
    700                 interface_lock_exclusive(thisEngine);
    701                 bool unpause = false;
    702                 if (NULL == thisEngine->mOutputMix) {
    703                     thisEngine->mOutputMix = thiz;
    704                     unpause = true;
    705                 }
    706                 interface_unlock_exclusive(thisEngine);
    707 #endif
    708                 IObject_Publish(&thiz->mObject);
    709 #ifdef USE_SDL
    710                 if (unpause) {
    711                     // Enable SDL_callback to be called periodically by SDL's internal thread
    712                     SDL_PauseAudio(0);
    713                 }
    714 #endif
    715                 // return the new output mix object
    716                 *pMix = &thiz->mObject.mItf;
    717             }
    718         }
    719     }
    720 
    721     SL_LEAVE_INTERFACE
    722 }
    723 
    724 
    725 static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor,
    726     SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
    727     const SLboolean *pInterfaceRequired)
    728 {
    729     SL_ENTER_INTERFACE
    730 
    731 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC)
    732     if (NULL == pMetadataExtractor) {
    733         result = SL_RESULT_PARAMETER_INVALID;
    734     } else {
    735         *pMetadataExtractor = NULL;
    736         unsigned exposedMask;
    737         const ClassTable *pCMetadataExtractor_class =
    738             objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR);
    739         if (NULL == pCMetadataExtractor_class) {
    740             result = SL_RESULT_FEATURE_UNSUPPORTED;
    741         } else {
    742             result = checkInterfaces(pCMetadataExtractor_class, numInterfaces,
    743                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
    744         }
    745         if (SL_RESULT_SUCCESS == result) {
    746             CMetadataExtractor *thiz = (CMetadataExtractor *)
    747                 construct(pCMetadataExtractor_class, exposedMask, self);
    748             if (NULL == thiz) {
    749                 result = SL_RESULT_MEMORY_FAILURE;
    750             } else {
    751 #if 0
    752                 "pDataSource", pDataSource, NONE, NONE
    753 #endif
    754                 IObject_Publish(&thiz->mObject);
    755                 // return the new metadata extractor object
    756                 *pMetadataExtractor = &thiz->mObject.mItf;
    757                 result = SL_RESULT_SUCCESS;
    758             }
    759         }
    760     }
    761 #else
    762     result = SL_RESULT_FEATURE_UNSUPPORTED;
    763 #endif
    764 
    765     SL_LEAVE_INTERFACE
    766 }
    767 
    768 
    769 static SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject,
    770     void *pParameters, SLuint32 objectID, SLuint32 numInterfaces,
    771     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
    772 {
    773     SL_ENTER_INTERFACE
    774 
    775     if (NULL == pObject) {
    776         result = SL_RESULT_PARAMETER_INVALID;
    777     } else {
    778         *pObject = NULL;
    779         result = SL_RESULT_FEATURE_UNSUPPORTED;
    780     }
    781 
    782     SL_LEAVE_INTERFACE
    783 }
    784 
    785 
    786 static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self,
    787     SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
    788 {
    789     SL_ENTER_INTERFACE
    790 
    791     if (NULL == pNumSupportedInterfaces) {
    792         result = SL_RESULT_PARAMETER_INVALID;
    793     } else {
    794         const ClassTable *clazz = objectIDtoClass(objectID);
    795         if (NULL == clazz) {
    796             result = SL_RESULT_FEATURE_UNSUPPORTED;
    797         } else {
    798             SLuint32 count = 0;
    799             SLuint32 i;
    800             for (i = 0; i < clazz->mInterfaceCount; ++i) {
    801                 switch (clazz->mInterfaces[i].mInterface) {
    802                 case INTERFACE_IMPLICIT:
    803                 case INTERFACE_IMPLICIT_PREREALIZE:
    804                 case INTERFACE_EXPLICIT:
    805                 case INTERFACE_EXPLICIT_PREREALIZE:
    806                 case INTERFACE_DYNAMIC:
    807                     ++count;
    808                     break;
    809                 case INTERFACE_UNAVAILABLE:
    810                     break;
    811                 default:
    812                     assert(false);
    813                     break;
    814                 }
    815             }
    816             *pNumSupportedInterfaces = count;
    817             result = SL_RESULT_SUCCESS;
    818         }
    819     }
    820 
    821     SL_LEAVE_INTERFACE;
    822 }
    823 
    824 
    825 static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self,
    826     SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
    827 {
    828     SL_ENTER_INTERFACE
    829 
    830     if (NULL == pInterfaceId) {
    831         result = SL_RESULT_PARAMETER_INVALID;
    832     } else {
    833         *pInterfaceId = NULL;
    834         const ClassTable *clazz = objectIDtoClass(objectID);
    835         if (NULL == clazz) {
    836             result = SL_RESULT_FEATURE_UNSUPPORTED;
    837         } else {
    838             result = SL_RESULT_PARAMETER_INVALID; // will be reset later
    839             SLuint32 i;
    840             for (i = 0; i < clazz->mInterfaceCount; ++i) {
    841                 switch (clazz->mInterfaces[i].mInterface) {
    842                 case INTERFACE_IMPLICIT:
    843                 case INTERFACE_IMPLICIT_PREREALIZE:
    844                 case INTERFACE_EXPLICIT:
    845                 case INTERFACE_EXPLICIT_PREREALIZE:
    846                 case INTERFACE_DYNAMIC:
    847                     break;
    848                 case INTERFACE_UNAVAILABLE:
    849                     continue;
    850                 default:
    851                     assert(false);
    852                     break;
    853                 }
    854                 if (index == 0) {
    855                     *pInterfaceId = &SL_IID_array[clazz->mInterfaces[i].mMPH];
    856                     result = SL_RESULT_SUCCESS;
    857                     break;
    858                 }
    859                 --index;
    860             }
    861         }
    862     }
    863 
    864     SL_LEAVE_INTERFACE
    865 };
    866 
    867 
    868 static const char * const extensionNames[] = {
    869 #ifdef ANDROID
    870 #define _(n) #n
    871 #define __(n) _(n)
    872     "ANDROID_SDK_LEVEL_" __(PLATFORM_SDK_VERSION),
    873 #undef _
    874 #undef __
    875 #else
    876     "WILHELM_DESKTOP",
    877 #endif
    878 };
    879 
    880 
    881 static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions)
    882 {
    883     SL_ENTER_INTERFACE
    884 
    885     if (NULL == pNumExtensions) {
    886         result = SL_RESULT_PARAMETER_INVALID;
    887     } else {
    888         *pNumExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
    889         result = SL_RESULT_SUCCESS;
    890     }
    891 
    892     SL_LEAVE_INTERFACE
    893 }
    894 
    895 
    896 static SLresult IEngine_QuerySupportedExtension(SLEngineItf self,
    897     SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
    898 {
    899     SL_ENTER_INTERFACE
    900 
    901     if (NULL == pNameLength) {
    902         result = SL_RESULT_PARAMETER_INVALID;
    903     } else {
    904         size_t actualNameLength;
    905         unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
    906         if (index >= numExtensions) {
    907             actualNameLength = 0;
    908             result = SL_RESULT_PARAMETER_INVALID;
    909         } else {
    910             const char *extensionName = extensionNames[index];
    911             actualNameLength = strlen(extensionName) + 1;
    912             if (NULL == pExtensionName) {
    913                 // application is querying the name length in order to allocate a buffer
    914                 result = SL_RESULT_SUCCESS;
    915             } else {
    916                 SLint16 availableNameLength = *pNameLength;
    917                 if (0 >= availableNameLength) {
    918                     // there is not even room for the terminating NUL
    919                     result = SL_RESULT_BUFFER_INSUFFICIENT;
    920                 } else if (actualNameLength > (size_t) availableNameLength) {
    921                     // "no invalid strings are written. That is, the null-terminator always exists"
    922                     memcpy(pExtensionName, extensionName, (size_t) availableNameLength - 1);
    923                     pExtensionName[(size_t) availableNameLength - 1] = '\0';
    924                     result = SL_RESULT_BUFFER_INSUFFICIENT;
    925                 } else {
    926                     memcpy(pExtensionName, extensionName, actualNameLength);
    927                     result = SL_RESULT_SUCCESS;
    928                 }
    929             }
    930         }
    931         *pNameLength = actualNameLength;
    932     }
    933 
    934     SL_LEAVE_INTERFACE
    935 }
    936 
    937 
    938 static SLresult IEngine_IsExtensionSupported(SLEngineItf self,
    939     const SLchar *pExtensionName, SLboolean *pSupported)
    940 {
    941     SL_ENTER_INTERFACE
    942 
    943     if (NULL == pSupported) {
    944         result = SL_RESULT_PARAMETER_INVALID;
    945     } else {
    946         SLboolean isSupported = SL_BOOLEAN_FALSE;
    947         if (NULL == pExtensionName) {
    948             result = SL_RESULT_PARAMETER_INVALID;
    949         } else {
    950             unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
    951             unsigned i;
    952             for (i = 0; i < numExtensions; ++i) {
    953                 if (!strcmp((const char *) pExtensionName, extensionNames[i])) {
    954                     isSupported = SL_BOOLEAN_TRUE;
    955                     break;
    956                 }
    957             }
    958             result = SL_RESULT_SUCCESS;
    959         }
    960         *pSupported = isSupported;
    961     }
    962 
    963     SL_LEAVE_INTERFACE
    964 }
    965 
    966 
    967 static const struct SLEngineItf_ IEngine_Itf = {
    968     IEngine_CreateLEDDevice,
    969     IEngine_CreateVibraDevice,
    970     IEngine_CreateAudioPlayer,
    971     IEngine_CreateAudioRecorder,
    972     IEngine_CreateMidiPlayer,
    973     IEngine_CreateListener,
    974     IEngine_Create3DGroup,
    975     IEngine_CreateOutputMix,
    976     IEngine_CreateMetadataExtractor,
    977     IEngine_CreateExtensionObject,
    978     IEngine_QueryNumSupportedInterfaces,
    979     IEngine_QuerySupportedInterfaces,
    980     IEngine_QueryNumSupportedExtensions,
    981     IEngine_QuerySupportedExtension,
    982     IEngine_IsExtensionSupported
    983 };
    984 
    985 void IEngine_init(void *self)
    986 {
    987     IEngine *thiz = (IEngine *) self;
    988     thiz->mItf = &IEngine_Itf;
    989     // mLossOfControlGlobal is initialized in slCreateEngine
    990 #ifdef USE_SDL
    991     thiz->mOutputMix = NULL;
    992 #endif
    993     thiz->mInstanceCount = 1; // ourself
    994     thiz->mInstanceMask = 0;
    995     thiz->mChangedMask = 0;
    996     unsigned i;
    997     for (i = 0; i < MAX_INSTANCE; ++i) {
    998         thiz->mInstances[i] = NULL;
    999     }
   1000     thiz->mShutdown = SL_BOOLEAN_FALSE;
   1001     thiz->mShutdownAck = SL_BOOLEAN_FALSE;
   1002 #if _BYTE_ORDER == _BIG_ENDIAN
   1003     thiz->mNativeEndianness = SL_BYTEORDER_BIGENDIAN;
   1004 #else
   1005     thiz->mNativeEndianness = SL_BYTEORDER_LITTLEENDIAN;
   1006 #endif
   1007 }
   1008 
   1009 void IEngine_deinit(void *self)
   1010 {
   1011 }
   1012 
   1013 
   1014 // OpenMAX AL Engine
   1015 
   1016 
   1017 static XAresult IEngine_CreateCameraDevice(XAEngineItf self, XAObjectItf *pDevice,
   1018         XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
   1019         const XAboolean *pInterfaceRequired)
   1020 {
   1021     XA_ENTER_INTERFACE
   1022 
   1023     //IXAEngine *thiz = (IXAEngine *) self;
   1024     result = SL_RESULT_FEATURE_UNSUPPORTED;
   1025 
   1026     XA_LEAVE_INTERFACE
   1027 }
   1028 
   1029 
   1030 static XAresult IEngine_CreateRadioDevice(XAEngineItf self, XAObjectItf *pDevice,
   1031         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
   1032         const XAboolean *pInterfaceRequired)
   1033 {
   1034     XA_ENTER_INTERFACE
   1035 
   1036     //IXAEngine *thiz = (IXAEngine *) self;
   1037     result = SL_RESULT_FEATURE_UNSUPPORTED;
   1038 
   1039     XA_LEAVE_INTERFACE
   1040 }
   1041 
   1042 
   1043 static XAresult IXAEngine_CreateLEDDevice(XAEngineItf self, XAObjectItf *pDevice, XAuint32 deviceID,
   1044         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
   1045         const XAboolean *pInterfaceRequired)
   1046 {
   1047     // forward to OpenSL ES
   1048     return IEngine_CreateLEDDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
   1049             (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
   1050             (const SLboolean *) pInterfaceRequired);
   1051 }
   1052 
   1053 
   1054 static XAresult IXAEngine_CreateVibraDevice(XAEngineItf self, XAObjectItf *pDevice,
   1055         XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
   1056         const XAboolean *pInterfaceRequired)
   1057 {
   1058     // forward to OpenSL ES
   1059     return IEngine_CreateVibraDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
   1060             (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
   1061             (const SLboolean *) pInterfaceRequired);
   1062 }
   1063 
   1064 
   1065 static XAresult IEngine_CreateMediaPlayer(XAEngineItf self, XAObjectItf *pPlayer,
   1066         XADataSource *pDataSrc, XADataSource *pBankSrc, XADataSink *pAudioSnk,
   1067         XADataSink *pImageVideoSnk, XADataSink *pVibra, XADataSink *pLEDArray,
   1068         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
   1069         const XAboolean *pInterfaceRequired)
   1070 {
   1071     XA_ENTER_INTERFACE
   1072 
   1073     if (NULL == pPlayer) {
   1074         result = XA_RESULT_PARAMETER_INVALID;
   1075     } else {
   1076         *pPlayer = NULL;
   1077         unsigned exposedMask;
   1078         const ClassTable *pCMediaPlayer_class = objectIDtoClass(XA_OBJECTID_MEDIAPLAYER);
   1079         assert(NULL != pCMediaPlayer_class);
   1080         result = checkInterfaces(pCMediaPlayer_class, numInterfaces,
   1081                 (const SLInterfaceID *) pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
   1082         if (XA_RESULT_SUCCESS == result) {
   1083 
   1084             // Construct our new MediaPlayer instance
   1085             CMediaPlayer *thiz = (CMediaPlayer *) construct(pCMediaPlayer_class, exposedMask,
   1086                     &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf);
   1087             if (NULL == thiz) {
   1088                 result = XA_RESULT_MEMORY_FAILURE;
   1089             } else {
   1090 
   1091                 do {
   1092 
   1093                     // Initialize private fields not associated with an interface
   1094 
   1095                     // Default data source in case of failure in checkDataSource
   1096                     thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
   1097                     thiz->mDataSource.mFormat.mFormatType = XA_DATAFORMAT_NULL;
   1098 
   1099                     // Default andio and image sink in case of failure in checkDataSink
   1100                     thiz->mAudioSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
   1101                     thiz->mAudioSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;
   1102                     thiz->mImageVideoSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
   1103                     thiz->mImageVideoSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;
   1104 
   1105                     // More default values, in case destructor needs to be called early
   1106                     thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
   1107 
   1108 #ifdef ANDROID
   1109                     // placement new (explicit constructor)
   1110                     // FIXME unnecessary once those fields are encapsulated in one class, rather
   1111                     //   than a structure
   1112                     (void) new (&thiz->mAVPlayer) android::sp<android::GenericPlayer>();
   1113                     (void) new (&thiz->mCallbackProtector)
   1114                             android::sp<android::CallbackProtector>();
   1115                     // Android-specific POD fields are initialized in android_Player_create,
   1116                     // and assume calloc or memset 0 during allocation
   1117 #endif
   1118 
   1119                     // Check the source and sink parameters against generic constraints
   1120 
   1121                     result = checkDataSource("pDataSrc", (const SLDataSource *) pDataSrc,
   1122                             &thiz->mDataSource, DATALOCATOR_MASK_URI
   1123 #ifdef ANDROID
   1124                             | DATALOCATOR_MASK_ANDROIDFD
   1125                             | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
   1126 #endif
   1127                             , DATAFORMAT_MASK_MIME);
   1128                     if (XA_RESULT_SUCCESS != result) {
   1129                         break;
   1130                     }
   1131 
   1132                     result = checkDataSource("pBankSrc", (const SLDataSource *) pBankSrc,
   1133                             &thiz->mBankSource, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_URI |
   1134                             DATALOCATOR_MASK_ADDRESS, DATAFORMAT_MASK_NULL);
   1135                     if (XA_RESULT_SUCCESS != result) {
   1136                         break;
   1137                     }
   1138 
   1139                     result = checkDataSink("pAudioSnk", (const SLDataSink *) pAudioSnk,
   1140                             &thiz->mAudioSink, DATALOCATOR_MASK_OUTPUTMIX, DATAFORMAT_MASK_NULL);
   1141                     if (XA_RESULT_SUCCESS != result) {
   1142                         break;
   1143                     }
   1144 
   1145                     result = checkDataSink("pImageVideoSnk", (const SLDataSink *) pImageVideoSnk,
   1146                             &thiz->mImageVideoSink,
   1147                             DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_NATIVEDISPLAY,
   1148                             DATAFORMAT_MASK_NULL);
   1149                     if (XA_RESULT_SUCCESS != result) {
   1150                         break;
   1151                     }
   1152 
   1153                     result = checkDataSink("pVibra", (const SLDataSink *) pVibra, &thiz->mVibraSink,
   1154                             DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
   1155                             DATAFORMAT_MASK_NULL);
   1156                     if (XA_RESULT_SUCCESS != result) {
   1157                         break;
   1158                     }
   1159 
   1160                     result = checkDataSink("pLEDArray", (const SLDataSink *) pLEDArray,
   1161                             &thiz->mLEDArraySink, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
   1162                             DATAFORMAT_MASK_NULL);
   1163                     if (XA_RESULT_SUCCESS != result) {
   1164                         break;
   1165                     }
   1166 
   1167                     // Unsafe to ever refer to application pointers again
   1168                     pDataSrc = NULL;
   1169                     pBankSrc = NULL;
   1170                     pAudioSnk = NULL;
   1171                     pImageVideoSnk = NULL;
   1172                     pVibra = NULL;
   1173                     pLEDArray = NULL;
   1174 
   1175                     // Check that the requested interfaces are compatible with the data source
   1176                     // FIXME implement
   1177 
   1178                     // check the source and sink parameters against platform support
   1179 #ifdef ANDROID
   1180                     result = android_Player_checkSourceSink(thiz);
   1181                     if (XA_RESULT_SUCCESS != result) {
   1182                         break;
   1183                     }
   1184 #endif
   1185 
   1186 #ifdef ANDROID
   1187                     // AndroidBufferQueue-specific initialization
   1188                     if (XA_DATALOCATOR_ANDROIDBUFFERQUEUE ==
   1189                             thiz->mDataSource.mLocator.mLocatorType) {
   1190                         XAuint16 nbBuffers = (XAuint16) thiz->mDataSource.mLocator.mABQ.numBuffers;
   1191 
   1192                         // Avoid possible integer overflow during multiplication; this arbitrary
   1193                         // maximum is big enough to not interfere with real applications, but
   1194                         // small enough to not overflow.
   1195                         if (nbBuffers >= 256) {
   1196                             result = SL_RESULT_MEMORY_FAILURE;
   1197                             break;
   1198                         }
   1199 
   1200                         // initialize ABQ buffer type
   1201                         // assert below has been checked in android_audioPlayer_checkSourceSink
   1202                         assert(XA_DATAFORMAT_MIME == thiz->mDataSource.mFormat.mFormatType);
   1203                         if (XA_CONTAINERTYPE_MPEG_TS ==
   1204                                 thiz->mDataSource.mFormat.mMIME.containerType) {
   1205                             thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;
   1206 
   1207                             // Set the container type for the StreamInformation interface
   1208                             XAMediaContainerInformation *containerInfo =
   1209                                     (XAMediaContainerInformation*)
   1210                                         // always storing container info at index 0, as per spec
   1211                                         &thiz->mStreamInfo.mStreamInfoTable.itemAt(0).containerInfo;
   1212                             containerInfo->containerType = XA_CONTAINERTYPE_MPEG_TS;
   1213                             // there are no streams at this stage
   1214                             containerInfo->numStreams = 0;
   1215 
   1216                         } else {
   1217                             thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
   1218                             SL_LOGE("Invalid buffer type in Android Buffer Queue");
   1219                             result = SL_RESULT_CONTENT_UNSUPPORTED;
   1220                         }
   1221 
   1222                         // initialize ABQ memory
   1223                         thiz->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *)
   1224                                     malloc( (nbBuffers + 1) * sizeof(AdvancedBufferHeader));
   1225                         if (NULL == thiz->mAndroidBufferQueue.mBufferArray) {
   1226                             result = SL_RESULT_MEMORY_FAILURE;
   1227                             break;
   1228                         } else {
   1229                             thiz->mAndroidBufferQueue.mFront =
   1230                                     thiz->mAndroidBufferQueue.mBufferArray;
   1231                             thiz->mAndroidBufferQueue.mRear =
   1232                                     thiz->mAndroidBufferQueue.mBufferArray;
   1233                         }
   1234 
   1235                         thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers;
   1236 
   1237                     }
   1238 #endif
   1239 
   1240                     // used to store the data source of our audio player
   1241                     thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource;
   1242 
   1243                     // platform-specific initialization
   1244 #ifdef ANDROID
   1245                     android_Player_create(thiz);
   1246 #endif
   1247 
   1248                 } while (0);
   1249 
   1250                 if (XA_RESULT_SUCCESS != result) {
   1251                     IObject_Destroy(&thiz->mObject.mItf);
   1252                 } else {
   1253                     IObject_Publish(&thiz->mObject);
   1254                     // return the new media player object
   1255                     *pPlayer = (XAObjectItf) &thiz->mObject.mItf;
   1256                 }
   1257 
   1258             }
   1259         }
   1260 
   1261     }
   1262 
   1263     XA_LEAVE_INTERFACE
   1264 }
   1265 
   1266 
   1267 static XAresult IEngine_CreateMediaRecorder(XAEngineItf self, XAObjectItf *pRecorder,
   1268         XADataSource *pAudioSrc, XADataSource *pImageVideoSrc,
   1269         XADataSink *pDataSnk, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
   1270         const XAboolean *pInterfaceRequired)
   1271 {
   1272     XA_ENTER_INTERFACE
   1273 
   1274     //IXAEngine *thiz = (IXAEngine *) self;
   1275     result = SL_RESULT_FEATURE_UNSUPPORTED;
   1276 
   1277 #if 0
   1278     "pAudioSrc", pAudioSrc,
   1279     "pImageVideoSrc", pImageVideoSrc,
   1280     "pDataSink", pDataSnk,
   1281 #endif
   1282 
   1283     XA_LEAVE_INTERFACE
   1284 }
   1285 
   1286 
   1287 static XAresult IXAEngine_CreateOutputMix(XAEngineItf self, XAObjectItf *pMix,
   1288         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
   1289         const XAboolean *pInterfaceRequired)
   1290 {
   1291     // forward to OpenSL ES
   1292     return IEngine_CreateOutputMix(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
   1293             (SLObjectItf *) pMix, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
   1294             (const SLboolean *) pInterfaceRequired);
   1295 }
   1296 
   1297 
   1298 static XAresult IXAEngine_CreateMetadataExtractor(XAEngineItf self, XAObjectItf *pMetadataExtractor,
   1299             XADataSource *pDataSource, XAuint32 numInterfaces,
   1300             const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
   1301 {
   1302     // forward to OpenSL ES
   1303     return IEngine_CreateMetadataExtractor(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
   1304             (SLObjectItf *) pMetadataExtractor, (SLDataSource *) pDataSource, numInterfaces,
   1305             (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
   1306 }
   1307 
   1308 
   1309 static XAresult IXAEngine_CreateExtensionObject(XAEngineItf self, XAObjectItf *pObject,
   1310             void *pParameters, XAuint32 objectID, XAuint32 numInterfaces,
   1311             const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
   1312 {
   1313     // forward to OpenSL ES
   1314     return IEngine_CreateExtensionObject(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
   1315             (SLObjectItf *) pObject, pParameters, objectID, numInterfaces,
   1316             (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
   1317 }
   1318 
   1319 
   1320 static XAresult IEngine_GetImplementationInfo(XAEngineItf self, XAuint32 *pMajor, XAuint32 *pMinor,
   1321         XAuint32 *pStep, /* XAuint32 nImplementationTextSize, */ const XAchar *pImplementationText)
   1322 {
   1323     XA_ENTER_INTERFACE
   1324 
   1325     //IXAEngine *thiz = (IXAEngine *) self;
   1326     result = SL_RESULT_FEATURE_UNSUPPORTED;
   1327 
   1328     XA_LEAVE_INTERFACE
   1329 }
   1330 
   1331 
   1332 static XAresult IXAEngine_QuerySupportedProfiles(XAEngineItf self, XAint16 *pProfilesSupported)
   1333 {
   1334     XA_ENTER_INTERFACE
   1335 
   1336     if (NULL == pProfilesSupported) {
   1337         result = XA_RESULT_PARAMETER_INVALID;
   1338     } else {
   1339 #if 1
   1340         *pProfilesSupported = 0;
   1341         // the code below was copied from OpenSL ES and needs to be adapted for OpenMAX AL.
   1342 #else
   1343         // The generic implementation doesn't implement any of the profiles, they shouldn't be
   1344         // declared as supported. Also exclude the fake profiles BASE and OPTIONAL.
   1345         *pProfilesSupported = USE_PROFILES &
   1346                 (USE_PROFILES_GAME | USE_PROFILES_MUSIC | USE_PROFILES_PHONE);
   1347 #endif
   1348         result = XA_RESULT_SUCCESS;
   1349     }
   1350 
   1351     XA_LEAVE_INTERFACE
   1352 }
   1353 
   1354 
   1355 static XAresult IXAEngine_QueryNumSupportedInterfaces(XAEngineItf self, XAuint32 objectID,
   1356         XAuint32 *pNumSupportedInterfaces)
   1357 {
   1358     // forward to OpenSL ES
   1359     return IEngine_QueryNumSupportedInterfaces(
   1360             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID,
   1361             pNumSupportedInterfaces);
   1362 }
   1363 
   1364 
   1365 static XAresult IXAEngine_QuerySupportedInterfaces(XAEngineItf self, XAuint32 objectID,
   1366         XAuint32 index, XAInterfaceID *pInterfaceId)
   1367 {
   1368     // forward to OpenSL ES
   1369     return IEngine_QuerySupportedInterfaces(
   1370             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID, index,
   1371             (SLInterfaceID *) pInterfaceId);
   1372 }
   1373 
   1374 
   1375 static XAresult IXAEngine_QueryNumSupportedExtensions(XAEngineItf self, XAuint32 *pNumExtensions)
   1376 {
   1377     // forward to OpenSL ES
   1378     return IEngine_QueryNumSupportedExtensions(
   1379             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, pNumExtensions);
   1380 }
   1381 
   1382 
   1383 static XAresult IXAEngine_QuerySupportedExtension(XAEngineItf self, XAuint32 index,
   1384         XAchar *pExtensionName, XAint16 *pNameLength)
   1385 {
   1386     // forward to OpenSL ES
   1387     return IEngine_QuerySupportedExtension(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
   1388             index, pExtensionName, (SLint16 *) pNameLength);
   1389 }
   1390 
   1391 
   1392 static XAresult IXAEngine_IsExtensionSupported(XAEngineItf self, const XAchar *pExtensionName,
   1393         XAboolean *pSupported)
   1394 {
   1395     // forward to OpenSL ES
   1396     return IEngine_IsExtensionSupported(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
   1397             pExtensionName, pSupported);
   1398 }
   1399 
   1400 
   1401 static XAresult IXAEngine_QueryLEDCapabilities(XAEngineItf self, XAuint32 *pIndex,
   1402         XAuint32 *pLEDDeviceID, XALEDDescriptor *pDescriptor)
   1403 {
   1404     // forward to OpenSL ES EngineCapabilities
   1405     return (XAresult) IEngineCapabilities_QueryLEDCapabilities(
   1406             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
   1407             pLEDDeviceID, (SLLEDDescriptor *) pDescriptor);
   1408 }
   1409 
   1410 
   1411 static XAresult IXAEngine_QueryVibraCapabilities(XAEngineItf self, XAuint32 *pIndex,
   1412         XAuint32 *pVibraDeviceID, XAVibraDescriptor *pDescriptor)
   1413 {
   1414     // forward to OpenSL ES EngineCapabilities
   1415     return (XAresult) IEngineCapabilities_QueryVibraCapabilities(
   1416             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
   1417             pVibraDeviceID, (SLVibraDescriptor *) pDescriptor);
   1418 }
   1419 
   1420 
   1421 // OpenMAX AL engine v-table
   1422 
   1423 static const struct XAEngineItf_ IXAEngine_Itf = {
   1424     IEngine_CreateCameraDevice,
   1425     IEngine_CreateRadioDevice,
   1426     IXAEngine_CreateLEDDevice,
   1427     IXAEngine_CreateVibraDevice,
   1428     IEngine_CreateMediaPlayer,
   1429     IEngine_CreateMediaRecorder,
   1430     IXAEngine_CreateOutputMix,
   1431     IXAEngine_CreateMetadataExtractor,
   1432     IXAEngine_CreateExtensionObject,
   1433     IEngine_GetImplementationInfo,
   1434     IXAEngine_QuerySupportedProfiles,
   1435     IXAEngine_QueryNumSupportedInterfaces,
   1436     IXAEngine_QuerySupportedInterfaces,
   1437     IXAEngine_QueryNumSupportedExtensions,
   1438     IXAEngine_QuerySupportedExtension,
   1439     IXAEngine_IsExtensionSupported,
   1440     IXAEngine_QueryLEDCapabilities,
   1441     IXAEngine_QueryVibraCapabilities
   1442 };
   1443 
   1444 
   1445 void IXAEngine_init(void *self)
   1446 {
   1447     IXAEngine *thiz = (IXAEngine *) self;
   1448     thiz->mItf = &IXAEngine_Itf;
   1449 }
   1450 
   1451 
   1452 void IXAEngine_deinit(void *self)
   1453 {
   1454 }
   1455