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