IEngine.c revision 2bb3547351a40ad394b09babec4d2fcc233bfe2e
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* Engine implementation */
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "sles_allinclusive.h"
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* Utility functions */
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult initializeBufferQueueMembers(CAudioPlayer *ap) {
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // inline allocation of circular mArray, up to a typical max
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (BUFFER_HEADER_TYPICAL >= ap->mBufferQueue.mNumBuffers) {
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ap->mBufferQueue.mArray = ap->mBufferQueue.mTypical;
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Avoid possible integer overflow during multiplication; this arbitrary
301173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        // maximum is big enough to not interfere with real applications, but
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // small enough to not overflow.
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (ap->mBufferQueue.mNumBuffers >= 256) {
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return SL_RESULT_MEMORY_FAILURE;
341173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        }
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ap->mBufferQueue.mArray = (BufferHeader *)
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                malloc((ap->mBufferQueue.mNumBuffers + 1) * sizeof(BufferHeader));
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == ap->mBufferQueue.mArray) {
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return SL_RESULT_MEMORY_FAILURE;
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ap->mBufferQueue.mFront = ap->mBufferQueue.mArray;
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ap->mBufferQueue.mRear = ap->mBufferQueue.mArray;
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return SL_RESULT_SUCCESS;
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult initializeAndroidBufferQueueMembers(CAudioPlayer *ap) {
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Avoid possible integer overflow during multiplication; this arbitrary
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // maximum is big enough to not interfere with real applications, but
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // small enough to not overflow.
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (ap->mAndroidBufferQueue.mNumBuffers >= 256) {
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return SL_RESULT_MEMORY_FAILURE;
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ap->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *)
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            malloc( (ap->mAndroidBufferQueue.mNumBuffers + 1) * sizeof(AdvancedBufferHeader));
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == ap->mAndroidBufferQueue.mBufferArray) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return SL_RESULT_MEMORY_FAILURE;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // initialize ABQ buffer type
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // assert below has been checked in android_audioPlayer_checkSourceSink
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        assert(SL_DATAFORMAT_MIME == ap->mDataSource.mFormat.mFormatType);
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch(ap->mDataSource.mFormat.mMIME.containerType) {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          case SL_CONTAINERTYPE_MPEG_TS:
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          case SL_CONTAINERTYPE_AAC:
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          case SL_CONTAINERTYPE_RAW: {
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            const char* mime = (char*)ap->mDataSource.mFormat.mMIME.mimeType;
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if ((mime != NULL) && !(strcasecmp(mime, ANDROID_MIME_AACADTS) &&
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    strcasecmp(mime, ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK))) {
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeAacadts;
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                SL_LOGE("CreateAudioPlayer: Invalid buffer type in Android Buffer Queue");
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return SL_RESULT_CONTENT_UNSUPPORTED;
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          } break;
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          default:
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            SL_LOGE("CreateAudioPlayer: Invalid buffer type in Android Buffer Queue");
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return SL_RESULT_CONTENT_UNSUPPORTED;
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // initialize ABQ memory
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        for (SLuint16 i=0 ; i<(ap->mAndroidBufferQueue.mNumBuffers + 1) ; i++) {
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            AdvancedBufferHeader *pBuf = &ap->mAndroidBufferQueue.mBufferArray[i];
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pBuf->mDataBuffer = NULL;
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pBuf->mDataSize = 0;
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pBuf->mDataSizeConsumed = 0;
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pBuf->mBufferContext = NULL;
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pBuf->mBufferState = SL_ANDROIDBUFFERQUEUEEVENT_NONE;
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            switch (ap->mAndroidBufferQueue.mBufferType) {
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              case kAndroidBufferTypeMpeg2Ts:
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                pBuf->mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                pBuf->mItems.mTsCmdData.mPts = 0;
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              case kAndroidBufferTypeAacadts:
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                pBuf->mItems.mTsCmdData.mTsCmdCode = ANDROID_ADTSEVENT_NONE;
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              default:
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return SL_RESULT_CONTENT_UNSUPPORTED;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ap->mAndroidBufferQueue.mFront = ap->mAndroidBufferQueue.mBufferArray;
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ap->mAndroidBufferQueue.mRear  = ap->mAndroidBufferQueue.mBufferArray;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return SL_RESULT_SUCCESS;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if USE_PROFILES & USE_PROFILES_OPTIONAL
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_LED != deviceID)) {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pDevice = NULL;
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned exposedMask;
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == pCLEDDevice_class) {
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_FEATURE_UNSUPPORTED;
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = checkInterfaces(pCLEDDevice_class, numInterfaces, pInterfaceIds,
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                pInterfaceRequired, &exposedMask);
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (SL_RESULT_SUCCESS == result) {
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CLEDDevice *thiz = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self);
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (NULL == thiz) {
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_MEMORY_FAILURE;
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                thiz->mDeviceID = deviceID;
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IObject_Publish(&thiz->mObject);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // return the new LED object
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *pDevice = &thiz->mObject.mItf;
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if USE_PROFILES & USE_PROFILES_OPTIONAL
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_VIBRA != deviceID)) {
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pDevice = NULL;
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned exposedMask;
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE);
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == pCVibraDevice_class) {
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_FEATURE_UNSUPPORTED;
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = checkInterfaces(pCVibraDevice_class, numInterfaces,
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                pInterfaceIds, pInterfaceRequired, &exposedMask);
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (SL_RESULT_SUCCESS == result) {
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CVibraDevice *thiz = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self);
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (NULL == thiz) {
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_MEMORY_FAILURE;
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                thiz->mDeviceID = deviceID;
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IObject_Publish(&thiz->mObject);
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // return the new vibra object
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *pDevice = &thiz->mObject.mItf;
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pPlayer) {
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber       result = SL_RESULT_PARAMETER_INVALID;
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pPlayer = NULL;
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned exposedMask;
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER);
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        assert(NULL != pCAudioPlayer_class);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = checkInterfaces(pCAudioPlayer_class, numInterfaces,
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pInterfaceIds, pInterfaceRequired, &exposedMask);
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (SL_RESULT_SUCCESS == result) {
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Construct our new AudioPlayer instance
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CAudioPlayer *thiz = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self);
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (NULL == thiz) {
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_MEMORY_FAILURE;
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                do {
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Initialize private fields not associated with an interface
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Default data source in case of failure in checkDataSource
218349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
219349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL;
220349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Default data sink in case of failure in checkDataSink
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL;
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Default is no per-channel mute or solo
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mMuteMask = 0;
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mSoloMask = 0;
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
229349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    // Will be set soon for PCM buffer queues, or later by platform-specific code
230349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    // during Realize or Prefetch
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // More default values, in case destructor needs to be called early
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mDirectLevel = 0;
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef USE_OUTPUTMIXEXT
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mTrack = NULL;
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mGains[0] = 1.0f;
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mGains[1] = 1.0f;
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mDestroyRequested = SL_BOOLEAN_FALSE;
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef USE_SNDFILE
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mSndFile.mPathname = NULL;
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mSndFile.mSNDFILE = NULL;
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memset(&thiz->mSndFile.mSfInfo, 0, sizeof(SF_INFO));
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memset(&thiz->mSndFile.mMutex, 0, sizeof(pthread_mutex_t));
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mSndFile.mEOF = SL_BOOLEAN_FALSE;
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mSndFile.mWhich = 0;
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memset(thiz->mSndFile.mBuffer, 0, sizeof(thiz->mSndFile.mBuffer));
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // extra safe initializations of pointers, in case of incomplete construction
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mpLock = NULL;
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // placement new (explicit constructor)
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // FIXME unnecessary once those fields are encapsulated in one class, rather
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    //   than a structure
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (void) new (&thiz->mAudioTrack) android::sp<android::AudioTrackProxy>();
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (void) new (&thiz->mCallbackProtector)
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            android::sp<android::CallbackProtector>();
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (void) new (&thiz->mAuxEffect) android::sp<android::AudioEffect>();
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (void) new (&thiz->mAPlayer) android::sp<android::GenericPlayer>();
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Check the source and sink parameters against generic constraints,
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // and make a local copy of all parameters in case other application threads
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // change memory concurrently.
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            DATALOCATOR_MASK_URI | DATALOCATOR_MASK_ADDRESS |
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            DATALOCATOR_MASK_BUFFERQUEUE
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            | DATALOCATOR_MASK_ANDROIDFD | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (SL_RESULT_SUCCESS != result) {
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink,
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            DATALOCATOR_MASK_OUTPUTMIX                  // for playback
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE // for decode to a BQ
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            | DATALOCATOR_MASK_BUFFERQUEUE              // for decode to a BQ
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            , DATAFORMAT_MASK_NULL
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            | DATAFORMAT_MASK_PCM                       // for decode to PCM
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            );
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (SL_RESULT_SUCCESS != result) {
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // It would be unsafe to ever refer to the application pointers again
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pAudioSrc = NULL;
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pAudioSnk = NULL;
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Check that the requested interfaces are compatible with data source and sink
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = checkSourceSinkVsInterfacesCompatibility(&thiz->mDataSource,
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            &thiz->mDataSink, pCAudioPlayer_class, exposedMask);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (SL_RESULT_SUCCESS != result) {
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // copy the buffer queue count from source locator (for playback) / from the
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // sink locator (for decode on ANDROID build) to the buffer queue interface
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // we have already range-checked the value down to a smaller width
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    SLuint16 nbBuffers = 0;
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bool usesAdvancedBufferHeaders = false;
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bool usesSimpleBufferQueue = false;
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // creating an AudioPlayer which decodes AAC ADTS buffers to a PCM buffer queue
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    //  will cause usesAdvancedBufferHeaders and usesSimpleBufferQueue to be true
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    switch (thiz->mDataSource.mLocator.mLocatorType) {
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    case SL_DATALOCATOR_BUFFERQUEUE:
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        usesSimpleBufferQueue = true;
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mBufferQueue.numBuffers;
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        assert(SL_DATAFORMAT_PCM == thiz->mDataSource.mFormat.mFormatType);
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        thiz->mNumChannels = thiz->mDataSource.mFormat.mPCM.numChannels;
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        thiz->mSampleRateMilliHz = thiz->mDataSource.mFormat.mPCM.samplesPerSec;
32531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        break;
32631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber#ifdef ANDROID
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        usesAdvancedBufferHeaders = true;
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mABQ.numBuffers;
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers;
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    default:
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        nbBuffers = 0;
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    switch(thiz->mDataSink.mLocator.mLocatorType) {
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    case SL_DATALOCATOR_BUFFERQUEUE:
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        usesSimpleBufferQueue = true;
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        nbBuffers = thiz->mDataSink.mLocator.mBufferQueue.numBuffers;
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        assert(SL_DATAFORMAT_PCM == thiz->mDataSink.mFormat.mFormatType);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // FIXME The values specified by the app are meaningless. We get the
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // real values from the decoder.  But the data sink checks currently require
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // that the app specify these useless values.  Needs doc/fix.
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // Instead use the "unknown" values, as needed by prepare completion.
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // thiz->mNumChannels = thiz->mDataSink.mFormat.mPCM.numChannels;
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // thiz->mSampleRateMilliHz = thiz->mDataSink.mFormat.mPCM.samplesPerSec;
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    default:
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // leave nbBuffers unchanged
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mBufferQueue.mNumBuffers = nbBuffers;
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // check the audio source and sink parameters against platform support
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = android_audioPlayer_checkSourceSink(thiz);
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (SL_RESULT_SUCCESS != result) {
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef USE_SNDFILE
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = SndFile_checkAudioPlayerSourceSink(thiz);
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (SL_RESULT_SUCCESS != result) {
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef USE_OUTPUTMIXEXT
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = IOutputMixExt_checkAudioPlayerSourceSink(thiz);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (SL_RESULT_SUCCESS != result) {
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Allocate memory for buffer queue
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (usesAdvancedBufferHeaders) {
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // locator is SL_DATALOCATOR_ANDROIDBUFFERQUEUE
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        result = initializeAndroidBufferQueueMembers(thiz);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        assert(false);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (usesSimpleBufferQueue) {
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // locator is SL_DATALOCATOR_BUFFERQUEUE
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        //         or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        result = initializeBufferQueueMembers(thiz);
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // used to store the data source of our audio player
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource;
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // platform-specific initialization
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    android_audioPlayer_create(thiz);
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } while (0);
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (SL_RESULT_SUCCESS != result) {
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    IObject_Destroy(&thiz->mObject.mItf);
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    IObject_Publish(&thiz->mObject);
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // return the new audio player object
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    *pPlayer = &thiz->mObject.mItf;
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_CreateAudioRecorder(SLEngineItf self, SLObjectItf *pRecorder,
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if (USE_PROFILES & USE_PROFILES_OPTIONAL) || defined(ANDROID)
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pRecorder) {
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pRecorder = NULL;
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned exposedMask;
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == pCAudioRecorder_class) {
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_FEATURE_UNSUPPORTED;
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = checkInterfaces(pCAudioRecorder_class, numInterfaces,
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pInterfaceIds, pInterfaceRequired, &exposedMask);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (SL_RESULT_SUCCESS == result) {
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Construct our new AudioRecorder instance
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CAudioRecorder *thiz = (CAudioRecorder *) construct(pCAudioRecorder_class, exposedMask,
4493c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis                    self);
4503c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            if (NULL == thiz) {
4513c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis                result = SL_RESULT_MEMORY_FAILURE;
4523c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            } else {
4533c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
4543c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis                do {
4553c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
4563c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis                    // Initialize fields not associated with any interface
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Default data source in case of failure in checkDataSource
4593c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis                    thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL;
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Default data sink in case of failure in checkDataSink
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL;
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
466258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    // These fields are set to real values by
467258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    // android_audioRecorder_checkSourceSinkSupport.  Note that the data sink is
468258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    // always PCM buffer queue, so we know the channel count and sample rate early.
469258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
470258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
471258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis#ifdef ANDROID
472258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    thiz->mAudioRecord = NULL;
473258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    thiz->mRecordSource = AUDIO_SOURCE_DEFAULT;
474258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis#endif
475258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
476258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    // Check the source and sink parameters, and make a local copy of all parameters
477258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
478258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                            DATALOCATOR_MASK_IODEVICE, DATAFORMAT_MASK_NULL);
479258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    if (SL_RESULT_SUCCESS != result) {
480258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                        break;
481258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    }
482258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink,
483258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                            DATALOCATOR_MASK_URI
484258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis#ifdef ANDROID
485258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                            | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
486258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis#endif
487258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                            , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM
488258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    );
489258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    if (SL_RESULT_SUCCESS != result) {
490258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                        break;
491258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    }
492258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // It would be unsafe to ever refer to the application pointers again
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pAudioSrc = NULL;
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pAudioSnk = NULL;
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // check the audio source and sink parameters against platform support
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = android_audioRecorder_checkSourceSinkSupport(thiz);
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (SL_RESULT_SUCCESS != result) {
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        SL_LOGE("Cannot create AudioRecorder: invalid source or sink");
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
50774006804065941841883c4b46ee785070164023fJamie Gennis                    // Allocate memory for buffer queue
5088ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev                    SLuint32 locatorType = thiz->mDataSink.mLocator.mLocatorType;
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (locatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE) {
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        thiz->mBufferQueue.mNumBuffers =
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            thiz->mDataSink.mLocator.mBufferQueue.numBuffers;
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // inline allocation of circular Buffer Queue mArray, up to a typical max
513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        if (BUFFER_HEADER_TYPICAL >= thiz->mBufferQueue.mNumBuffers) {
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            thiz->mBufferQueue.mArray = thiz->mBufferQueue.mTypical;
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        } else {
51674006804065941841883c4b46ee785070164023fJamie Gennis                            // Avoid possible integer overflow during multiplication; this arbitrary
51774006804065941841883c4b46ee785070164023fJamie Gennis                            // maximum is big enough to not interfere with real applications, but
51874006804065941841883c4b46ee785070164023fJamie Gennis                            // small enough to not overflow.
51974006804065941841883c4b46ee785070164023fJamie Gennis                            if (thiz->mBufferQueue.mNumBuffers >= 256) {
52074006804065941841883c4b46ee785070164023fJamie Gennis                                result = SL_RESULT_MEMORY_FAILURE;
52174006804065941841883c4b46ee785070164023fJamie Gennis                                break;
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            }
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            thiz->mBufferQueue.mArray = (BufferHeader *) malloc((thiz->mBufferQueue.
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                    mNumBuffers + 1) * sizeof(BufferHeader));
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            if (NULL == thiz->mBufferQueue.mArray) {
52674006804065941841883c4b46ee785070164023fJamie Gennis                                result = SL_RESULT_MEMORY_FAILURE;
52774006804065941841883c4b46ee785070164023fJamie Gennis                                break;
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            }
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        }
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        thiz->mBufferQueue.mFront = thiz->mBufferQueue.mArray;
53174006804065941841883c4b46ee785070164023fJamie Gennis                        thiz->mBufferQueue.mRear = thiz->mBufferQueue.mArray;
53274006804065941841883c4b46ee785070164023fJamie Gennis                    }
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // platform-specific initialization
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    android_audioRecorder_create(thiz);
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } while (0);
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (SL_RESULT_SUCCESS != result) {
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    IObject_Destroy(&thiz->mObject.mItf);
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
54574006804065941841883c4b46ee785070164023fJamie Gennis                    IObject_Publish(&thiz->mObject);
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // return the new audio recorder object
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    *pRecorder = &thiz->mObject.mItf;
548258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                }
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE)
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if ((NULL == pPlayer) || (NULL == pMIDISrc) || (NULL == pAudioOutput)) {
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pPlayer = NULL;
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned exposedMask;
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER);
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == pCMidiPlayer_class) {
5778ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev            result = SL_RESULT_FEATURE_UNSUPPORTED;
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = checkInterfaces(pCMidiPlayer_class, numInterfaces,
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                pInterfaceIds, pInterfaceRequired, &exposedMask);
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (SL_RESULT_SUCCESS == result) {
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CMidiPlayer *thiz = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self);
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (NULL == thiz) {
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_MEMORY_FAILURE;
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                "pMIDISrc", pMIDISrc, URI | MIDIBUFFERQUEUE, NONE
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                "pBankSrc", pBanksrc, NULL | URI | ADDRESS, NULL
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                "pAudioOutput", pAudioOutput, OUTPUTMIX, NULL
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                "pVibra", pVibra, NULL | IODEVICE, NULL
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                "pLEDArray", pLEDArray, NULL | IODEVICE, NULL
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // a fake value - why not use value from IPlay_init? what does CT check for?
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                thiz->mPlay.mDuration = 0;
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IObject_Publish(&thiz->mObject);
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // return the new MIDI player object
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *pPlayer = &thiz->mObject.mItf;
599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
609349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
614349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
615349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber#if USE_PROFILES & USE_PROFILES_GAME
616349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (NULL == pListener) {
617349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
618349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    } else {
619349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        *pListener = NULL;
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned exposedMask;
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == pCListener_class) {
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_FEATURE_UNSUPPORTED;
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = checkInterfaces(pCListener_class, numInterfaces,
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                pInterfaceIds, pInterfaceRequired, &exposedMask);
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (SL_RESULT_SUCCESS == result) {
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CListener *thiz = (CListener *) construct(pCListener_class, exposedMask, self);
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (NULL == thiz) {
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_MEMORY_FAILURE;
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IObject_Publish(&thiz->mObject);
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // return the new 3D listener object
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *pListener = &thiz->mObject.mItf;
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces,
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if USE_PROFILES & USE_PROFILES_GAME
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pGroup) {
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pGroup = NULL;
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned exposedMask;
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP);
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == pC3DGroup_class) {
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_FEATURE_UNSUPPORTED;
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = checkInterfaces(pC3DGroup_class, numInterfaces,
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                pInterfaceIds, pInterfaceRequired, &exposedMask);
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (SL_RESULT_SUCCESS == result) {
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            C3DGroup *thiz = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self);
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (NULL == thiz) {
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_MEMORY_FAILURE;
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                thiz->mMemberMask = 0;
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IObject_Publish(&thiz->mObject);
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // return the new 3D group object
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *pGroup = &thiz->mObject.mItf;
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces,
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pMix) {
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pMix = NULL;
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned exposedMask;
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX);
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        assert(NULL != pCOutputMix_class);
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = checkInterfaces(pCOutputMix_class, numInterfaces,
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pInterfaceIds, pInterfaceRequired, &exposedMask);
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (SL_RESULT_SUCCESS == result) {
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            COutputMix *thiz = (COutputMix *) construct(pCOutputMix_class, exposedMask, self);
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (NULL == thiz) {
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_MEMORY_FAILURE;
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                android_outputMix_create(thiz);
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef USE_SDL
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IEngine *thisEngine = &thiz->mObject.mEngine->mEngine;
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                interface_lock_exclusive(thisEngine);
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                bool unpause = false;
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (NULL == thisEngine->mOutputMix) {
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thisEngine->mOutputMix = thiz;
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    unpause = true;
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                interface_unlock_exclusive(thisEngine);
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IObject_Publish(&thiz->mObject);
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef USE_SDL
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (unpause) {
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Enable SDL_callback to be called periodically by SDL's internal thread
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    SDL_PauseAudio(0);
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // return the new output mix object
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *pMix = &thiz->mObject.mItf;
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor,
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const SLboolean *pInterfaceRequired)
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC)
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pMetadataExtractor) {
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pMetadataExtractor = NULL;
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned exposedMask;
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *pCMetadataExtractor_class =
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR);
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == pCMetadataExtractor_class) {
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_FEATURE_UNSUPPORTED;
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = checkInterfaces(pCMetadataExtractor_class, numInterfaces,
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                pInterfaceIds, pInterfaceRequired, &exposedMask);
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (SL_RESULT_SUCCESS == result) {
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CMetadataExtractor *thiz = (CMetadataExtractor *)
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                construct(pCMetadataExtractor_class, exposedMask, self);
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (NULL == thiz) {
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_MEMORY_FAILURE;
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                "pDataSource", pDataSource, NONE, NONE
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IObject_Publish(&thiz->mObject);
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // return the new metadata extractor object
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *pMetadataExtractor = &thiz->mObject.mItf;
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_SUCCESS;
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject,
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void *pParameters, SLuint32 objectID, SLuint32 numInterfaces,
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pObject) {
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pObject = NULL;
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_FEATURE_UNSUPPORTED;
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self,
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pNumSupportedInterfaces) {
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *clazz = objectIDtoClass(objectID);
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == clazz) {
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_FEATURE_UNSUPPORTED;
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            SLuint32 count = 0;
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            SLuint32 i;
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            for (i = 0; i < clazz->mInterfaceCount; ++i) {
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                switch (clazz->mInterfaces[i].mInterface) {
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_IMPLICIT:
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_IMPLICIT_PREREALIZE:
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_EXPLICIT:
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_EXPLICIT_PREREALIZE:
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_DYNAMIC:
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    ++count;
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_UNAVAILABLE:
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                default:
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    assert(false);
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            *pNumSupportedInterfaces = count;
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_SUCCESS;
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE;
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self,
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pInterfaceId) {
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pInterfaceId = NULL;
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const ClassTable *clazz = objectIDtoClass(objectID);
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == clazz) {
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_FEATURE_UNSUPPORTED;
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_PARAMETER_INVALID; // will be reset later
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            SLuint32 i;
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            for (i = 0; i < clazz->mInterfaceCount; ++i) {
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                switch (clazz->mInterfaces[i].mInterface) {
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_IMPLICIT:
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_IMPLICIT_PREREALIZE:
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_EXPLICIT:
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_EXPLICIT_PREREALIZE:
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_DYNAMIC:
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                case INTERFACE_UNAVAILABLE:
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    continue;
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                default:
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    assert(false);
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (index == 0) {
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    *pInterfaceId = &SL_IID_array[clazz->mInterfaces[i].mMPH];
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = SL_RESULT_SUCCESS;
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                --index;
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic const char * const extensionNames[] = {
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define _(n) #n
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define __(n) _(n)
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    "ANDROID_SDK_LEVEL_" __(PLATFORM_SDK_VERSION),
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#undef _
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#undef __
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    "WILHELM_DESKTOP",
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions)
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pNumExtensions) {
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pNumExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_SUCCESS;
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_QuerySupportedExtension(SLEngineItf self,
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pNameLength) {
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t actualNameLength;
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (index >= numExtensions) {
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            actualNameLength = 0;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_PARAMETER_INVALID;
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            const char *extensionName = extensionNames[index];
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            actualNameLength = strlen(extensionName) + 1;
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (NULL == pExtensionName) {
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // application is querying the name length in order to allocate a buffer
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                result = SL_RESULT_SUCCESS;
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                SLint16 availableNameLength = *pNameLength;
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (0 >= availableNameLength) {
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // there is not even room for the terminating NUL
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = SL_RESULT_BUFFER_INSUFFICIENT;
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else if (actualNameLength > (size_t) availableNameLength) {
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // "no invalid strings are written. That is, the null-terminator always exists"
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(pExtensionName, extensionName, (size_t) availableNameLength - 1);
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pExtensionName[(size_t) availableNameLength - 1] = '\0';
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = SL_RESULT_BUFFER_INSUFFICIENT;
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(pExtensionName, extensionName, actualNameLength);
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = SL_RESULT_SUCCESS;
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pNameLength = actualNameLength;
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic SLresult IEngine_IsExtensionSupported(SLEngineItf self,
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const SLchar *pExtensionName, SLboolean *pSupported)
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_ENTER_INTERFACE
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (NULL == pSupported) {
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = SL_RESULT_PARAMETER_INVALID;
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        SLboolean isSupported = SL_BOOLEAN_FALSE;
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (NULL == pExtensionName) {
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_PARAMETER_INVALID;
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            unsigned i;
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            for (i = 0; i < numExtensions; ++i) {
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (!strcmp((const char *) pExtensionName, extensionNames[i])) {
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    isSupported = SL_BOOLEAN_TRUE;
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            result = SL_RESULT_SUCCESS;
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pSupported = isSupported;
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SL_LEAVE_INTERFACE
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic const struct SLEngineItf_ IEngine_Itf = {
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateLEDDevice,
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateVibraDevice,
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateAudioPlayer,
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateAudioRecorder,
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateMidiPlayer,
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateListener,
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_Create3DGroup,
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateOutputMix,
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateMetadataExtractor,
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateExtensionObject,
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_QueryNumSupportedInterfaces,
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_QuerySupportedInterfaces,
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_QueryNumSupportedExtensions,
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_QuerySupportedExtension,
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_IsExtensionSupported
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
994f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid IEngine_init(void *self)
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine *thiz = (IEngine *) self;
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    thiz->mItf = &IEngine_Itf;
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // mLossOfControlGlobal is initialized in slCreateEngine
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef USE_SDL
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    thiz->mOutputMix = NULL;
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    thiz->mInstanceCount = 1; // ourself
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    thiz->mInstanceMask = 0;
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    thiz->mChangedMask = 0;
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    unsigned i;
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < MAX_INSTANCE; ++i) {
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        thiz->mInstances[i] = NULL;
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    thiz->mShutdown = SL_BOOLEAN_FALSE;
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    thiz->mShutdownAck = SL_BOOLEAN_FALSE;
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid IEngine_deinit(void *self)
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// OpenMAX AL Engine
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IEngine_CreateCameraDevice(XAEngineItf self, XAObjectItf *pDevice,
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const XAboolean *pInterfaceRequired)
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    XA_ENTER_INTERFACE
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    //IXAEngine *thiz = (IXAEngine *) self;
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
103031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    XA_LEAVE_INTERFACE
103131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
103231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
103331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
103431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huberstatic XAresult IEngine_CreateRadioDevice(XAEngineItf self, XAObjectItf *pDevice,
103531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
103631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        const XAboolean *pInterfaceRequired)
103731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber{
103831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    XA_ENTER_INTERFACE
103931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
104031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    //IXAEngine *thiz = (IXAEngine *) self;
104131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
104231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
104331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    XA_LEAVE_INTERFACE
104431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
104531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
104631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
104731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huberstatic XAresult IXAEngine_CreateLEDDevice(XAEngineItf self, XAObjectItf *pDevice, XAuint32 deviceID,
104831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
104931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        const XAboolean *pInterfaceRequired)
105031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber{
105131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    // forward to OpenSL ES
105231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    return IEngine_CreateLEDDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
105331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
105431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            (const SLboolean *) pInterfaceRequired);
105531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
105631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
105731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
105831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huberstatic XAresult IXAEngine_CreateVibraDevice(XAEngineItf self, XAObjectItf *pDevice,
105931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
106031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        const XAboolean *pInterfaceRequired)
106131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber{
106231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    // forward to OpenSL ES
106331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    return IEngine_CreateVibraDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
106431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
106531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            (const SLboolean *) pInterfaceRequired);
106631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
106731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
106831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
106931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huberstatic XAresult IEngine_CreateMediaPlayer(XAEngineItf self, XAObjectItf *pPlayer,
107031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        XADataSource *pDataSrc, XADataSource *pBankSrc, XADataSink *pAudioSnk,
107131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        XADataSink *pImageVideoSnk, XADataSink *pVibra, XADataSink *pLEDArray,
107231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
107331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        const XAboolean *pInterfaceRequired)
107431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber{
107531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    XA_ENTER_INTERFACE
107631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
107731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    if (NULL == pPlayer) {
107831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        result = XA_RESULT_PARAMETER_INVALID;
107931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    } else {
108031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        *pPlayer = NULL;
108131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        unsigned exposedMask;
108231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        const ClassTable *pCMediaPlayer_class = objectIDtoClass(XA_OBJECTID_MEDIAPLAYER);
108331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        assert(NULL != pCMediaPlayer_class);
108489c120e7adbe09c6283591789594c5e591aa5032Andreas Huber        result = checkInterfaces(pCMediaPlayer_class, numInterfaces,
108589c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                (const SLInterfaceID *) pInterfaceIds, pInterfaceRequired, &exposedMask);
108631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        if (XA_RESULT_SUCCESS == result) {
108731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
108831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            // Construct our new MediaPlayer instance
108931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CMediaPlayer *thiz = (CMediaPlayer *) construct(pCMediaPlayer_class, exposedMask,
109031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf);
109131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (NULL == thiz) {
109231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                result = XA_RESULT_MEMORY_FAILURE;
109331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else {
109431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
109531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                do {
109631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
109731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // Initialize private fields not associated with an interface
109831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
109931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // Default data source in case of failure in checkDataSource
110031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
110131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    thiz->mDataSource.mFormat.mFormatType = XA_DATAFORMAT_NULL;
110231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
110331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // Default andio and image sink in case of failure in checkDataSink
110431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    thiz->mAudioSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
110531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    thiz->mAudioSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;
110631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    thiz->mImageVideoSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
110731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    thiz->mImageVideoSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;
110831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
110931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // More default values, in case destructor needs to be called early
111031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
111131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
111231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // (assume calloc or memset 0 during allocation)
111331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // placement new
111431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber#ifdef ANDROID
111531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // FIXME unnecessary once those fields are encapsulated in one class, rather
111631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    //   than a structure
111731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    (void) new (&thiz->mAVPlayer) android::sp<android::GenericPlayer>();
111831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber#endif
111931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
112031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // Check the source and sink parameters against generic constraints
112131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
112231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    result = checkDataSource("pDataSrc", (const SLDataSource *) pDataSrc,
112331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            &thiz->mDataSource, DATALOCATOR_MASK_URI
112431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber#ifdef ANDROID
112531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            | DATALOCATOR_MASK_ANDROIDFD
112631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            , DATAFORMAT_MASK_MIME);
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (XA_RESULT_SUCCESS != result) {
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = checkDataSource("pBankSrc", (const SLDataSource *) pBankSrc,
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            &thiz->mBankSource, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_URI |
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            DATALOCATOR_MASK_ADDRESS, DATAFORMAT_MASK_NULL);
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (XA_RESULT_SUCCESS != result) {
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = checkDataSink("pAudioSnk", (const SLDataSink *) pAudioSnk,
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            &thiz->mAudioSink, DATALOCATOR_MASK_OUTPUTMIX, DATAFORMAT_MASK_NULL);
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (XA_RESULT_SUCCESS != result) {
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = checkDataSink("pImageVideoSnk", (const SLDataSink *) pImageVideoSnk,
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            &thiz->mImageVideoSink,
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_NATIVEDISPLAY,
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            DATAFORMAT_MASK_NULL);
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (XA_RESULT_SUCCESS != result) {
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = checkDataSink("pVibra", (const SLDataSink *) pVibra, &thiz->mVibraSink,
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            DATAFORMAT_MASK_NULL);
1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (XA_RESULT_SUCCESS != result) {
1158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = checkDataSink("pLEDArray", (const SLDataSink *) pLEDArray,
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            &thiz->mLEDArraySink, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            DATAFORMAT_MASK_NULL);
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (XA_RESULT_SUCCESS != result) {
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Unsafe to ever refer to application pointers again
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pDataSrc = NULL;
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pBankSrc = NULL;
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pAudioSnk = NULL;
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pImageVideoSnk = NULL;
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pVibra = NULL;
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    pLEDArray = NULL;
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // Check that the requested interfaces are compatible with the data source
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // FIXME implement
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // check the source and sink parameters against platform support
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    result = android_Player_checkSourceSink(thiz);
1182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (XA_RESULT_SUCCESS != result) {
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
1184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // AndroidBufferQueue-specific initialization
1189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (XA_DATALOCATOR_ANDROIDBUFFERQUEUE ==
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            thiz->mDataSource.mLocator.mLocatorType) {
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        XAuint16 nbBuffers = (XAuint16) thiz->mDataSource.mLocator.mABQ.numBuffers;
1192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // Avoid possible integer overflow during multiplication; this arbitrary
1194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // maximum is big enough to not interfere with real applications, but
1195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // small enough to not overflow.
1196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        if (nbBuffers >= 256) {
1197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            result = SL_RESULT_MEMORY_FAILURE;
1198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            break;
1199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        }
1200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // initialize ABQ buffer type
1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // assert below has been checked in android_audioPlayer_checkSourceSink
1203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        assert(XA_DATAFORMAT_MIME == thiz->mDataSource.mFormat.mFormatType);
1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        if (XA_CONTAINERTYPE_MPEG_TS ==
1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                thiz->mDataSource.mFormat.mMIME.containerType) {
1206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;
1207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            // Set the container type for the StreamInformation interface
1209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            XAMediaContainerInformation *containerInfo =
1210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                    (XAMediaContainerInformation*)
1211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                        // always storing container info at index 0, as per spec
1212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                        &(thiz->mStreamInfo.mStreamInfoTable.itemAt(0).
1213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                                containerInfo);
1214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            containerInfo->containerType = XA_CONTAINERTYPE_MPEG_TS;
1215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            // there are no streams at this stage
1216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            containerInfo->numStreams = 0;
1217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        } else {
1219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
1220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            SL_LOGE("Invalid buffer type in Android Buffer Queue");
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            result = SL_RESULT_CONTENT_UNSUPPORTED;
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        }
1223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        // initialize ABQ memory
1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        thiz->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *)
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                    malloc( (nbBuffers + 1) * sizeof(AdvancedBufferHeader));
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        if (NULL == thiz->mAndroidBufferQueue.mBufferArray) {
1228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            result = SL_RESULT_MEMORY_FAILURE;
12295bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                            break;
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        } else {
1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            for (XAuint16 i=0 ; i<(nbBuffers + 1) ; i++) {
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                thiz->mAndroidBufferQueue.mBufferArray[i].mDataBuffer = NULL;
1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                thiz->mAndroidBufferQueue.mBufferArray[i].mDataSize = 0;
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                thiz->mAndroidBufferQueue.mBufferArray[i].mDataSizeConsumed = 0;
1235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                thiz->mAndroidBufferQueue.mBufferArray[i].mBufferContext = NULL;
1236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                thiz->mAndroidBufferQueue.mBufferArray[i].mBufferState =
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                        XA_ANDROIDBUFFERQUEUEEVENT_NONE;
1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                switch (thiz->mAndroidBufferQueue.mBufferType) {
1239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                  case kAndroidBufferTypeMpeg2Ts:
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                    thiz->mAndroidBufferQueue.mBufferArray[i].mItems.mTsCmdData.
1241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                            mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                    thiz->mAndroidBufferQueue.mBufferArray[i].mItems.mTsCmdData.
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                            mPts = 0;
1244349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                                    break;
1245349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                                  default:
1246349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                                    result = SL_RESULT_CONTENT_UNSUPPORTED;
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                    break;
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                }
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            }
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            thiz->mAndroidBufferQueue.mFront =
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                    thiz->mAndroidBufferQueue.mBufferArray;
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            thiz->mAndroidBufferQueue.mRear =
1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                    thiz->mAndroidBufferQueue.mBufferArray;
1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        }
1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers;
1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // used to store the data source of our audio player
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource;
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // platform-specific initialization
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef ANDROID
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    android_Player_create(thiz);
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } while (0);
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (XA_RESULT_SUCCESS != result) {
1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    IObject_Destroy(&thiz->mObject.mItf);
1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    IObject_Publish(&thiz->mObject);
1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // return the new media player object
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    *pPlayer = (XAObjectItf) &thiz->mObject.mItf;
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    XA_LEAVE_INTERFACE
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IEngine_CreateMediaRecorder(XAEngineItf self, XAObjectItf *pRecorder,
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        XADataSource *pAudioSrc, XADataSource *pImageVideoSrc,
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        XADataSink *pDataSnk, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const XAboolean *pInterfaceRequired)
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    XA_ENTER_INTERFACE
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    //IXAEngine *thiz = (IXAEngine *) self;
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    "pAudioSrc", pAudioSrc,
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    "pImageVideoSrc", pImageVideoSrc,
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    "pDataSink", pDataSnk,
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    XA_LEAVE_INTERFACE
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13073831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
13083831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huberstatic XAresult IXAEngine_CreateOutputMix(XAEngineItf self, XAObjectItf *pMix,
13093831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const XAboolean *pInterfaceRequired)
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return IEngine_CreateOutputMix(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            (SLObjectItf *) pMix, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            (const SLboolean *) pInterfaceRequired);
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IXAEngine_CreateMetadataExtractor(XAEngineItf self, XAObjectItf *pMetadataExtractor,
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            XADataSource *pDataSource, XAuint32 numInterfaces,
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return IEngine_CreateMetadataExtractor(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            (SLObjectItf *) pMetadataExtractor, (SLDataSource *) pDataSource, numInterfaces,
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IXAEngine_CreateExtensionObject(XAEngineItf self, XAObjectItf *pObject,
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *pParameters, XAuint32 objectID, XAuint32 numInterfaces,
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return IEngine_CreateExtensionObject(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            (SLObjectItf *) pObject, pParameters, objectID, numInterfaces,
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IEngine_GetImplementationInfo(XAEngineItf self, XAuint32 *pMajor, XAuint32 *pMinor,
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        XAuint32 *pStep, /* XAuint32 nImplementationTextSize, */ const XAchar *pImplementationText)
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    XA_ENTER_INTERFACE
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    //IXAEngine *thiz = (IXAEngine *) self;
1347349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    result = SL_RESULT_FEATURE_UNSUPPORTED;
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    XA_LEAVE_INTERFACE
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IXAEngine_QuerySupportedProfiles(XAEngineItf self, XAint16 *pProfilesSupported)
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    XA_ENTER_INTERFACE
1356349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
1357349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (NULL == pProfilesSupported) {
1358349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        result = XA_RESULT_PARAMETER_INVALID;
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 1
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pProfilesSupported = 0;
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // the code below was copied from OpenSL ES and needs to be adapted for OpenMAX AL.
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The generic implementation doesn't implement any of the profiles, they shouldn't be
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // declared as supported. Also exclude the fake profiles BASE and OPTIONAL.
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *pProfilesSupported = USE_PROFILES &
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                (USE_PROFILES_GAME | USE_PROFILES_MUSIC | USE_PROFILES_PHONE);
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result = XA_RESULT_SUCCESS;
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    XA_LEAVE_INTERFACE
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1375349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
1376349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatic XAresult IXAEngine_QueryNumSupportedInterfaces(XAEngineItf self, XAuint32 objectID,
1377349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        XAuint32 *pNumSupportedInterfaces)
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return IEngine_QueryNumSupportedInterfaces(
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID,
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pNumSupportedInterfaces);
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IXAEngine_QuerySupportedInterfaces(XAEngineItf self, XAuint32 objectID,
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        XAuint32 index, XAInterfaceID *pInterfaceId)
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return IEngine_QuerySupportedInterfaces(
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID, index,
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            (SLInterfaceID *) pInterfaceId);
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IXAEngine_QueryNumSupportedExtensions(XAEngineItf self, XAuint32 *pNumExtensions)
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return IEngine_QueryNumSupportedExtensions(
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, pNumExtensions);
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IXAEngine_QuerySupportedExtension(XAEngineItf self, XAuint32 index,
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        XAchar *pExtensionName, XAint16 *pNameLength)
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return IEngine_QuerySupportedExtension(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            index, pExtensionName, (SLint16 *) pNameLength);
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IXAEngine_IsExtensionSupported(XAEngineItf self, const XAchar *pExtensionName,
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        XAboolean *pSupported)
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return IEngine_IsExtensionSupported(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pExtensionName, pSupported);
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IXAEngine_QueryLEDCapabilities(XAEngineItf self, XAuint32 *pIndex,
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        XAuint32 *pLEDDeviceID, XALEDDescriptor *pDescriptor)
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES EngineCapabilities
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return (XAresult) IEngineCapabilities_QueryLEDCapabilities(
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            pLEDDeviceID, (SLLEDDescriptor *) pDescriptor);
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic XAresult IXAEngine_QueryVibraCapabilities(XAEngineItf self, XAuint32 *pIndex,
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        XAuint32 *pVibraDeviceID, XAVibraDescriptor *pDescriptor)
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // forward to OpenSL ES EngineCapabilities
1436349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    return (XAresult) IEngineCapabilities_QueryVibraCapabilities(
1437349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
1438349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            pVibraDeviceID, (SLVibraDescriptor *) pDescriptor);
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// OpenMAX AL engine v-table
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic const struct XAEngineItf_ IXAEngine_Itf = {
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateCameraDevice,
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateRadioDevice,
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_CreateLEDDevice,
1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_CreateVibraDevice,
1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateMediaPlayer,
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_CreateMediaRecorder,
1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_CreateOutputMix,
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_CreateMetadataExtractor,
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_CreateExtensionObject,
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IEngine_GetImplementationInfo,
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_QuerySupportedProfiles,
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_QueryNumSupportedInterfaces,
1457349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    IXAEngine_QuerySupportedInterfaces,
1458349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    IXAEngine_QueryNumSupportedExtensions,
1459349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    IXAEngine_QuerySupportedExtension,
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_IsExtensionSupported,
1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_QueryLEDCapabilities,
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IXAEngine_QueryVibraCapabilities
1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid IXAEngine_init(void *self)
146731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber{
146831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    IXAEngine *thiz = (IXAEngine *) self;
146931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    thiz->mItf = &IXAEngine_Itf;
147031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid IXAEngine_deinit(void *self)
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber