/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Engine implementation */

#include "sles_allinclusive.h"


/* Utility functions */

static SLresult initializeBufferQueueMembers(CAudioPlayer *ap) {
    // inline allocation of circular mArray, up to a typical max
    if (BUFFER_HEADER_TYPICAL >= ap->mBufferQueue.mNumBuffers) {
        ap->mBufferQueue.mArray = ap->mBufferQueue.mTypical;
    } else {
        // Avoid possible integer overflow during multiplication; this arbitrary
        // maximum is big enough to not interfere with real applications, but
        // small enough to not overflow.
        if (ap->mBufferQueue.mNumBuffers >= 256) {
            return SL_RESULT_MEMORY_FAILURE;
        }
        ap->mBufferQueue.mArray = (BufferHeader *)
                malloc((ap->mBufferQueue.mNumBuffers + 1) * sizeof(BufferHeader));
        if (NULL == ap->mBufferQueue.mArray) {
            return SL_RESULT_MEMORY_FAILURE;
        }
    }
    ap->mBufferQueue.mFront = ap->mBufferQueue.mArray;
    ap->mBufferQueue.mRear = ap->mBufferQueue.mArray;
    return SL_RESULT_SUCCESS;
}

#ifdef ANDROID
static SLresult initializeAndroidBufferQueueMembers(CAudioPlayer *ap) {
    // Avoid possible integer overflow during multiplication; this arbitrary
    // maximum is big enough to not interfere with real applications, but
    // small enough to not overflow.
    if (ap->mAndroidBufferQueue.mNumBuffers >= 256) {
        return SL_RESULT_MEMORY_FAILURE;
    }
    ap->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *)
            malloc( (ap->mAndroidBufferQueue.mNumBuffers + 1) * sizeof(AdvancedBufferHeader));
    if (NULL == ap->mAndroidBufferQueue.mBufferArray) {
        return SL_RESULT_MEMORY_FAILURE;
    } else {

        // initialize ABQ buffer type
        // assert below has been checked in android_audioPlayer_checkSourceSink
        assert(SL_DATAFORMAT_MIME == ap->mDataSource.mFormat.mFormatType);
        switch(ap->mDataSource.mFormat.mMIME.containerType) {
          case SL_CONTAINERTYPE_MPEG_TS:
            ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;
            break;
          case SL_CONTAINERTYPE_AAC:
          case SL_CONTAINERTYPE_RAW: {
            const char* mime = (char*)ap->mDataSource.mFormat.mMIME.mimeType;
            if ((mime != NULL) && !(strcasecmp(mime, (const char *)SL_ANDROID_MIME_AACADTS) &&
                    strcasecmp(mime, ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK))) {
                ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeAacadts;
            } else {
                ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
                SL_LOGE("CreateAudioPlayer: Invalid buffer type in Android Buffer Queue");
                return SL_RESULT_CONTENT_UNSUPPORTED;
            }
          } break;
          default:
            ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
            SL_LOGE("CreateAudioPlayer: Invalid buffer type in Android Buffer Queue");
            return SL_RESULT_CONTENT_UNSUPPORTED;
        }

        ap->mAndroidBufferQueue.mFront = ap->mAndroidBufferQueue.mBufferArray;
        ap->mAndroidBufferQueue.mRear  = ap->mAndroidBufferQueue.mBufferArray;
    }

    return SL_RESULT_SUCCESS;
}
#endif


static SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

#if USE_PROFILES & USE_PROFILES_OPTIONAL
    if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_LED != deviceID)) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pDevice = NULL;
        unsigned exposedMask;
        const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE);
        if (NULL == pCLEDDevice_class) {
            result = SL_RESULT_FEATURE_UNSUPPORTED;
        } else {
            result = checkInterfaces(pCLEDDevice_class, numInterfaces, pInterfaceIds,
                pInterfaceRequired, &exposedMask, NULL);
        }
        if (SL_RESULT_SUCCESS == result) {
            CLEDDevice *thiz = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self);
            if (NULL == thiz) {
                result = SL_RESULT_MEMORY_FAILURE;
            } else {
                thiz->mDeviceID = deviceID;
                IObject_Publish(&thiz->mObject);
                // return the new LED object
                *pDevice = &thiz->mObject.mItf;
            }
        }
    }
#else
    result = SL_RESULT_FEATURE_UNSUPPORTED;
#endif

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

#if USE_PROFILES & USE_PROFILES_OPTIONAL
    if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_VIBRA != deviceID)) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pDevice = NULL;
        unsigned exposedMask;
        const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE);
        if (NULL == pCVibraDevice_class) {
            result = SL_RESULT_FEATURE_UNSUPPORTED;
        } else {
            result = checkInterfaces(pCVibraDevice_class, numInterfaces,
                pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
        }
        if (SL_RESULT_SUCCESS == result) {
            CVibraDevice *thiz = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self);
            if (NULL == thiz) {
                result = SL_RESULT_MEMORY_FAILURE;
            } else {
                thiz->mDeviceID = deviceID;
                IObject_Publish(&thiz->mObject);
                // return the new vibra object
                *pDevice = &thiz->mObject.mItf;
            }
        }
    }
#else
    result = SL_RESULT_FEATURE_UNSUPPORTED;
