misc: medialibrary: ctx does not need dynamic lifetime
[vlc.git] / modules / audio_output / opensles_android.c
blobb475c0855d0821ab6bc1425a33791384f8bc3ad5
1 /*****************************************************************************
2 * opensles_android.c : audio output for android native code
3 *****************************************************************************
4 * Copyright © 2011-2012 VideoLAN
6 * Authors: Dominique Martinet <asmadeus@codewreck.org>
7 * Hugo Beauzée-Luyssen <hugo@beauzee.fr>
8 * Rafaël Carré <funman@videolanorg>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_aout.h>
36 #include <assert.h>
37 #include <dlfcn.h>
38 #include <math.h>
40 // For native audio
41 #include <SLES/OpenSLES.h>
42 #include <SLES/OpenSLES_Android.h>
44 #include <jni.h>
45 JNIEnv *android_getEnv(vlc_object_t *p_obj, const char *psz_thread_name);
47 #define OPENSLES_BUFFERS 255 /* maximum number of buffers */
48 #define OPENSLES_BUFLEN 10 /* ms */
50 * 10ms of precision when mesasuring latency should be enough,
51 * with 255 buffers we can buffer 2.55s of audio.
54 #define CHECK_OPENSL_ERROR(msg) \
55 if (unlikely(result != SL_RESULT_SUCCESS)) \
56 { \
57 msg_Err(aout, msg" (%lu)", result); \
58 goto error; \
61 typedef SLresult (*slCreateEngine_t)(
62 SLObjectItf*, SLuint32, const SLEngineOption*, SLuint32,
63 const SLInterfaceID*, const SLboolean*);
65 #define Destroy(a) (*a)->Destroy(a);
66 #define SetPlayState(a, b) (*a)->SetPlayState(a, b)
67 #define RegisterCallback(a, b, c) (*a)->RegisterCallback(a, b, c)
68 #define GetInterface(a, b, c) (*a)->GetInterface(a, b, c)
69 #define Realize(a, b) (*a)->Realize(a, b)
70 #define CreateOutputMix(a, b, c, d, e) (*a)->CreateOutputMix(a, b, c, d, e)
71 #define CreateAudioPlayer(a, b, c, d, e, f, g) \
72 (*a)->CreateAudioPlayer(a, b, c, d, e, f, g)
73 #define Enqueue(a, b, c) (*a)->Enqueue(a, b, c)
74 #define Clear(a) (*a)->Clear(a)
75 #define GetState(a, b) (*a)->GetState(a, b)
76 #define SetPositionUpdatePeriod(a, b) (*a)->SetPositionUpdatePeriod(a, b)
77 #define SetVolumeLevel(a, b) (*a)->SetVolumeLevel(a, b)
78 #define SetMute(a, b) (*a)->SetMute(a, b)
80 /*****************************************************************************
82 *****************************************************************************/
83 typedef struct
85 /* OpenSL objects */
86 SLObjectItf engineObject;
87 SLObjectItf outputMixObject;
88 SLAndroidSimpleBufferQueueItf playerBufferQueue;
89 SLObjectItf playerObject;
90 SLVolumeItf volumeItf;
91 SLEngineItf engineEngine;
92 SLPlayItf playerPlay;
94 /* OpenSL symbols */
95 void *p_so_handle;
97 slCreateEngine_t slCreateEnginePtr;
98 SLInterfaceID SL_IID_ENGINE;
99 SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
100 SLInterfaceID SL_IID_VOLUME;
101 SLInterfaceID SL_IID_PLAY;
103 /* */
105 vlc_mutex_t lock;
107 /* audio buffered through opensles */
108 uint8_t *buf;
109 size_t samples_per_buf;
110 int next_buf;
112 int rate;
114 /* if we can measure latency already */
115 bool started;
117 /* audio not yet buffered through opensles */
118 block_t *p_buffer_chain;
119 block_t **pp_buffer_last;
120 size_t samples;
121 } aout_sys_t;
123 /*****************************************************************************
124 * Local prototypes.
125 *****************************************************************************/
126 static int Open (vlc_object_t *);
127 static void Close (vlc_object_t *);
129 /*****************************************************************************
130 * Module descriptor
131 *****************************************************************************/
133 vlc_module_begin ()
134 set_description("OpenSLES audio output")
135 set_shortname("OpenSLES")
136 set_category(CAT_AUDIO)
137 set_subcategory(SUBCAT_AUDIO_AOUT)
139 set_capability("audio output", 170)
140 add_shortcut("opensles", "android")
141 set_callbacks(Open, Close)
142 vlc_module_end ()
144 /*****************************************************************************
146 *****************************************************************************/
148 static inline int bytesPerSample(void)
150 return 2 /* S16 */ * 2 /* stereo */;
153 static int TimeGet(audio_output_t* aout, vlc_tick_t* restrict drift)
155 aout_sys_t *sys = aout->sys;
157 SLAndroidSimpleBufferQueueState st;
158 SLresult res = GetState(sys->playerBufferQueue, &st);
159 if (unlikely(res != SL_RESULT_SUCCESS)) {
160 msg_Err(aout, "Could not query buffer queue state in TimeGet (%lu)", res);
161 return -1;
164 vlc_mutex_lock(&sys->lock);
165 bool started = sys->started;
166 vlc_mutex_unlock(&sys->lock);
168 if (!started)
169 return -1;
171 *drift = (CLOCK_FREQ * OPENSLES_BUFLEN * st.count / 1000)
172 + sys->samples * CLOCK_FREQ / sys->rate;
174 /* msg_Dbg(aout, "latency %"PRId64" ms, %d/%d buffers", *drift / 1000,
175 (int)st.count, OPENSLES_BUFFERS); */
177 return 0;
180 static void Flush(audio_output_t *aout, bool drain)
182 aout_sys_t *sys = aout->sys;
184 if (drain) {
185 vlc_tick_t delay;
186 if (!TimeGet(aout, &delay))
187 vlc_tick_sleep(delay);
188 } else {
189 vlc_mutex_lock(&sys->lock);
190 SetPlayState(sys->playerPlay, SL_PLAYSTATE_STOPPED);
191 Clear(sys->playerBufferQueue);
192 SetPlayState(sys->playerPlay, SL_PLAYSTATE_PLAYING);
194 /* release audio data not yet written to opensles */
195 block_ChainRelease(sys->p_buffer_chain);
196 sys->p_buffer_chain = NULL;
197 sys->pp_buffer_last = &sys->p_buffer_chain;
199 sys->samples = 0;
200 sys->started = false;
202 vlc_mutex_unlock(&sys->lock);
206 static int VolumeSet(audio_output_t *aout, float vol)
208 aout_sys_t *sys = aout->sys;
209 if (!sys->volumeItf)
210 return -1;
212 /* Convert UI volume to linear factor (cube) */
213 vol = vol * vol * vol;
215 /* millibels from linear amplification */
216 int mb = lroundf(2000.f * log10f(vol));
217 if (mb < SL_MILLIBEL_MIN)
218 mb = SL_MILLIBEL_MIN;
219 else if (mb > 0)
220 mb = 0; /* maximum supported level could be higher: GetMaxVolumeLevel */
222 SLresult r = SetVolumeLevel(sys->volumeItf, mb);
223 return (r == SL_RESULT_SUCCESS) ? 0 : -1;
226 static int MuteSet(audio_output_t *aout, bool mute)
228 aout_sys_t *sys = aout->sys;
229 if (!sys->volumeItf)
230 return -1;
232 SLresult r = SetMute(sys->volumeItf, mute);
233 return (r == SL_RESULT_SUCCESS) ? 0 : -1;
236 static void Pause(audio_output_t *aout, bool pause, vlc_tick_t date)
238 (void)date;
239 aout_sys_t *sys = aout->sys;
240 SetPlayState(sys->playerPlay,
241 pause ? SL_PLAYSTATE_PAUSED : SL_PLAYSTATE_PLAYING);
244 static int WriteBuffer(audio_output_t *aout)
246 aout_sys_t *sys = aout->sys;
247 const size_t unit_size = sys->samples_per_buf * bytesPerSample();
249 block_t *b = sys->p_buffer_chain;
250 if (!b)
251 return false;
253 /* Check if we can fill at least one buffer unit by chaining blocks */
254 if (b->i_buffer < unit_size) {
255 if (!b->p_next)
256 return false;
257 ssize_t needed = unit_size - b->i_buffer;
258 for (block_t *next = b->p_next; next; next = next->p_next) {
259 needed -= next->i_buffer;
260 if (needed <= 0)
261 break;
264 if (needed > 0)
265 return false;
268 SLAndroidSimpleBufferQueueState st;
269 SLresult res = GetState(sys->playerBufferQueue, &st);
270 if (unlikely(res != SL_RESULT_SUCCESS)) {
271 msg_Err(aout, "Could not query buffer queue state in %s (%lu)", __func__, res);
272 return false;
275 if (st.count == OPENSLES_BUFFERS)
276 return false;
278 size_t done = 0;
279 while (done < unit_size) {
280 size_t cur = b->i_buffer;
281 if (cur > unit_size - done)
282 cur = unit_size - done;
284 memcpy(&sys->buf[unit_size * sys->next_buf + done], b->p_buffer, cur);
285 b->i_buffer -= cur;
286 b->p_buffer += cur;
287 done += cur;
289 block_t *next = b->p_next;
290 if (b->i_buffer == 0) {
291 block_Release(b);
292 b = NULL;
295 if (done == unit_size)
296 break;
297 else
298 b = next;
301 sys->p_buffer_chain = b;
302 if (!b)
303 sys->pp_buffer_last = &sys->p_buffer_chain;
305 SLresult r = Enqueue(sys->playerBufferQueue,
306 &sys->buf[unit_size * sys->next_buf], unit_size);
308 sys->samples -= sys->samples_per_buf;
310 if (r == SL_RESULT_SUCCESS) {
311 if (++sys->next_buf == OPENSLES_BUFFERS)
312 sys->next_buf = 0;
313 return true;
314 } else {
315 /* XXX : if writing fails, we don't retry */
316 msg_Err(aout, "error %lu when writing %d bytes %s",
317 r, b->i_buffer,
318 (r == SL_RESULT_BUFFER_INSUFFICIENT) ? " (buffer insufficient)" : "");
319 return false;
323 /*****************************************************************************
324 * Play: play a sound
325 *****************************************************************************/
326 static void Play(audio_output_t *aout, block_t *p_buffer, vlc_tick_t date)
328 aout_sys_t *sys = aout->sys;
330 p_buffer->p_next = NULL; /* Make sur our linked list doesn't use old references */
331 vlc_mutex_lock(&sys->lock);
333 sys->samples += p_buffer->i_buffer / bytesPerSample();
335 /* Hold this block until we can write it into the OpenSL buffer */
336 block_ChainLastAppend(&sys->pp_buffer_last, p_buffer);
338 /* Fill OpenSL buffer */
339 while (WriteBuffer(aout))
342 vlc_mutex_unlock(&sys->lock);
343 (void) date;
346 static void PlayedCallback (SLAndroidSimpleBufferQueueItf caller, void *pContext)
348 (void)caller;
349 audio_output_t *aout = pContext;
350 aout_sys_t *sys = aout->sys;
352 assert (caller == sys->playerBufferQueue);
354 vlc_mutex_lock(&sys->lock);
355 sys->started = true;
356 vlc_mutex_unlock(&sys->lock);
359 static int aout_get_native_sample_rate(audio_output_t *aout)
361 JNIEnv *p_env;
362 if (!(p_env = android_getEnv(VLC_OBJECT(aout), "opensles")))
363 return -1;
364 jclass cls = (*p_env)->FindClass (p_env, "android/media/AudioTrack");
365 if ((*p_env)->ExceptionCheck(p_env))
367 (*p_env)->ExceptionClear(p_env);
368 return -1;
370 jmethodID method = (*p_env)->GetStaticMethodID(p_env, cls,
371 "getNativeOutputSampleRate",
372 "(I)I");
373 /* 3 for AudioManager.STREAM_MUSIC */
374 int sample_rate = (*p_env)->CallStaticIntMethod(p_env, cls, method, 3);
375 (*p_env)->DeleteLocalRef(p_env, cls);
376 msg_Dbg(aout, "%s: %d", __func__, sample_rate);
377 return sample_rate;
380 /*****************************************************************************
382 *****************************************************************************/
383 static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
385 if (aout_FormatNbChannels(fmt) == 0 || !AOUT_FMT_LINEAR(fmt))
386 return VLC_EGENERIC;
388 SLresult result;
390 aout_sys_t *sys = aout->sys;
392 // configure audio source - this defines the number of samples you can enqueue.
393 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
394 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
395 OPENSLES_BUFFERS
398 SLDataFormat_PCM format_pcm;
399 format_pcm.formatType = SL_DATAFORMAT_PCM;
400 format_pcm.numChannels = 2;
401 format_pcm.samplesPerSec = ((SLuint32) fmt->i_rate * 1000) ;
402 format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
403 format_pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
404 format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
405 format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
407 SLDataSource audioSrc = {&loc_bufq, &format_pcm};
409 // configure audio sink
410 SLDataLocator_OutputMix loc_outmix = {
411 SL_DATALOCATOR_OUTPUTMIX,
412 sys->outputMixObject
414 SLDataSink audioSnk = {&loc_outmix, NULL};
416 //create audio player
417 const SLInterfaceID ids2[] = { sys->SL_IID_ANDROIDSIMPLEBUFFERQUEUE, sys->SL_IID_VOLUME };
418 static const SLboolean req2[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
420 if (aout_get_native_sample_rate(aout) >= fmt->i_rate) {
421 result = CreateAudioPlayer(sys->engineEngine, &sys->playerObject, &audioSrc,
422 &audioSnk, sizeof(ids2) / sizeof(*ids2),
423 ids2, req2);
424 } else {
425 // Don't try to play back a sample rate higher than the native one,
426 // since OpenSL ES will try to use the fast path, which AudioFlinger
427 // will reject (fast path can't do resampling), and will end up with
428 // too small buffers for the resampling. See http://b.android.com/59453
429 // for details. This bug is still present in 4.4. If it is fixed later
430 // this workaround could be made conditional.
431 result = SL_RESULT_UNKNOWN_ERROR;
433 if (unlikely(result != SL_RESULT_SUCCESS)) {
434 /* Try again with a more sensible samplerate */
435 fmt->i_rate = 44100;
436 format_pcm.samplesPerSec = ((SLuint32) 44100 * 1000) ;
437 result = CreateAudioPlayer(sys->engineEngine, &sys->playerObject, &audioSrc,
438 &audioSnk, sizeof(ids2) / sizeof(*ids2),
439 ids2, req2);
441 CHECK_OPENSL_ERROR("Failed to create audio player");
443 result = Realize(sys->playerObject, SL_BOOLEAN_FALSE);
444 CHECK_OPENSL_ERROR("Failed to realize player object.");
446 result = GetInterface(sys->playerObject, sys->SL_IID_PLAY, &sys->playerPlay);
447 CHECK_OPENSL_ERROR("Failed to get player interface.");
449 result = GetInterface(sys->playerObject, sys->SL_IID_VOLUME, &sys->volumeItf);
450 CHECK_OPENSL_ERROR("failed to get volume interface.");
452 result = GetInterface(sys->playerObject, sys->SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
453 &sys->playerBufferQueue);
454 CHECK_OPENSL_ERROR("Failed to get buff queue interface");
456 result = RegisterCallback(sys->playerBufferQueue, PlayedCallback,
457 (void*)aout);
458 CHECK_OPENSL_ERROR("Failed to register buff queue callback.");
460 // set the player's state to playing
461 result = SetPlayState(sys->playerPlay, SL_PLAYSTATE_PLAYING);
462 CHECK_OPENSL_ERROR("Failed to switch to playing state");
464 /* XXX: rounding shouldn't affect us at normal sampling rate */
465 sys->rate = fmt->i_rate;
466 sys->samples_per_buf = OPENSLES_BUFLEN * fmt->i_rate / 1000;
467 sys->buf = vlc_alloc(sys->samples_per_buf * bytesPerSample(), OPENSLES_BUFFERS);
468 if (!sys->buf)
469 goto error;
471 sys->started = false;
472 sys->next_buf = 0;
474 sys->p_buffer_chain = NULL;
475 sys->pp_buffer_last = &sys->p_buffer_chain;
476 sys->samples = 0;
478 // we want 16bit signed data native endian.
479 fmt->i_format = VLC_CODEC_S16N;
480 fmt->i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
481 fmt->channel_type = AUDIO_CHANNEL_TYPE_BITMAP;
483 SetPositionUpdatePeriod(sys->playerPlay, AOUT_MIN_PREPARE_TIME * 1000 / CLOCK_FREQ);
485 aout_FormatPrepare(fmt);
487 return VLC_SUCCESS;
489 error:
490 if (sys->playerObject) {
491 Destroy(sys->playerObject);
492 sys->playerObject = NULL;
493 sys->playerBufferQueue = NULL;
494 sys->volumeItf = NULL;
495 sys->playerPlay = NULL;
498 return VLC_EGENERIC;
501 static void Stop(audio_output_t *aout)
503 aout_sys_t *sys = aout->sys;
505 SetPlayState(sys->playerPlay, SL_PLAYSTATE_STOPPED);
506 //Flush remaining buffers if any.
507 Clear(sys->playerBufferQueue);
509 free(sys->buf);
510 block_ChainRelease(sys->p_buffer_chain);
512 Destroy(sys->playerObject);
513 sys->playerObject = NULL;
514 sys->playerBufferQueue = NULL;
515 sys->volumeItf = NULL;
516 sys->playerPlay = NULL;
519 /*****************************************************************************
521 *****************************************************************************/
522 static void Close(vlc_object_t *obj)
524 audio_output_t *aout = (audio_output_t *)obj;
525 aout_sys_t *sys = aout->sys;
527 Destroy(sys->outputMixObject);
528 Destroy(sys->engineObject);
529 dlclose(sys->p_so_handle);
530 vlc_mutex_destroy(&sys->lock);
531 free(sys);
534 static int Open (vlc_object_t *obj)
536 audio_output_t *aout = (audio_output_t *)obj;
537 aout_sys_t *sys;
538 SLresult result;
540 aout->sys = sys = calloc(1, sizeof(*sys));
541 if (unlikely(sys == NULL))
542 return VLC_ENOMEM;
544 sys->p_so_handle = dlopen("libOpenSLES.so", RTLD_NOW);
545 if (sys->p_so_handle == NULL)
547 msg_Err(aout, "Failed to load libOpenSLES");
548 goto error;
551 sys->slCreateEnginePtr = dlsym(sys->p_so_handle, "slCreateEngine");
552 if (unlikely(sys->slCreateEnginePtr == NULL))
554 msg_Err(aout, "Failed to load symbol slCreateEngine");
555 goto error;
558 #define OPENSL_DLSYM(dest, name) \
559 do { \
560 const SLInterfaceID *sym = dlsym(sys->p_so_handle, "SL_IID_"name); \
561 if (unlikely(sym == NULL)) \
563 msg_Err(aout, "Failed to load symbol SL_IID_"name); \
564 goto error; \
566 sys->dest = *sym; \
567 } while(0)
569 OPENSL_DLSYM(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, "ANDROIDSIMPLEBUFFERQUEUE");
570 OPENSL_DLSYM(SL_IID_ENGINE, "ENGINE");
571 OPENSL_DLSYM(SL_IID_PLAY, "PLAY");
572 OPENSL_DLSYM(SL_IID_VOLUME, "VOLUME");
573 #undef OPENSL_DLSYM
575 // create engine
576 result = sys->slCreateEnginePtr(&sys->engineObject, 0, NULL, 0, NULL, NULL);
577 CHECK_OPENSL_ERROR("Failed to create engine");
579 // realize the engine in synchronous mode
580 result = Realize(sys->engineObject, SL_BOOLEAN_FALSE);
581 CHECK_OPENSL_ERROR("Failed to realize engine");
583 // get the engine interface, needed to create other objects
584 result = GetInterface(sys->engineObject, sys->SL_IID_ENGINE, &sys->engineEngine);
585 CHECK_OPENSL_ERROR("Failed to get the engine interface");
587 // create output mix, with environmental reverb specified as a non-required interface
588 const SLInterfaceID ids1[] = { sys->SL_IID_VOLUME };
589 const SLboolean req1[] = { SL_BOOLEAN_FALSE };
590 result = CreateOutputMix(sys->engineEngine, &sys->outputMixObject, 1, ids1, req1);
591 CHECK_OPENSL_ERROR("Failed to create output mix");
593 // realize the output mix in synchronous mode
594 result = Realize(sys->outputMixObject, SL_BOOLEAN_FALSE);
595 CHECK_OPENSL_ERROR("Failed to realize output mix");
597 vlc_mutex_init(&sys->lock);
599 aout->start = Start;
600 aout->stop = Stop;
601 aout->time_get = TimeGet;
602 aout->play = Play;
603 aout->pause = Pause;
604 aout->flush = Flush;
605 aout->mute_set = MuteSet;
606 aout->volume_set = VolumeSet;
608 return VLC_SUCCESS;
610 error:
611 if (sys->outputMixObject)
612 Destroy(sys->outputMixObject);
613 if (sys->engineObject)
614 Destroy(sys->engineObject);
615 if (sys->p_so_handle)
616 dlclose(sys->p_so_handle);
617 free(sys);
618 return VLC_EGENERIC;