sles_allinclusive.h revision 33b27581efde3ee91652bfec35194b2d54603c7c
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/** \file sles_allinclusive.h Everything including the kitchen sink */
18
19#include "SLES/OpenSLES.h"
20#include "OMXAL/OpenMAXAL.h"
21#ifdef ANDROID
22#include "SLES/OpenSLES_Android.h"
23#include "OMXAL/OpenMAXAL_Android.h"
24#endif
25#include <stddef.h> // offsetof
26#include <stdlib.h> // malloc
27#include <string.h> // memcmp
28#include <strings.h>
29#include <stdio.h>  // debugging
30#include <assert.h> // debugging
31#include <pthread.h>
32#include <unistd.h> // usleep
33#include <errno.h>
34
35#ifndef __cplusplus
36typedef int bool;
37#ifndef false
38#define false 0
39#endif
40#ifndef true
41#define true 1
42#endif
43#endif
44
45// The OpenSLES.h definitions of SL_PROFILES_... have casts, so are unusable by preprocessor
46#define USE_PROFILES_PHONE    0x1   // == SL_PROFILES_PHONE
47#define USE_PROFILES_MUSIC    0x2   // == SL_PROFILES_MUSIC
48#define USE_PROFILES_GAME     0x4   // == SL_PROFILES_GAME
49// Pseudo profiles, used to decide whether to include code for incomplete or untested features
50// Features that are not in union of all profiles: audio recorder, LED, Vibra
51#define USE_PROFILES_OPTIONAL 0x8
52// Features that are in the intersection of all profiles:
53// object priorities, preemption, loss of control, device configuration
54#define USE_PROFILES_BASE     0x10
55
56#include "MPH.h"
57#include "MPH_to.h"
58#include "devices.h"
59#include "ut/OpenSLESUT.h"
60#include "ThreadPool.h"
61
62typedef struct CEngine_struct CEngine;
63typedef struct CAudioPlayer_struct CAudioPlayer;
64typedef struct CAudioRecorder_struct CAudioRecorder;
65typedef struct C3DGroup_struct C3DGroup;
66typedef struct COutputMix_struct COutputMix;
67
68#ifdef USE_SNDFILE
69#include <sndfile.h>
70#include "desktop/SLSndFile.h"
71#endif // USE_SNDFILE
72
73#ifdef USE_SDL
74#include <SDL/SDL_audio.h>
75#endif // USE_SDL
76
77#define STEREO_CHANNELS 2
78
79#ifdef ANDROID
80#include <utils/Log.h>
81#include <utils/KeyedVector.h>
82#include "SLES/OpenSLES_AndroidConfiguration.h"
83#include "media/AudioSystem.h"
84#include "media/mediarecorder.h"
85#include "media/AudioRecord.h"
86#include "media/AudioTrack.h"
87#include "media/mediaplayer.h"
88#include <media/IStreamSource.h>
89#include "media/AudioEffect.h"
90#include "media/EffectApi.h"
91#include "media/EffectEqualizerApi.h"
92#include "media/EffectBassBoostApi.h"
93#include "media/EffectVirtualizerApi.h"
94#include "media/EffectPresetReverbApi.h"
95#include "media/EffectEnvironmentalReverbApi.h"
96#include <utils/String8.h>
97#define ANDROID_SL_MILLIBEL_MAX 0
98#include <binder/ProcessState.h>
99#include "android/android_sles_conversions.h"
100#include "android/android_defs.h"
101#include "android/android_SfPlayer.h"
102#endif
103
104#ifdef USE_OUTPUTMIXEXT
105#include "desktop/OutputMixExt.h"
106#endif
107
108#include "sllog.h"
109
110typedef enum {
111    predestroy_error,   // Application should not be calling destroy now
112    predestroy_ok,      // OK to destroy object now
113    predestroy_again    // Application did nothing wrong, but should destroy again to be effective
114} predestroy_t;
115
116// Hook functions
117
118typedef void (*VoidHook)(void *self);
119//typedef SLresult (*ResultHook)(void *self);
120typedef SLresult (*AsyncHook)(void *self, SLboolean async);
121typedef bool (*BoolHook)(void *self);
122typedef predestroy_t (*PreDestroyHook)(void *self);
123
124// Describes how an interface is related to a given class, used in iid_vtable::mInterface
125
126#define INTERFACE_IMPLICIT            0 // no need for application to request prior to GetInterface
127#define INTERFACE_EXPLICIT            1 // must be requested explicitly during object creation
128#define INTERFACE_DYNAMIC             2 // can be requested after object creation
129#define INTERFACE_UNAVAILABLE         3 // this interface is not available on objects of this class
130#define INTERFACE_IMPLICIT_PREREALIZE 4 // implicit, and can call GetInterface before Realize
131#define INTERFACE_EXPLICIT_PREREALIZE 5 // explicit, and can call GetInterface before Realize
132// 6 and 7 are reserved for the meaningless DYNAMIC_PREREALIZE and UNAVAILABLE_PREREALIZE
133// note that INTERFACE_OPTIONAL is always re-mapped to one of the above
134#define INTERFACE_PREREALIZE          4 // bit-mask to test for calling GetInterface before Realize
135
136// Profile-specific interfaces
137
138#if USE_PROFILES & USE_PROFILES_BASE
139#define INTERFACE_IMPLICIT_BASE       INTERFACE_IMPLICIT
140#define INTERFACE_EXPLICIT_BASE       INTERFACE_EXPLICIT
141#else
142#define INTERFACE_IMPLICIT_BASE       INTERFACE_UNAVAILABLE
143#define INTERFACE_EXPLICIT_BASE       INTERFACE_UNAVAILABLE
144#endif
145
146#if USE_PROFILES & USE_PROFILES_GAME
147#define INTERFACE_DYNAMIC_GAME        INTERFACE_DYNAMIC
148#define INTERFACE_EXPLICIT_GAME       INTERFACE_EXPLICIT
149#else
150#define INTERFACE_DYNAMIC_GAME        INTERFACE_OPTIONAL
151#define INTERFACE_EXPLICIT_GAME       INTERFACE_OPTIONAL
152#endif
153
154#if USE_PROFILES & USE_PROFILES_MUSIC
155#define INTERFACE_DYNAMIC_MUSIC       INTERFACE_DYNAMIC
156#else
157#define INTERFACE_DYNAMIC_MUSIC       INTERFACE_OPTIONAL
158#endif
159
160#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC)
161#define INTERFACE_DYNAMIC_GAME_MUSIC  INTERFACE_DYNAMIC
162#define INTERFACE_EXPLICIT_GAME_MUSIC INTERFACE_EXPLICIT
163#else
164#define INTERFACE_DYNAMIC_GAME_MUSIC  INTERFACE_OPTIONAL
165#define INTERFACE_EXPLICIT_GAME_MUSIC INTERFACE_OPTIONAL
166#endif
167
168#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE)
169#define INTERFACE_EXPLICIT_GAME_PHONE INTERFACE_EXPLICIT
170#else
171#define INTERFACE_EXPLICIT_GAME_PHONE INTERFACE_OPTIONAL
172#endif
173
174#if USE_PROFILES & USE_PROFILES_OPTIONAL
175#define INTERFACE_OPTIONAL            INTERFACE_EXPLICIT
176#define INTERFACE_DYNAMIC_OPTIONAL    INTERFACE_DYNAMIC
177#else
178#define INTERFACE_OPTIONAL            INTERFACE_UNAVAILABLE
179#define INTERFACE_DYNAMIC_OPTIONAL    INTERFACE_UNAVAILABLE
180#endif
181
182// Describes how an interface is related to a given object
183
184#define INTERFACE_UNINITIALIZED 0  ///< not available
185#define INTERFACE_INITIALIZED   1  ///< not requested at object creation time
186#define INTERFACE_EXPOSED       2  ///< requested at object creation time
187#define INTERFACE_ADDING_1      3  ///< part 1 of asynchronous AddInterface, pending
188#define INTERFACE_ADDING_2      4  ///< synchronous AddInterface, or part 2 of asynchronous
189#define INTERFACE_ADDED         5  ///< AddInterface has completed
190#define INTERFACE_REMOVING      6  ///< unlocked phase of (synchronous) RemoveInterface
191#define INTERFACE_SUSPENDING    7  ///< suspend in progress
192#define INTERFACE_SUSPENDED     8  ///< suspend has completed
193#define INTERFACE_RESUMING_1    9  ///< part 1 of asynchronous ResumeInterface, pending
194#define INTERFACE_RESUMING_2   10  ///< synchronous ResumeInterface, or part 2 of asynchronous
195#define INTERFACE_ADDING_1A    11  ///< part 1 of asynchronous AddInterface, aborted
196#define INTERFACE_RESUMING_1A  12  ///< part 1 of asynchronous ResumeInterface, aborted
197
198
199// Maps an interface ID to its offset within the class that exposes it
200
201struct iid_vtable {
202    unsigned char mMPH;         // primary MPH for this interface, does not include any aliases
203    unsigned char mInterface;   // relationship of interface to this class
204    /*size_t*/ unsigned short mOffset;
205};
206
207// Per-class const data shared by all instances of the same class
208
209typedef struct {
210    const struct iid_vtable *mInterfaces;   // maps interface index to info about that interface
211    SLuint32 mInterfaceCount;  // number of possible interfaces
212    const signed char *mMPH_to_index;
213    const char * const mName;
214    size_t mSize;
215    // OpenSL ES and OpenMAX AL object IDs come from different ranges, and some objects such as
216    // Engine, Output Mix, LED, and Vibra belong to both APIs, so we keep both object IDs
217    SLuint16 mSLObjectID;   // OpenSL ES object ID
218    XAuint16 mXAObjectID;   // OpenMAX AL object ID
219    // hooks
220    AsyncHook mRealize;
221    AsyncHook mResume;
222    VoidHook mDestroy;
223    PreDestroyHook mPreDestroy;
224} ClassTable;
225
226// BufferHeader describes each element of a BufferQueue, other than the data
227typedef struct {
228    const void *mBuffer;
229    SLuint32 mSize;
230} BufferHeader;
231
232#ifdef ANDROID
233// Holds information about all commands that can be passed alongside an MPEG-2 TS buffer
234// Is used with buffers of type kAndroidBufferTypeMpeg2Ts
235typedef struct {
236    SLuint32 mTsCmdCode;
237    SLAuint64 mPts;
238} Mpeg2TsCommands;
239
240// Union of the different structures to hold items stored in an AdvancedBufferHeader
241//   when an item comes from an AndroidBufferQueue as the data source, it's a command
242//   when an item is output to an AndroidBufferQueue as the data sink, it's a message (or metadata)
243typedef union {
244    Mpeg2TsCommands mTsCmdData;
245} AdvancedBufferItems;
246
247// AdvancedBufferHeader describes each element of an AndroidBufferQueue, other than the data
248//  and associated messages
249typedef struct {
250    const void *mDataBuffer;
251    SLuint32 mDataSize;
252    SLuint32 mDataSizeConsumed;
253    AdvancedBufferItems mItems;
254    const void *mBufferContext;
255    SLuint32 mBufferState;
256} AdvancedBufferHeader;
257#endif
258
259#ifdef USE_SNDFILE
260
261#define SndFile_BUFSIZE 512     // in 16-bit samples
262#define SndFile_NUMBUFS 2
263
264struct SndFile {
265    // save URI also?
266    SLchar *mPathname;
267    SNDFILE *mSNDFILE;
268    SF_INFO mSfInfo;
269    pthread_mutex_t mMutex; // protects mSNDFILE only
270    SLboolean mEOF;         // sf_read returned zero sample frames
271    SLuint32 mWhich;        // which buffer to use next
272    short mBuffer[SndFile_BUFSIZE * SndFile_NUMBUFS];
273};
274
275#endif // USE_SNDFILE
276
277#include "data.h"
278#include "itfstruct.h"
279
280#ifdef ANDROID
281
282#ifdef ANDROID
283// FIXME this include is done here so the effect structures and enums have been defined. Messy.
284#include "android/android_Effect.h"
285#include "android/android_GenericPlayer.h"
286#include "android/android_GenericMediaPlayer.h"
287#include "android/android_AudioSfDecoder.h"
288#include "android/android_AudioToCbRenderer.h"
289#include "android/android_StreamPlayer.h"
290#include "android/android_LocAVPlayer.h"
291#endif
292
293#endif  // ANDROID
294
295#include "classes.h"
296
297struct MPH_init {
298    VoidHook mInit;     // called first to initialize the interface, right after object is allocated
299    // Each interface is initialized regardless whether it is exposed to application.
300    VoidHook mResume;   // called to resume interface after suspension, not currently used
301    VoidHook mDeinit;   // called last when object is about to be destroyed
302    BoolHook mExpose;   // called after initialization, only if interface is exposed to application
303    VoidHook mRemove;   // called by DynamicInterfaceManager::RemoveInterface, and prior to mDeinit
304    // will need a suspend hook when suspend is implemented
305};
306
307extern /*static*/ int IID_to_MPH(const SLInterfaceID iid);
308extern /*static*/ const struct MPH_init MPH_init_table[MPH_MAX];
309extern SLresult checkInterfaces(const ClassTable *clazz,
310    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
311    const SLboolean *pInterfaceRequired, unsigned *pExposedMask);
312extern IObject *construct(const ClassTable *clazz,
313    unsigned exposedMask, SLEngineItf engine);
314extern const ClassTable *objectIDtoClass(SLuint32 objectID);
315extern const struct SLInterfaceID_ SL_IID_array[MPH_MAX];
316extern SLuint32 IObjectToObjectID(IObject *object);
317extern void IObject_Publish(IObject *thiz);
318extern void IObject_Destroy(SLObjectItf self);
319
320// Map an interface to it's "object ID" (which is really a class ID).
321// Note: this operation is undefined on IObject, as it lacks an mThis.
322// If you have an IObject, then use IObjectToObjectID directly.
323
324#define InterfaceToObjectID(thiz) IObjectToObjectID((thiz)->mThis)
325
326// Map an interface to it's corresponding IObject.
327// Note: this operation is undefined on IObject, as it lacks an mThis.
328// If you have an IObject, then you're done -- you already have what you need.
329
330#define InterfaceToIObject(thiz) ((thiz)->mThis)
331
332#define InterfaceToCAudioPlayer(thiz) (((CAudioPlayer*)InterfaceToIObject(thiz)))
333
334#define InterfaceToCAudioRecorder(thiz) (((CAudioRecorder*)InterfaceToIObject(thiz)))
335
336#ifdef ANDROID
337#include "android/MediaPlayer_to_android.h"
338#include "android/OutputMix_to_android.h"
339#include "android/AudioPlayer_to_android.h"
340#include "android/AudioRecorder_to_android.h"
341#endif
342
343extern predestroy_t C3DGroup_PreDestroy(void *self);
344
345extern SLresult CAudioPlayer_Realize(void *self, SLboolean async);
346extern SLresult CAudioPlayer_Resume(void *self, SLboolean async);
347extern void CAudioPlayer_Destroy(void *self);
348extern predestroy_t CAudioPlayer_PreDestroy(void *self);
349
350extern SLresult CAudioRecorder_Realize(void *self, SLboolean async);
351extern SLresult CAudioRecorder_Resume(void *self, SLboolean async);
352extern void CAudioRecorder_Destroy(void *self);
353extern predestroy_t CAudioRecorder_PreDestroy(void *self);
354
355extern SLresult CEngine_Realize(void *self, SLboolean async);
356extern SLresult CEngine_Resume(void *self, SLboolean async);
357extern void CEngine_Destroy(void *self);
358extern predestroy_t CEngine_PreDestroy(void *self);
359extern void CEngine_Destroyed(CEngine *self);
360
361extern SLresult COutputMix_Realize(void *self, SLboolean async);
362extern SLresult COutputMix_Resume(void *self, SLboolean async);
363extern void COutputMix_Destroy(void *self);
364extern predestroy_t COutputMix_PreDestroy(void *self);
365
366extern SLresult CMediaPlayer_Realize(void *self, SLboolean async);
367extern SLresult CMediaPlayer_Resume(void *self, SLboolean async);
368extern void CMediaPlayer_Destroy(void *self);
369extern predestroy_t CMediaPlayer_PreDestroy(void *self);
370
371#ifdef USE_SDL
372extern void SDL_open(IEngine *thisEngine);
373extern void SDL_close(void);
374#endif
375#define SL_OBJECT_STATE_REALIZING_1  ((SLuint32) 0x4) // async realize on work queue
376#define SL_OBJECT_STATE_REALIZING_2  ((SLuint32) 0x5) // sync realize, or async realize hook
377#define SL_OBJECT_STATE_RESUMING_1   ((SLuint32) 0x6) // async resume on work queue
378#define SL_OBJECT_STATE_RESUMING_2   ((SLuint32) 0x7) // sync resume, or async resume hook
379#define SL_OBJECT_STATE_SUSPENDING   ((SLuint32) 0x8) // suspend in progress
380#define SL_OBJECT_STATE_REALIZING_1A ((SLuint32) 0x9) // abort while async realize on work queue
381#define SL_OBJECT_STATE_RESUMING_1A  ((SLuint32) 0xA) // abort while async resume on work queue
382#define SL_OBJECT_STATE_DESTROYING   ((SLuint32) 0xB) // destroy object when no strong references
383#ifndef ANDROID
384extern void *sync_start(void *arg);
385#endif
386extern SLresult err_to_result(int err);
387
388#ifdef __GNUC__
389#define ctz __builtin_ctz
390#else
391extern unsigned ctz(unsigned);
392#endif
393extern const char * const interface_names[MPH_MAX];
394#include "platform.h"
395
396// Attributes
397
398#define ATTR_NONE       ((unsigned) 0x0)      // none
399#define ATTR_GAIN       ((unsigned) 0x1 << 0) // player volume, channel mute, channel solo,
400                                              // player stereo position, player mute
401#define ATTR_TRANSPORT   ((unsigned) 0x1 << 1) // play state, looping
402#define ATTR_POSITION    ((unsigned) 0x1 << 2) // requested position (a.k.a. seek position)
403#define ATTR_BQ_ENQUEUE  ((unsigned) 0x1 << 3) // buffer queue became non-empty and in playing state
404#define ATTR_ABQ_ENQUEUE ((unsigned) 0x1 << 4) // Android buffer queue became non-empty and
405                                               //     in playing state
406
407#include "trace.h"
408
409#ifdef USE_SNDFILE
410extern void audioPlayerTransportUpdate(CAudioPlayer *audioPlayer);
411#endif
412
413extern SLresult IBufferQueue_Enqueue(SLBufferQueueItf self, const void *pBuffer, SLuint32 size);
414extern SLresult IBufferQueue_Clear(SLBufferQueueItf self);
415extern SLresult IBufferQueue_RegisterCallback(SLBufferQueueItf self,
416    slBufferQueueCallback callback, void *pContext);
417
418extern bool IsInterfaceInitialized(IObject *thiz, unsigned MPH);
419extern SLresult AcquireStrongRef(IObject *object, SLuint32 expectedObjectID);
420extern void ReleaseStrongRef(IObject *object);
421extern void ReleaseStrongRefAndUnlockExclusive(IObject *object);
422
423extern COutputMix *CAudioPlayer_GetOutputMix(CAudioPlayer *audioPlayer);
424extern SLresult IEngineCapabilities_QueryLEDCapabilities(SLEngineCapabilitiesItf self,
425    SLuint32 *pIndex, SLuint32 *pLEDDeviceID, SLLEDDescriptor *pDescriptor);
426extern SLresult IEngineCapabilities_QueryVibraCapabilities(SLEngineCapabilitiesItf self,
427    SLuint32 *pIndex, SLuint32 *pVibraDeviceID, SLVibraDescriptor *pDescriptor);
428
429extern CEngine *theOneTrueEngine;
430extern pthread_mutex_t theOneTrueMutex;
431extern unsigned theOneTrueRefCount;
432
433extern LI_API SLresult liCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
434    const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
435    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired,
436    const ClassTable *pCEngine_class);
437extern LI_API SLresult liQueryNumSupportedInterfaces(SLuint32 *pNumSupportedInterfaces,
438        const ClassTable *clazz);
439extern LI_API SLresult liQuerySupportedInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId,
440        const ClassTable *clazz);
441