#endif

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

    if (NULL == pPlayer) {
       result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pPlayer = NULL;
        unsigned exposedMask, requiredMask;
        const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER);
        assert(NULL != pCAudioPlayer_class);
        result = checkInterfaces(pCAudioPlayer_class, numInterfaces,
            pInterfaceIds, pInterfaceRequired, &exposedMask, &requiredMask);
        if (SL_RESULT_SUCCESS == result) {

            // Construct our new AudioPlayer instance
            CAudioPlayer *thiz = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self);
            if (NULL == thiz) {
                result = SL_RESULT_MEMORY_FAILURE;
            } else {

                do {

                    // Initialize private fields not associated with an interface

                    // Default data source in case of failure in checkDataSource
                    thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
                    thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL;

                    // Default data sink in case of failure in checkDataSink
                    thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
                    thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL;

                    // Default is no per-channel mute or solo
                    thiz->mMuteMask = 0;
                    thiz->mSoloMask = 0;

                    // Will be set soon for PCM buffer queues, or later by platform-specific code
                    // during Realize or Prefetch
                    thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
                    thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;

                    // More default values, in case destructor needs to be called early
                    thiz->mDirectLevel = 0; // no attenuation
#ifdef USE_OUTPUTMIXEXT
                    thiz->mTrack = NULL;
                    thiz->mGains[0] = 1.0f;
                    thiz->mGains[1] = 1.0f;
                    thiz->mDestroyRequested = SL_BOOLEAN_FALSE;
#endif
#ifdef USE_SNDFILE
                    thiz->mSndFile.mPathname = NULL;
                    thiz->mSndFile.mSNDFILE = NULL;
                    memset(&thiz->mSndFile.mSfInfo, 0, sizeof(SF_INFO));
                    memset(&thiz->mSndFile.mMutex, 0, sizeof(pthread_mutex_t));
                    thiz->mSndFile.mEOF = SL_BOOLEAN_FALSE;
                    thiz->mSndFile.mWhich = 0;
                    memset(thiz->mSndFile.mBuffer, 0, sizeof(thiz->mSndFile.mBuffer));
#endif
#ifdef ANDROID
                    // placement new (explicit constructor)
                    // FIXME unnecessary once those fields are encapsulated in one class, rather
                    //   than a structure
                    (void) new (&thiz->mAudioTrack) android::sp<android::AudioTrack>();
                    (void) new (&thiz->mCallbackProtector)
                            android::sp<android::CallbackProtector>();
                    (void) new (&thiz->mAuxEffect) android::sp<android::AudioEffect>();
                    (void) new (&thiz->mAPlayer) android::sp<android::GenericPlayer>();
                    // Android-specific POD fields are initialized in android_audioPlayer_create,
                    // and assume calloc or memset 0 during allocation
#endif

                    // Check the source and sink parameters against generic constraints,
                    // and make a local copy of all parameters in case other application threads
                    // change memory concurrently.

                    result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
                            DATALOCATOR_MASK_URI | DATALOCATOR_MASK_ADDRESS |
                            DATALOCATOR_MASK_BUFFERQUEUE
#ifdef ANDROID
                            | DATALOCATOR_MASK_ANDROIDFD | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
                            | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
#endif
                            , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM);

                    if (SL_RESULT_SUCCESS != result) {
                        break;
                    }

                    result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink,
                            DATALOCATOR_MASK_OUTPUTMIX                  // for playback
#ifdef ANDROID
                            | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE // for decode to a BQ
                            | DATALOCATOR_MASK_BUFFERQUEUE              // for decode to a BQ
#endif
                            , DATAFORMAT_MASK_NULL
#ifdef ANDROID
                            | DATAFORMAT_MASK_PCM                       // for decode to PCM
#endif
                            );
                    if (SL_RESULT_SUCCESS != result) {
                        break;
                    }

                    // It would be unsafe to ever refer to the application pointers again
                    pAudioSrc = NULL;
                    pAudioSnk = NULL;

                    // Check that the requested interfaces are compatible with data source and sink
                    result = checkSourceSinkVsInterfacesCompatibility(&thiz->mDataSource,
                            &thiz->mDataSink, pCAudioPlayer_class, requiredMask);
                    if (SL_RESULT_SUCCESS != result) {
                        break;
                    }

                    // copy the buffer queue count from source locator (for playback) / from the
                    // sink locator (for decode on ANDROID build) to the buffer queue interface
                    // we have already range-checked the value down to a smaller width
                    SLuint16 nbBuffers = 0;
                    bool usesAdvancedBufferHeaders = false;
                    bool usesSimpleBufferQueue = false;
                    // creating an AudioPlayer which decodes AAC ADTS buffers to a PCM buffer queue
                    //  will cause usesAdvancedBufferHeaders and usesSimpleBufferQueue to be true
                    switch (thiz->mDataSource.mLocator.mLocatorType) {
                    case SL_DATALOCATOR_BUFFERQUEUE:
#ifdef ANDROID
                    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
#endif
                        usesSimpleBufferQueue = true;
                        nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mBufferQueue.numBuffers;
                        assert(SL_DATAFORMAT_PCM == thiz->mDataSource.mFormat.mFormatType);
                        thiz->mNumChannels = thiz->mDataSource.mFormat.mPCM.numChannels;
                        thiz->mSampleRateMilliHz = thiz->mDataSource.mFormat.mPCM.samplesPerSec;
                        break;
#ifdef ANDROID
                    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
                        usesAdvancedBufferHeaders = true;
                        nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mABQ.numBuffers;
                        thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers;
                        break;
#endif
                    default:
                        nbBuffers = 0;
                        break;
                    }
#ifdef ANDROID
                    switch(thiz->mDataSink.mLocator.mLocatorType) {
                    case SL_DATALOCATOR_BUFFERQUEUE:
                    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
                        usesSimpleBufferQueue = true;
                        nbBuffers = thiz->mDataSink.mLocator.mBufferQueue.numBuffers;
                        assert(SL_DATAFORMAT_PCM == thiz->mDataSink.mFormat.mFormatType);
                        // FIXME The values specified by the app are meaningless. We get the
                        // real values from the decoder.  But the data sink checks currently require
                        // that the app specify these useless values.  Needs doc/fix.
                        // Instead use the "unknown" values, as needed by prepare completion.
                        // thiz->mNumChannels = thiz->mDataSink.mFormat.mPCM.numChannels;
                        // thiz->mSampleRateMilliHz = thiz->mDataSink.mFormat.mPCM.samplesPerSec;
                        thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
                        thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
                        break;
                    default:
                        // leave nbBuffers unchanged
                        break;
                    }
