OSDN Git Service

Async callback queue updates, applied to XAStreamInformationItf
[android-x86/system-media.git] / wilhelm / src / sles_allinclusive.h
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
36 typedef 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
62 typedef struct CEngine_struct CEngine;
63 typedef struct CAudioPlayer_struct CAudioPlayer;
64 typedef struct CAudioRecorder_struct CAudioRecorder;
65 typedef struct C3DGroup_struct C3DGroup;
66 typedef 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 /**
80  * Constants to define unknown property values
81  */
82 #define UNKNOWN_NUMCHANNELS 0
83 #define UNKNOWN_SAMPLERATE  0
84 #define UNKNOWN_CHANNELMASK 0
85
86 #ifdef ANDROID
87 #include <utils/Log.h>
88 #include <utils/KeyedVector.h>
89 #include "SLES/OpenSLES_AndroidConfiguration.h"
90 #include "media/AudioSystem.h"
91 #include "media/mediarecorder.h"
92 #include "media/AudioRecord.h"
93 #include "media/AudioTrack.h"
94 #include "media/mediaplayer.h"
95 #include <utils/String8.h>
96 #define ANDROID_SL_MILLIBEL_MAX 0
97 #include "android/android_sles_conversions.h"
98 #include "android/android_defs.h"
99 #endif
100
101 #ifdef USE_OUTPUTMIXEXT
102 #include "desktop/OutputMixExt.h"
103 #endif
104
105 #include "sllog.h"
106
107 typedef enum {
108     predestroy_error,   // Application should not be calling destroy now
109     predestroy_ok,      // OK to destroy object now
110     predestroy_again    // Application did nothing wrong, but should destroy again to be effective
111 } predestroy_t;
112
113 // Hook functions
114
115 typedef void (*VoidHook)(void *self);
116 //typedef SLresult (*ResultHook)(void *self);
117 typedef SLresult (*AsyncHook)(void *self, SLboolean async);
118 typedef bool (*BoolHook)(void *self);
119 typedef predestroy_t (*PreDestroyHook)(void *self);
120
121 // Describes how an interface is related to a given class, used in iid_vtable::mInterface
122
123 #define INTERFACE_IMPLICIT            0 // no need for application to request prior to GetInterface
124 #define INTERFACE_EXPLICIT            1 // must be requested explicitly during object creation
125 #define INTERFACE_DYNAMIC             2 // can be requested after object creation
126 #define INTERFACE_UNAVAILABLE         3 // this interface is not available on objects of this class
127 #define INTERFACE_IMPLICIT_PREREALIZE 4 // implicit, and can call GetInterface before Realize
128 #define INTERFACE_EXPLICIT_PREREALIZE 5 // explicit, and can call GetInterface before Realize
129 // 6 and 7 are reserved for the meaningless DYNAMIC_PREREALIZE and UNAVAILABLE_PREREALIZE
130 // note that INTERFACE_OPTIONAL is always re-mapped to one of the above
131 #define INTERFACE_PREREALIZE          4 // bit-mask to test for calling GetInterface before Realize
132
133 // Profile-specific interfaces
134
135 #if USE_PROFILES & USE_PROFILES_BASE
136 #define INTERFACE_IMPLICIT_BASE       INTERFACE_IMPLICIT
137 #define INTERFACE_EXPLICIT_BASE       INTERFACE_EXPLICIT
138 #else
139 #define INTERFACE_IMPLICIT_BASE       INTERFACE_UNAVAILABLE
140 #define INTERFACE_EXPLICIT_BASE       INTERFACE_UNAVAILABLE
141 #endif
142
143 #if USE_PROFILES & USE_PROFILES_GAME
144 #define INTERFACE_DYNAMIC_GAME        INTERFACE_DYNAMIC
145 #define INTERFACE_EXPLICIT_GAME       INTERFACE_EXPLICIT
146 #else
147 #define INTERFACE_DYNAMIC_GAME        INTERFACE_OPTIONAL
148 #define INTERFACE_EXPLICIT_GAME       INTERFACE_OPTIONAL
149 #endif
150
151 #if USE_PROFILES & USE_PROFILES_MUSIC
152 #define INTERFACE_DYNAMIC_MUSIC       INTERFACE_DYNAMIC
153 #else
154 #define INTERFACE_DYNAMIC_MUSIC       INTERFACE_OPTIONAL
155 #endif
156
157 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC)
158 #define INTERFACE_DYNAMIC_GAME_MUSIC  INTERFACE_DYNAMIC
159 #define INTERFACE_EXPLICIT_GAME_MUSIC INTERFACE_EXPLICIT
160 #else
161 #define INTERFACE_DYNAMIC_GAME_MUSIC  INTERFACE_OPTIONAL
162 #define INTERFACE_EXPLICIT_GAME_MUSIC INTERFACE_OPTIONAL
163 #endif
164
165 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE)
166 #define INTERFACE_EXPLICIT_GAME_PHONE INTERFACE_EXPLICIT
167 #else
168 #define INTERFACE_EXPLICIT_GAME_PHONE INTERFACE_OPTIONAL
169 #endif
170
171 #if USE_PROFILES & USE_PROFILES_OPTIONAL
172 #define INTERFACE_OPTIONAL            INTERFACE_EXPLICIT
173 #define INTERFACE_DYNAMIC_OPTIONAL    INTERFACE_DYNAMIC
174 #else
175 #define INTERFACE_OPTIONAL            INTERFACE_UNAVAILABLE
176 #define INTERFACE_DYNAMIC_OPTIONAL    INTERFACE_UNAVAILABLE
177 #endif
178
179 // Describes how an interface is related to a given object
180
181 #define INTERFACE_UNINITIALIZED 0  ///< not available
182 #define INTERFACE_INITIALIZED   1  ///< not requested at object creation time
183 #define INTERFACE_EXPOSED       2  ///< requested at object creation time
184 #define INTERFACE_ADDING_1      3  ///< part 1 of asynchronous AddInterface, pending
185 #define INTERFACE_ADDING_2      4  ///< synchronous AddInterface, or part 2 of asynchronous
186 #define INTERFACE_ADDED         5  ///< AddInterface has completed
187 #define INTERFACE_REMOVING      6  ///< unlocked phase of (synchronous) RemoveInterface
188 #define INTERFACE_SUSPENDING    7  ///< suspend in progress
189 #define INTERFACE_SUSPENDED     8  ///< suspend has completed
190 #define INTERFACE_RESUMING_1    9  ///< part 1 of asynchronous ResumeInterface, pending
191 #define INTERFACE_RESUMING_2   10  ///< synchronous ResumeInterface, or part 2 of asynchronous
192 #define INTERFACE_ADDING_1A    11  ///< part 1 of asynchronous AddInterface, aborted
193 #define INTERFACE_RESUMING_1A  12  ///< part 1 of asynchronous ResumeInterface, aborted
194
195
196 // Maps an interface ID to its offset within the class that exposes it
197
198 struct iid_vtable {
199     unsigned char mMPH;         // primary MPH for this interface, does not include any aliases
200     unsigned char mInterface;   // relationship of interface to this class
201     /*size_t*/ unsigned short mOffset;
202 };
203
204 // Per-class const data shared by all instances of the same class
205
206 typedef struct {
207     const struct iid_vtable *mInterfaces;   // maps interface index to info about that interface
208     SLuint32 mInterfaceCount;  // number of possible interfaces
209     const signed char *mMPH_to_index;
210     const char * const mName;
211     size_t mSize;
212     // OpenSL ES and OpenMAX AL object IDs come from different ranges, and some objects such as
213     // Engine, Output Mix, LED, and Vibra belong to both APIs, so we keep both object IDs
214     SLuint16 mSLObjectID;   // OpenSL ES object ID
215     XAuint16 mXAObjectID;   // OpenMAX AL object ID
216     // hooks
217     AsyncHook mRealize;
218     AsyncHook mResume;
219     VoidHook mDestroy;
220     PreDestroyHook mPreDestroy;
221 } ClassTable;
222
223 // BufferHeader describes each element of a BufferQueue, other than the data
224 typedef struct {
225     const void *mBuffer;
226     SLuint32 mSize;
227 } BufferHeader;
228
229 #ifdef ANDROID
230 // Holds information about all commands that can be passed alongside an MPEG-2 TS buffer
231 // Is used with buffers of type kAndroidBufferTypeMpeg2Ts
232 typedef struct {
233     SLuint32 mTsCmdCode;
234     SLAuint64 mPts;
235 } Mpeg2TsCommands;
236
237 // Union of the different structures to hold items stored in an AdvancedBufferHeader
238 //   when an item comes from an AndroidBufferQueue as the data source, it's a command
239 //   when an item is output to an AndroidBufferQueue as the data sink, it's a message (or metadata)
240 typedef union {
241     Mpeg2TsCommands mTsCmdData;
242 } AdvancedBufferItems;
243
244 // AdvancedBufferHeader describes each element of an AndroidBufferQueue, other than the data
245 //  and associated messages
246 typedef struct {
247     const void *mDataBuffer;
248     SLuint32 mDataSize;
249     SLuint32 mDataSizeConsumed;
250     AdvancedBufferItems mItems;
251     const void *mBufferContext;
252     SLuint32 mBufferState;
253 } AdvancedBufferHeader;
254 #endif
255
256 #ifdef USE_SNDFILE
257
258 #define SndFile_BUFSIZE 512     // in 16-bit samples
259 #define SndFile_NUMBUFS 2
260
261 struct SndFile {
262     // save URI also?
263     SLchar *mPathname;
264     SNDFILE *mSNDFILE;
265     SF_INFO mSfInfo;
266     pthread_mutex_t mMutex; // protects mSNDFILE only
267     SLboolean mEOF;         // sf_read returned zero sample frames
268     SLuint32 mWhich;        // which buffer to use next
269     short mBuffer[SndFile_BUFSIZE * SndFile_NUMBUFS];
270 };
271
272 #endif // USE_SNDFILE
273
274 #include "data.h"
275 #include "itfstruct.h"
276 #include "classes.h"
277
278 struct MPH_init {
279     VoidHook mInit;     // called first to initialize the interface, right after object is allocated
280     // Each interface is initialized regardless whether it is exposed to application.
281     VoidHook mResume;   // called to resume interface after suspension, not currently used
282     VoidHook mDeinit;   // called last when object is about to be destroyed
283     BoolHook mExpose;   // called after initialization, only if interface is exposed to application
284     VoidHook mRemove;   // called by DynamicInterfaceManager::RemoveInterface, and prior to mDeinit
285     // will need a suspend hook when suspend is implemented
286 };
287
288 extern /*static*/ int IID_to_MPH(const SLInterfaceID iid);
289 extern /*static*/ const struct MPH_init MPH_init_table[MPH_MAX];
290 extern SLresult checkInterfaces(const ClassTable *clazz,
291     SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
292     const SLboolean *pInterfaceRequired, unsigned *pExposedMask);
293 extern IObject *construct(const ClassTable *clazz,
294     unsigned exposedMask, SLEngineItf engine);
295 extern const ClassTable *objectIDtoClass(SLuint32 objectID);
296 extern const struct SLInterfaceID_ SL_IID_array[MPH_MAX];
297 extern SLuint32 IObjectToObjectID(IObject *object);
298 extern void IObject_Publish(IObject *thiz);
299 extern void IObject_Destroy(SLObjectItf self);
300
301 // Map an interface to it's "object ID" (which is really a class ID).
302 // Note: this operation is undefined on IObject, as it lacks an mThis.
303 // If you have an IObject, then use IObjectToObjectID directly.
304
305 #define InterfaceToObjectID(thiz) IObjectToObjectID((thiz)->mThis)
306
307 // Map an interface to it's corresponding IObject.
308 // Note: this operation is undefined on IObject, as it lacks an mThis.
309 // If you have an IObject, then you're done -- you already have what you need.
310
311 #define InterfaceToIObject(thiz) ((thiz)->mThis)
312
313 #define InterfaceToCAudioPlayer(thiz) (((CAudioPlayer*)InterfaceToIObject(thiz)))
314
315 #define InterfaceToCAudioRecorder(thiz) (((CAudioRecorder*)InterfaceToIObject(thiz)))
316
317 #define InterfaceToCAudioRecorder(thiz) (((CAudioRecorder*)InterfaceToIObject(thiz)))
318
319 #define InterfaceToCMediaPlayer(thiz) (((CMediaPlayer*)InterfaceToIObject(thiz)))
320
321 #ifdef ANDROID
322 #include "android/MediaPlayer_to_android.h"
323 #include "android/OutputMix_to_android.h"
324 #include "android/AudioPlayer_to_android.h"
325 #include "android/AudioRecorder_to_android.h"
326 #endif
327
328 extern predestroy_t C3DGroup_PreDestroy(void *self);
329
330 extern SLresult CAudioPlayer_Realize(void *self, SLboolean async);
331 extern SLresult CAudioPlayer_Resume(void *self, SLboolean async);
332 extern void CAudioPlayer_Destroy(void *self);
333 extern predestroy_t CAudioPlayer_PreDestroy(void *self);
334
335 extern SLresult CAudioRecorder_Realize(void *self, SLboolean async);
336 extern SLresult CAudioRecorder_Resume(void *self, SLboolean async);
337 extern void CAudioRecorder_Destroy(void *self);
338 extern predestroy_t CAudioRecorder_PreDestroy(void *self);
339
340 extern SLresult CEngine_Realize(void *self, SLboolean async);
341 extern SLresult CEngine_Resume(void *self, SLboolean async);
342 extern void CEngine_Destroy(void *self);
343 extern predestroy_t CEngine_PreDestroy(void *self);
344 extern void CEngine_Destroyed(CEngine *self);
345
346 extern SLresult COutputMix_Realize(void *self, SLboolean async);
347 extern SLresult COutputMix_Resume(void *self, SLboolean async);
348 extern void COutputMix_Destroy(void *self);
349 extern predestroy_t COutputMix_PreDestroy(void *self);
350
351 extern SLresult CMediaPlayer_Realize(void *self, SLboolean async);
352 extern SLresult CMediaPlayer_Resume(void *self, SLboolean async);
353 extern void CMediaPlayer_Destroy(void *self);
354 extern predestroy_t CMediaPlayer_PreDestroy(void *self);
355
356 #ifdef USE_SDL
357 extern void SDL_open(IEngine *thisEngine);
358 extern void SDL_close(void);
359 #endif
360 #define SL_OBJECT_STATE_REALIZING_1  ((SLuint32) 0x4) // async realize on work queue
361 #define SL_OBJECT_STATE_REALIZING_2  ((SLuint32) 0x5) // sync realize, or async realize hook
362 #define SL_OBJECT_STATE_RESUMING_1   ((SLuint32) 0x6) // async resume on work queue
363 #define SL_OBJECT_STATE_RESUMING_2   ((SLuint32) 0x7) // sync resume, or async resume hook
364 #define SL_OBJECT_STATE_SUSPENDING   ((SLuint32) 0x8) // suspend in progress
365 #define SL_OBJECT_STATE_REALIZING_1A ((SLuint32) 0x9) // abort while async realize on work queue
366 #define SL_OBJECT_STATE_RESUMING_1A  ((SLuint32) 0xA) // abort while async resume on work queue
367 #define SL_OBJECT_STATE_DESTROYING   ((SLuint32) 0xB) // destroy object when no strong references
368 #ifndef ANDROID
369 extern void *sync_start(void *arg);
370 #endif
371 extern SLresult err_to_result(int err);
372
373 #ifdef __GNUC__
374 #define ctz __builtin_ctz
375 #else
376 extern unsigned ctz(unsigned);
377 #endif
378 extern const char * const interface_names[MPH_MAX];
379 #include "platform.h"
380 #include "attr.h"
381 #include "handlers.h"
382 #include "trace.h"
383
384 #ifdef USE_SNDFILE
385 extern void audioPlayerTransportUpdate(CAudioPlayer *audioPlayer);
386 #endif
387
388 extern SLresult IBufferQueue_Enqueue(SLBufferQueueItf self, const void *pBuffer, SLuint32 size);
389 extern SLresult IBufferQueue_Clear(SLBufferQueueItf self);
390 extern SLresult IBufferQueue_RegisterCallback(SLBufferQueueItf self,
391     slBufferQueueCallback callback, void *pContext);
392
393 extern bool IsInterfaceInitialized(IObject *thiz, unsigned MPH);
394 extern SLresult AcquireStrongRef(IObject *object, SLuint32 expectedObjectID);
395 extern void ReleaseStrongRef(IObject *object);
396 extern void ReleaseStrongRefAndUnlockExclusive(IObject *object);
397
398 extern COutputMix *CAudioPlayer_GetOutputMix(CAudioPlayer *audioPlayer);
399 extern SLresult IEngineCapabilities_QueryLEDCapabilities(SLEngineCapabilitiesItf self,
400     SLuint32 *pIndex, SLuint32 *pLEDDeviceID, SLLEDDescriptor *pDescriptor);
401 extern SLresult IEngineCapabilities_QueryVibraCapabilities(SLEngineCapabilitiesItf self,
402     SLuint32 *pIndex, SLuint32 *pVibraDeviceID, SLVibraDescriptor *pDescriptor);
403
404 extern CEngine *theOneTrueEngine;
405 extern pthread_mutex_t theOneTrueMutex;
406 extern unsigned theOneTrueRefCount;
407
408 extern LI_API SLresult liCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
409     const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
410     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired,
411     const ClassTable *pCEngine_class);
412 extern LI_API SLresult liQueryNumSupportedInterfaces(SLuint32 *pNumSupportedInterfaces,
413         const ClassTable *clazz);
414 extern LI_API SLresult liQuerySupportedInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId,
415         const ClassTable *clazz);
416
417 // The EnqueueAsyncCallback macros provide a safe way to asynchronously call an application-level
418 // callback handler that is permitted to do almost anything, including block.  This is intended
419 // primarily for "notification" callbacks such as play head progress.  Do not use for callbacks
420 // which must be synchronous, such as buffer queue completions.  The enqueue may fail if
421 // the callback queue is full.  This almost always indicates an application error such as blocking
422 // for an excessive time within a callback handler or requesting too frequent callbacks.  The
423 // recommended recovery is to either retry later, or log a warning or error as appropriate.
424 // If the callback absolutely must be called, then you should be calling it directly instead.
425 // Example usage:
426 //  CAudioPlayer *ap;
427 //  SLresult result = EnqueueAsyncCallback_ppi(ap, playCallback, &ap->mPlay.mItf, playContext,
428 //       SL_PLAYEVENT_HEADATEND);
429 //  if (SL_RESULT_SUCCESS != result) {
430 //    LOGW("Callback %p(%p, %p, SL_PLAYEVENT_HEADATEND) dropped", playCallback, &ap->mPlay.mItf,
431 //        playContext);
432 //  }
433 // which replaces:
434 //  (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
435 #define EnqueueAsyncCallback_ppi(object, handler, p1, p2, i1) \
436         ThreadPool_add_ppi(&(object)->mObject.mEngine->mThreadPool, \
437             (ClosureHandler_ppi) (handler), (p1), (p2), (i1))
438 #define EnqueueAsyncCallback_ppii(object, handler, p1, p2, i1, i2) \
439         ThreadPool_add_ppii(&(object)->mObject.mEngine->mThreadPool, \
440             (ClosureHandler_ppii) (handler), (p1), (p2), (i1), (i2))
441 #define EnqueueAsyncCallback_piipp(object, handler, p1, i1, i2, p2, p3) \
442         ThreadPool_add_piipp(&(object)->mObject.mEngine->mThreadPool, \
443             (ClosureHandler_piipp) (handler), (p1), (i1), (i2), (p2), (p3))