#endif
                    thiz->mBufferQueue.mNumBuffers = nbBuffers;

                    // check the audio source and sink parameters against platform support
#ifdef ANDROID
                    result = android_audioPlayer_checkSourceSink(thiz);
                    if (SL_RESULT_SUCCESS != result) {
                        break;
                    }
#endif

#ifdef USE_SNDFILE
                    result = SndFile_checkAudioPlayerSourceSink(thiz);
                    if (SL_RESULT_SUCCESS != result) {
                        break;
                    }
#endif

#ifdef USE_OUTPUTMIXEXT
                    result = IOutputMixExt_checkAudioPlayerSourceSink(thiz);
                    if (SL_RESULT_SUCCESS != result) {
                        break;
                    }
#endif

                    // Allocate memory for buffer queue
                    if (usesAdvancedBufferHeaders) {
#ifdef ANDROID
                        // locator is SL_DATALOCATOR_ANDROIDBUFFERQUEUE
                        result = initializeAndroidBufferQueueMembers(thiz);
#else
                        assert(false);
#endif
                    }

                    if (usesSimpleBufferQueue) {
                        // locator is SL_DATALOCATOR_BUFFERQUEUE
                        //         or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
                        result = initializeBufferQueueMembers(thiz);
                    }

                    // used to store the data source of our audio player
                    thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource;

                    // platform-specific initialization
#ifdef ANDROID
                    android_audioPlayer_create(thiz);
#endif

                } while (0);

                if (SL_RESULT_SUCCESS != result) {
                    IObject_Destroy(&thiz->mObject.mItf);
                } else {
                    IObject_Publish(&thiz->mObject);
                    // return the new audio player object
                    *pPlayer = &thiz->mObject.mItf;
                }

            }
        }

    }

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_CreateAudioRecorder(SLEngineItf self, SLObjectItf *pRecorder,
    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

#if (USE_PROFILES & USE_PROFILES_OPTIONAL) || defined(ANDROID)
    if (NULL == pRecorder) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pRecorder = NULL;
        unsigned exposedMask;
        const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER);
        if (NULL == pCAudioRecorder_class) {
            result = SL_RESULT_FEATURE_UNSUPPORTED;
        } else {
            result = checkInterfaces(pCAudioRecorder_class, numInterfaces,
                    pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
        }

        if (SL_RESULT_SUCCESS == result) {

            // Construct our new AudioRecorder instance
            CAudioRecorder *thiz = (CAudioRecorder *) construct(pCAudioRecorder_class, exposedMask,
                    self);
            if (NULL == thiz) {
                result = SL_RESULT_MEMORY_FAILURE;
            } else {

                do {

                    // Initialize fields not associated with any interface

                    // Default data source in case of failure in checkDataSource
                    thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
                    thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL;

                    // Default data sink in case of failure in checkDataSink
                    thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
                    thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL;

                    // These fields are set to real values by
                    // android_audioRecorder_checkSourceSinkSupport.  Note that the data sink is
                    // always PCM buffer queue, so we know the channel count and sample rate early.
                    thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
                    thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
#ifdef ANDROID
                    thiz->mAudioRecord = NULL;
                    thiz->mRecordSource = AUDIO_SOURCE_DEFAULT;
#endif

                    // Check the source and sink parameters, and make a local copy of all parameters
                    result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
                            DATALOCATOR_MASK_IODEVICE, DATAFORMAT_MASK_NULL);
                    if (SL_RESULT_SUCCESS != result) {
                        break;
                    }
                    result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink,
                            DATALOCATOR_MASK_URI
#ifdef ANDROID
                            | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
#endif
                            , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM
                    );
                    if (SL_RESULT_SUCCESS != result) {
                        break;
                    }

                    // It would be unsafe to ever refer to the application pointers again
                    pAudioSrc = NULL;
                    pAudioSnk = NULL;

                    // check the audio source and sink parameters against platform support
#ifdef ANDROID
                    result = android_audioRecorder_checkSourceSinkSupport(thiz);
                    if (SL_RESULT_SUCCESS != result) {
                        SL_LOGE("Cannot create AudioRecorder: invalid source or sink");
                        break;
                    }
#endif

#ifdef ANDROID
                    // Allocate memory for buffer queue
                    SLuint32 locatorType = thiz->mDataSink.mLocator.mLocatorType;
                    if (locatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE) {
                        thiz->mBufferQueue.mNumBuffers =
                            thiz->mDataSink.mLocator.mBufferQueue.numBuffers;
                        // inline allocation of circular Buffer Queue mArray, up to a typical max
                        if (BUFFER_HEADER_TYPICAL >= thiz->mBufferQueue.mNumBuffers) {
                            thiz->mBufferQueue.mArray = thiz->mBufferQueue.mTypical;
                        } else {
                            // Avoid possible integer overflow during multiplication; this arbitrary
                            // maximum is big enough to not interfere with real applications, but
                            // small enough to not overflow.
                            if (thiz->mBufferQueue.mNumBuffers >= 256) {
                                result = SL_RESULT_MEMORY_FAILURE;
                                break;
                            }
                            thiz->mBufferQueue.mArray = (BufferHeader *) malloc((thiz->mBufferQueue.
                                    mNumBuffers + 1) * sizeof(BufferHeader));
                            if (NULL == thiz->mBufferQueue.mArray) {
                                result = SL_RESULT_MEMORY_FAILURE;
                                break;
                            }
                        }
                        thiz->mBufferQueue.mFront = thiz->mBufferQueue.mArray;
                        thiz->mBufferQueue.mRear = thiz->mBufferQueue.mArray;
                    }
#endif

                    // platform-specific initialization
#ifdef ANDROID
                    android_audioRecorder_create(thiz);
#endif

                } while (0);

                if (SL_RESULT_SUCCESS != result) {
                    IObject_Destroy(&thiz->mObject.mItf);
                } else {
                    IObject_Publish(&thiz->mObject);
                    // return the new audio recorder object
                    *pRecorder = &thiz->mObject.mItf;
                }
            }

        }

    }
#else
    result = SL_RESULT_FEATURE_UNSUPPORTED;
#endif

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
    SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
    SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE)
    if ((NULL == pPlayer) || (NULL == pMIDISrc) || (NULL == pAudioOutput)) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pPlayer = NULL;
        unsigned exposedMask;
        const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER);
        if (NULL == pCMidiPlayer_class) {
            result = SL_RESULT_FEATURE_UNSUPPORTED;
        } else {
            result = checkInterfaces(pCMidiPlayer_class, numInterfaces,
                pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
        }
        if (SL_RESULT_SUCCESS == result) {
            CMidiPlayer *thiz = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self);
            if (NULL == thiz) {
                result = SL_RESULT_MEMORY_FAILURE;
            } else {
#if 0
                "pMIDISrc", pMIDISrc, URI | MIDIBUFFERQUEUE, NONE
                "pBankSrc", pBanksrc, NULL | URI | ADDRESS, NULL
                "pAudioOutput", pAudioOutput, OUTPUTMIX, NULL
                "pVibra", pVibra, NULL | IODEVICE, NULL
                "pLEDArray", pLEDArray, NULL | IODEVICE, NULL
#endif
                // a fake value - why not use value from IPlay_init? what does CT check for?
                thiz->mPlay.mDuration = 0;
                IObject_Publish(&thiz->mObject);
                // return the new MIDI player object
                *pPlayer = &thiz->mObject.mItf;
            }
        }
    }
#else
    result = SL_RESULT_FEATURE_UNSUPPORTED;
#endif

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

#if USE_PROFILES & USE_PROFILES_GAME
    if (NULL == pListener) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pListener = NULL;
        unsigned exposedMask;
        const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER);
        if (NULL == pCListener_class) {
            result = SL_RESULT_FEATURE_UNSUPPORTED;
        } else {
            result = checkInterfaces(pCListener_class, numInterfaces,
                pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
        }
        if (SL_RESULT_SUCCESS == result) {
            CListener *thiz = (CListener *) construct(pCListener_class, exposedMask, self);
            if (NULL == thiz) {
                result = SL_RESULT_MEMORY_FAILURE;
            } else {
                IObject_Publish(&thiz->mObject);
                // return the new 3D listener object
                *pListener = &thiz->mObject.mItf;
            }
        }
    }
#else
    result = SL_RESULT_FEATURE_UNSUPPORTED;
#endif

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces,
    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

#if USE_PROFILES & USE_PROFILES_GAME
    if (NULL == pGroup) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pGroup = NULL;
        unsigned exposedMask;
        const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP);
        if (NULL == pC3DGroup_class) {
            result = SL_RESULT_FEATURE_UNSUPPORTED;
        } else {
            result = checkInterfaces(pC3DGroup_class, numInterfaces,
                pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
        }
        if (SL_RESULT_SUCCESS == result) {
            C3DGroup *thiz = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self);
            if (NULL == thiz) {
                result = SL_RESULT_MEMORY_FAILURE;
            } else {
                thiz->mMemberMask = 0;
                IObject_Publish(&thiz->mObject);
                // return the new 3D group object
                *pGroup = &thiz->mObject.mItf;
            }
        }
    }
#else
    result = SL_RESULT_FEATURE_UNSUPPORTED;
#endif

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces,
    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

    if (NULL == pMix) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pMix = NULL;
        unsigned exposedMask;
        const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX);
        assert(NULL != pCOutputMix_class);
        result = checkInterfaces(pCOutputMix_class, numInterfaces,
            pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
        if (SL_RESULT_SUCCESS == result) {
            COutputMix *thiz = (COutputMix *) construct(pCOutputMix_class, exposedMask, self);
            if (NULL == thiz) {
                result = SL_RESULT_MEMORY_FAILURE;
            } else {
#ifdef ANDROID
                android_outputMix_create(thiz);
#endif
#ifdef USE_SDL
                IEngine *thisEngine = &thiz->mObject.mEngine->mEngine;
                interface_lock_exclusive(thisEngine);
                bool unpause = false;
                if (NULL == thisEngine->mOutputMix) {
                    thisEngine->mOutputMix = thiz;
                    unpause = true;
                }
                interface_unlock_exclusive(thisEngine);
#endif
                IObject_Publish(&thiz->mObject);
#ifdef USE_SDL
                if (unpause) {
                    // Enable SDL_callback to be called periodically by SDL's internal thread
                    SDL_PauseAudio(0);
                }
#endif
                // return the new output mix object
                *pMix = &thiz->mObject.mItf;
            }
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor,
    SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
    const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC)
    if (NULL == pMetadataExtractor) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pMetadataExtractor = NULL;
        unsigned exposedMask;
        const ClassTable *pCMetadataExtractor_class =
            objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR);
        if (NULL == pCMetadataExtractor_class) {
            result = SL_RESULT_FEATURE_UNSUPPORTED;
        } else {
            result = checkInterfaces(pCMetadataExtractor_class, numInterfaces,
                pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
        }
        if (SL_RESULT_SUCCESS == result) {
            CMetadataExtractor *thiz = (CMetadataExtractor *)
                construct(pCMetadataExtractor_class, exposedMask, self);
            if (NULL == thiz) {
                result = SL_RESULT_MEMORY_FAILURE;
            } else {
#if 0
                "pDataSource", pDataSource, NONE, NONE
#endif
                IObject_Publish(&thiz->mObject);
                // return the new metadata extractor object
                *pMetadataExtractor = &thiz->mObject.mItf;
                result = SL_RESULT_SUCCESS;
            }
        }
    }
#else
    result = SL_RESULT_FEATURE_UNSUPPORTED;
#endif

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject,
    void *pParameters, SLuint32 objectID, SLuint32 numInterfaces,
    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
    SL_ENTER_INTERFACE

    if (NULL == pObject) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pObject = NULL;
        result = SL_RESULT_FEATURE_UNSUPPORTED;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self,
    SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
{
    SL_ENTER_INTERFACE

    if (NULL == pNumSupportedInterfaces) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        const ClassTable *clazz = objectIDtoClass(objectID);
        if (NULL == clazz) {
            result = SL_RESULT_FEATURE_UNSUPPORTED;
        } else {
            SLuint32 count = 0;
            SLuint32 i;
            for (i = 0; i < clazz->mInterfaceCount; ++i) {
                switch (clazz->mInterfaces[i].mInterface) {
                case INTERFACE_IMPLICIT:
                case INTERFACE_IMPLICIT_PREREALIZE:
                case INTERFACE_EXPLICIT:
                case INTERFACE_EXPLICIT_PREREALIZE:
                case INTERFACE_DYNAMIC:
                    ++count;
                    break;
                case INTERFACE_UNAVAILABLE:
                    break;
                default:
                    assert(false);
                    break;
                }
            }
            *pNumSupportedInterfaces = count;
            result = SL_RESULT_SUCCESS;
        }
    }

    SL_LEAVE_INTERFACE;
}


static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self,
    SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
{
    SL_ENTER_INTERFACE

    if (NULL == pInterfaceId) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pInterfaceId = NULL;
        const ClassTable *clazz = objectIDtoClass(objectID);
        if (NULL == clazz) {
            result = SL_RESULT_FEATURE_UNSUPPORTED;
        } else {
            result = SL_RESULT_PARAMETER_INVALID; // will be reset later
            SLuint32 i;
            for (i = 0; i < clazz->mInterfaceCount; ++i) {
                switch (clazz->mInterfaces[i].mInterface) {
                case INTERFACE_IMPLICIT:
                case INTERFACE_IMPLICIT_PREREALIZE:
                case INTERFACE_EXPLICIT:
                case INTERFACE_EXPLICIT_PREREALIZE:
                case INTERFACE_DYNAMIC:
                    break;
                case INTERFACE_UNAVAILABLE:
                    continue;
                default:
                    assert(false);
                    break;
                }
                if (index == 0) {
                    *pInterfaceId = &SL_IID_array[clazz->mInterfaces[i].mMPH];
                    result = SL_RESULT_SUCCESS;
                    break;
                }
                --index;
            }
        }
    }

    SL_LEAVE_INTERFACE
};


static const char * const extensionNames[] = {
#ifdef ANDROID
#define _(n) #n
#define __(n) _(n)
    "ANDROID_SDK_LEVEL_" __(PLATFORM_SDK_VERSION),
#undef _
#undef __
#else
    "WILHELM_DESKTOP",
#endif
};


static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions)
{
    SL_ENTER_INTERFACE

    if (NULL == pNumExtensions) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        *pNumExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_QuerySupportedExtension(SLEngineItf self,
    SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
{
    SL_ENTER_INTERFACE

    if (NULL == pNameLength) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        size_t actualNameLength;
        unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
        if (index >= numExtensions) {
            actualNameLength = 0;
            result = SL_RESULT_PARAMETER_INVALID;
        } else {
            const char *extensionName = extensionNames[index];
            actualNameLength = strlen(extensionName) + 1;
            if (NULL == pExtensionName) {
                // application is querying the name length in order to allocate a buffer
                result = SL_RESULT_SUCCESS;
            } else {
                SLint16 availableNameLength = *pNameLength;
                if (0 >= availableNameLength) {
                    // there is not even room for the terminating NUL
                    result = SL_RESULT_BUFFER_INSUFFICIENT;
                } else if (actualNameLength > (size_t) availableNameLength) {
                    // "no invalid strings are written. That is, the null-terminator always exists"
                    memcpy(pExtensionName, extensionName, (size_t) availableNameLength - 1);
                    pExtensionName[(size_t) availableNameLength - 1] = '\0';
                    result = SL_RESULT_BUFFER_INSUFFICIENT;
                } else {
                    memcpy(pExtensionName, extensionName, actualNameLength);
                    result = SL_RESULT_SUCCESS;
                }
            }
        }
        *pNameLength = actualNameLength;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEngine_IsExtensionSupported(SLEngineItf self,
    const SLchar *pExtensionName, SLboolean *pSupported)
{
    SL_ENTER_INTERFACE

    if (NULL == pSupported) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        SLboolean isSupported = SL_BOOLEAN_FALSE;
        if (NULL == pExtensionName) {
            result = SL_RESULT_PARAMETER_INVALID;
        } else {
            unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
            unsigned i;
            for (i = 0; i < numExtensions; ++i) {
                if (!strcmp((const char *) pExtensionName, extensionNames[i])) {
                    isSupported = SL_BOOLEAN_TRUE;
                    break;
                }
            }
            result = SL_RESULT_SUCCESS;
        }
        *pSupported = isSupported;
    }

    SL_LEAVE_INTERFACE
}


static const struct SLEngineItf_ IEngine_Itf = {
    IEngine_CreateLEDDevice,
    IEngine_CreateVibraDevice,
    IEngine_CreateAudioPlayer,
    IEngine_CreateAudioRecorder,
    IEngine_CreateMidiPlayer,
    IEngine_CreateListener,
    IEngine_Create3DGroup,
    IEngine_CreateOutputMix,
    IEngine_CreateMetadataExtractor,
    IEngine_CreateExtensionObject,
    IEngine_QueryNumSupportedInterfaces,
    IEngine_QuerySupportedInterfaces,
    IEngine_QueryNumSupportedExtensions,
    IEngine_QuerySupportedExtension,
    IEngine_IsExtensionSupported
};

void IEngine_init(void *self)
{
    IEngine *thiz = (IEngine *) self;
    thiz->mItf = &IEngine_Itf;
    // mLossOfControlGlobal is initialized in slCreateEngine
#ifdef USE_SDL
    thiz->mOutputMix = NULL;
#endif
    thiz->mInstanceCount = 1; // ourself
    thiz->mInstanceMask = 0;
    thiz->mChangedMask = 0;
    unsigned i;
    for (i = 0; i < MAX_INSTANCE; ++i) {
        thiz->mInstances[i] = NULL;
    }
    thiz->mShutdown = SL_BOOLEAN_FALSE;
    thiz->mShutdownAck = SL_BOOLEAN_FALSE;
}

void IEngine_deinit(void *self)
{
}


// OpenMAX AL Engine


static XAresult IEngine_CreateCameraDevice(XAEngineItf self, XAObjectItf *pDevice,
        XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
        const XAboolean *pInterfaceRequired)
{
    XA_ENTER_INTERFACE

    //IXAEngine *thiz = (IXAEngine *) self;
    result = SL_RESULT_FEATURE_UNSUPPORTED;

    XA_LEAVE_INTERFACE
}


static XAresult IEngine_CreateRadioDevice(XAEngineItf self, XAObjectItf *pDevice,
        XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
        const XAboolean *pInterfaceRequired)
{
    XA_ENTER_INTERFACE

    //IXAEngine *thiz = (IXAEngine *) self;
    result = SL_RESULT_FEATURE_UNSUPPORTED;

    XA_LEAVE_INTERFACE
}


static XAresult IXAEngine_CreateLEDDevice(XAEngineItf self, XAObjectItf *pDevice, XAuint32 deviceID,
        XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
        const XAboolean *pInterfaceRequired)
{
    // forward to OpenSL ES
    return IEngine_CreateLEDDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
            (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
            (const SLboolean *) pInterfaceRequired);
}


static XAresult IXAEngine_CreateVibraDevice(XAEngineItf self, XAObjectItf *pDevice,
        XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
        const XAboolean *pInterfaceRequired)
{
    // forward to OpenSL ES
    return IEngine_CreateVibraDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
            (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
            (const SLboolean *) pInterfaceRequired);
}


static XAresult IEngine_CreateMediaPlayer(XAEngineItf self, XAObjectItf *pPlayer,
        XADataSource *pDataSrc, XADataSource *pBankSrc, XADataSink *pAudioSnk,
        XADataSink *pImageVideoSnk, XADataSink *pVibra, XADataSink *pLEDArray,
        XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
        const XAboolean *pInterfaceRequired)
{
    XA_ENTER_INTERFACE

    if (NULL == pPlayer) {
        result = XA_RESULT_PARAMETER_INVALID;
    } else {
        *pPlayer = NULL;
        unsigned exposedMask;
        const ClassTable *pCMediaPlayer_class = objectIDtoClass(XA_OBJECTID_MEDIAPLAYER);
        assert(NULL != pCMediaPlayer_class);
        result = checkInterfaces(pCMediaPlayer_class, numInterfaces,
                (const SLInterfaceID *) pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
        if (XA_RESULT_SUCCESS == result) {

            // Construct our new MediaPlayer instance
            CMediaPlayer *thiz = (CMediaPlayer *) construct(pCMediaPlayer_class, exposedMask,
                    &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf);
            if (NULL == thiz) {
                result = XA_RESULT_MEMORY_FAILURE;
            } else {

                do {

                    // Initialize private fields not associated with an interface

                    // Default data source in case of failure in checkDataSource
                    thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
                    thiz->mDataSource.mFormat.mFormatType = XA_DATAFORMAT_NULL;

                    // Default andio and image sink in case of failure in checkDataSink
                    thiz->mAudioSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
                    thiz->mAudioSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;
                    thiz->mImageVideoSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
                    thiz->mImageVideoSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;

                    // More default values, in case destructor needs to be called early
                    thiz->mNumChannels = UNKNOWN_NUMCHANNELS;

#ifdef ANDROID
                    // placement new (explicit constructor)
                    // FIXME unnecessary once those fields are encapsulated in one class, rather
                    //   than a structure
                    (void) new (&thiz->mAVPlayer) android::sp<android::GenericPlayer>();
                    (void) new (&thiz->mCallbackProtector)
                            android::sp<android::CallbackProtector>();
                    // Android-specific POD fields are initialized in android_Player_create,
                    // and assume calloc or memset 0 during allocation
#endif

                    // Check the source and sink parameters against generic constraints

                    result = checkDataSource("pDataSrc", (const SLDataSource *) pDataSrc,
                            &thiz->mDataSource, DATALOCATOR_MASK_URI
#ifdef ANDROID
                            | DATALOCATOR_MASK_ANDROIDFD
                            | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
#endif
                            , DATAFORMAT_MASK_MIME);
                    if (XA_RESULT_SUCCESS != result) {
                        break;
                    }

                    result = checkDataSource("pBankSrc", (const SLDataSource *) pBankSrc,
                            &thiz->mBankSource, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_URI |
                            DATALOCATOR_MASK_ADDRESS, DATAFORMAT_MASK_NULL);
                    if (XA_RESULT_SUCCESS != result) {
                        break;
                    }

                    result = checkDataSink("pAudioSnk", (const SLDataSink *) pAudioSnk,
                            &thiz->mAudioSink, DATALOCATOR_MASK_OUTPUTMIX, DATAFORMAT_MASK_NULL);
                    if (XA_RESULT_SUCCESS != result) {
                        break;
                    }

                    result = checkDataSink("pImageVideoSnk", (const SLDataSink *) pImageVideoSnk,
                            &thiz->mImageVideoSink,
                            DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_NATIVEDISPLAY,
                            DATAFORMAT_MASK_NULL);
                    if (XA_RESULT_SUCCESS != result) {
                        break;
                    }

                    result = checkDataSink("pVibra", (const SLDataSink *) pVibra, &thiz->mVibraSink,
                            DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
                            DATAFORMAT_MASK_NULL);
                    if (XA_RESULT_SUCCESS != result) {
                        break;
                    }

                    result = checkDataSink("pLEDArray", (const SLDataSink *) pLEDArray,
                            &thiz->mLEDArraySink, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
                            DATAFORMAT_MASK_NULL);
                    if (XA_RESULT_SUCCESS != result) {
                        break;
                    }

                    // Unsafe to ever refer to application pointers again
                    pDataSrc = NULL;
                    pBankSrc = NULL;
                    pAudioSnk = NULL;
                    pImageVideoSnk = NULL;
                    pVibra = NULL;
                    pLEDArray = NULL;

                    // Check that the requested interfaces are compatible with the data source
                    // FIXME implement

                    // check the source and sink parameters against platform support
#ifdef ANDROID
                    result = android_Player_checkSourceSink(thiz);
                    if (XA_RESULT_SUCCESS != result) {
                        break;
                    }
#endif

#ifdef ANDROID
                    // AndroidBufferQueue-specific initialization
                    if (XA_DATALOCATOR_ANDROIDBUFFERQUEUE ==
                            thiz->mDataSource.mLocator.mLocatorType) {
                        XAuint16 nbBuffers = (XAuint16) thiz->mDataSource.mLocator.mABQ.numBuffers;

                        // Avoid possible integer overflow during multiplication; this arbitrary
                        // maximum is big enough to not interfere with real applications, but
                        // small enough to not overflow.
                        if (nbBuffers >= 256) {
                            result = SL_RESULT_MEMORY_FAILURE;
                            break;
                        }

                        // initialize ABQ buffer type
                        // assert below has been checked in android_audioPlayer_checkSourceSink
                        assert(XA_DATAFORMAT_MIME == thiz->mDataSource.mFormat.mFormatType);
                        if (XA_CONTAINERTYPE_MPEG_TS ==
                                thiz->mDataSource.mFormat.mMIME.containerType) {
                            thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;

                            // Set the container type for the StreamInformation interface
                            XAMediaContainerInformation *containerInfo =
                                    (XAMediaContainerInformation*)
                                        // always storing container info at index 0, as per spec
                                        &(thiz->mStreamInfo.mStreamInfoTable.itemAt(0).
                                                containerInfo);
                            containerInfo->containerType = XA_CONTAINERTYPE_MPEG_TS;
                            // there are no streams at this stage
                            containerInfo->numStreams = 0;

                        } else {
                            thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
                            SL_LOGE("Invalid buffer type in Android Buffer Queue");
                            result = SL_RESULT_CONTENT_UNSUPPORTED;
                        }

                        // initialize ABQ memory
                        thiz->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *)
                                    malloc( (nbBuffers + 1) * sizeof(AdvancedBufferHeader));
                        if (NULL == thiz->mAndroidBufferQueue.mBufferArray) {
                            result = SL_RESULT_MEMORY_FAILURE;
                            break;
                        } else {
                            thiz->mAndroidBufferQueue.mFront =
                                    thiz->mAndroidBufferQueue.mBufferArray;
                            thiz->mAndroidBufferQueue.mRear =
                                    thiz->mAndroidBufferQueue.mBufferArray;
                        }

                        thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers;

                    }
#endif

                    // used to store the data source of our audio player
                    thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource;

                    // platform-specific initialization
#ifdef ANDROID
                    android_Player_create(thiz);
#endif

                } while (0);

                if (XA_RESULT_SUCCESS != result) {
                    IObject_Destroy(&thiz->mObject.mItf);
                } else {
                    IObject_Publish(&thiz->mObject);
                    // return the new media player object
                    *pPlayer = (XAObjectItf) &thiz->mObject.mItf;
                }

            }
        }

    }

    XA_LEAVE_INTERFACE
}


static XAresult IEngine_CreateMediaRecorder(XAEngineItf self, XAObjectItf *pRecorder,
        XADataSource *pAudioSrc, XADataSource *pImageVideoSrc,
        XADataSink *pDataSnk, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
        const XAboolean *pInterfaceRequired)
{
    XA_ENTER_INTERFACE

    //IXAEngine *thiz = (IXAEngine *) self;
    result = SL_RESULT_FEATURE_UNSUPPORTED;

#if 0
    "pAudioSrc", pAudioSrc,
    "pImageVideoSrc", pImageVideoSrc,
    "pDataSink", pDataSnk,
#endif

    XA_LEAVE_INTERFACE
}


static XAresult IXAEngine_CreateOutputMix(XAEngineItf self, XAObjectItf *pMix,
        XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
        const XAboolean *pInterfaceRequired)
{
    // forward to OpenSL ES
    return IEngine_CreateOutputMix(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
            (SLObjectItf *) pMix, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
            (const SLboolean *) pInterfaceRequired);
}


static XAresult IXAEngine_CreateMetadataExtractor(XAEngineItf self, XAObjectItf *pMetadataExtractor,
            XADataSource *pDataSource, XAuint32 numInterfaces,
            const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
{
    // forward to OpenSL ES
    return IEngine_CreateMetadataExtractor(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
            (SLObjectItf *) pMetadataExtractor, (SLDataSource *) pDataSource, numInterfaces,
            (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
}


static XAresult IXAEngine_CreateExtensionObject(XAEngineItf self, XAObjectItf *pObject,
            void *pParameters, XAuint32 objectID, XAuint32 numInterfaces,
            const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
{
    // forward to OpenSL ES
    return IEngine_CreateExtensionObject(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
            (SLObjectItf *) pObject, pParameters, objectID, numInterfaces,
            (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
}


static XAresult IEngine_GetImplementationInfo(XAEngineItf self, XAuint32 *pMajor, XAuint32 *pMinor,
        XAuint32 *pStep, /* XAuint32 nImplementationTextSize, */ const XAchar *pImplementationText)
{
    XA_ENTER_INTERFACE

    //IXAEngine *thiz = (IXAEngine *) self;
    result = SL_RESULT_FEATURE_UNSUPPORTED;

    XA_LEAVE_INTERFACE
}


static XAresult IXAEngine_QuerySupportedProfiles(XAEngineItf self, XAint16 *pProfilesSupported)
{
    XA_ENTER_INTERFACE

    if (NULL == pProfilesSupported) {
        result = XA_RESULT_PARAMETER_INVALID;
    } else {
#if 1
        *pProfilesSupported = 0;
        // the code below was copied from OpenSL ES and needs to be adapted for OpenMAX AL.
#else
        // The generic implementation doesn't implement any of the profiles, they shouldn't be
        // declared as supported. Also exclude the fake profiles BASE and OPTIONAL.
        *pProfilesSupported = USE_PROFILES &
                (USE_PROFILES_GAME | USE_PROFILES_MUSIC | USE_PROFILES_PHONE);
#endif
        result = XA_RESULT_SUCCESS;
    }

    XA_LEAVE_INTERFACE
}


static XAresult IXAEngine_QueryNumSupportedInterfaces(XAEngineItf self, XAuint32 objectID,
        XAuint32 *pNumSupportedInterfaces)
{
    // forward to OpenSL ES
    return IEngine_QueryNumSupportedInterfaces(
            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID,
            pNumSupportedInterfaces);
}


static XAresult IXAEngine_QuerySupportedInterfaces(XAEngineItf self, XAuint32 objectID,
        XAuint32 index, XAInterfaceID *pInterfaceId)
{
    // forward to OpenSL ES
    return IEngine_QuerySupportedInterfaces(
            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID, index,
            (SLInterfaceID *) pInterfaceId);
}


static XAresult IXAEngine_QueryNumSupportedExtensions(XAEngineItf self, XAuint32 *pNumExtensions)
{
    // forward to OpenSL ES
    return IEngine_QueryNumSupportedExtensions(
            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, pNumExtensions);
}


static XAresult IXAEngine_QuerySupportedExtension(XAEngineItf self, XAuint32 index,
        XAchar *pExtensionName, XAint16 *pNameLength)
{
    // forward to OpenSL ES
    return IEngine_QuerySupportedExtension(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
            index, pExtensionName, (SLint16 *) pNameLength);
}


static XAresult IXAEngine_IsExtensionSupported(XAEngineItf self, const XAchar *pExtensionName,
        XAboolean *pSupported)
{
    // forward to OpenSL ES
    return IEngine_IsExtensionSupported(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
            pExtensionName, pSupported);
}


static XAresult IXAEngine_QueryLEDCapabilities(XAEngineItf self, XAuint32 *pIndex,
        XAuint32 *pLEDDeviceID, XALEDDescriptor *pDescriptor)
{
    // forward to OpenSL ES EngineCapabilities
    return (XAresult) IEngineCapabilities_QueryLEDCapabilities(
            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
            pLEDDeviceID, (SLLEDDescriptor *) pDescriptor);
}


static XAresult IXAEngine_QueryVibraCapabilities(XAEngineItf self, XAuint32 *pIndex,
        XAuint32 *pVibraDeviceID, XAVibraDescriptor *pDescriptor)
{
    // forward to OpenSL ES EngineCapabilities
    return (XAresult) IEngineCapabilities_QueryVibraCapabilities(
            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
            pVibraDeviceID, (SLVibraDescriptor *) pDescriptor);
}


// OpenMAX AL engine v-table

static const struct XAEngineItf_ IXAEngine_Itf = {
    IEngine_CreateCameraDevice,
    IEngine_CreateRadioDevice,
    IXAEngine_CreateLEDDevice,
    IXAEngine_CreateVibraDevice,
    IEngine_CreateMediaPlayer,
    IEngine_CreateMediaRecorder,
    IXAEngine_CreateOutputMix,
    IXAEngine_CreateMetadataExtractor,
    IXAEngine_CreateExtensionObject,
    IEngine_GetImplementationInfo,
    IXAEngine_QuerySupportedProfiles,
    IXAEngine_QueryNumSupportedInterfaces,
    IXAEngine_QuerySupportedInterfaces,
    IXAEngine_QueryNumSupportedExtensions,
    IXAEngine_QuerySupportedExtension,
    IXAEngine_IsExtensionSupported,
    IXAEngine_QueryLEDCapabilities,
    IXAEngine_QueryVibraCapabilities
};


void IXAEngine_init(void *self)
{
    IXAEngine *thiz = (IXAEngine *) self;
    thiz->mItf = &IXAEngine_Itf;
}


void IXAEngine_deinit(void *self)
{
}
