]> git.sesse.net Git - vlc/blob - modules/audio_output/audiotrack.c
audiotrack: don't re-init to NULL
[vlc] / modules / audio_output / audiotrack.c
1 /*****************************************************************************
2  * audiotrack.c: Android Java AudioTrack audio output module
3  *****************************************************************************
4  * Copyright © 2012-2015 VLC authors and VideoLAN, VideoLabs
5  *
6  * Authors: Thomas Guillem <thomas@gllm.fr>
7  *          Ming Hu <tewilove@gmail.com>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include <assert.h>
29 #include <jni.h>
30 #include <dlfcn.h>
31 #include <stdbool.h>
32 #include <sys/queue.h>
33
34 #include <vlc_atomic.h>
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_aout.h>
38 #include <vlc_threads.h>
39
40 /* Maximum VLC buffers queued by the internal queue in microseconds. This delay
41  * doesn't include audiotrack delay */
42 #define MAX_QUEUE_US INT64_C(1000000) // 1000ms
43
44 static int  Open( vlc_object_t * );
45 static void Close( vlc_object_t * );
46 static void JNIThread_Stop( JNIEnv *env, audio_output_t *p_aout );
47
48 struct thread_cmd;
49 typedef TAILQ_HEAD(, thread_cmd) THREAD_CMD_QUEUE;
50
51 struct aout_sys_t {
52     /* sw gain */
53     float soft_gain;
54     bool soft_mute;
55
56     /* Owned by JNIThread */
57     jobject p_audiotrack; /* AudioTrack ref */
58     jobject p_audioTimestamp; /* AudioTimestamp ref */
59     jbyteArray p_bytearray; /* ByteArray ref (for Write) */
60     size_t i_bytearray_size; /* size of the ByteArray */
61     jobject p_bytebuffer; /* ByteBuffer ref (for WriteV21) */
62     audio_sample_format_t fmt; /* fmt setup by Start */
63     uint32_t i_pos_initial; /* initial position set by getPlaybackHeadPosition */
64     uint32_t i_samples_written; /* number of samples written since last flush */
65     uint32_t i_bytes_per_frame; /* byte per frame */
66     uint32_t i_max_audiotrack_samples;
67     mtime_t i_play_time; /* time when play was called */
68     bool b_audiotrack_exception; /* true if audiotrack throwed an exception */
69     int i_audiotrack_stuck_count;
70     uint8_t i_chans_to_reorder; /* do we need channel reordering */
71     uint8_t p_chan_table[AOUT_CHAN_MAX];
72
73     /* JNIThread control */
74     vlc_mutex_t mutex;
75     vlc_cond_t cond;
76     vlc_thread_t thread;
77
78     /* Shared between two threads, must be locked */
79     bool b_thread_run; /* is thread alive */
80     THREAD_CMD_QUEUE thread_cmd_queue; /* thread cmd queue */
81     uint32_t i_samples_queued; /* number of samples queued */
82 };
83
84 /* Soft volume helper */
85 #include "audio_output/volume.h"
86
87 //#define AUDIOTRACK_USE_FLOAT
88 // TODO: activate getTimestamp for new android versions
89 //#define AUDIOTRACK_USE_TIMESTAMP
90
91 vlc_module_begin ()
92     set_shortname( "AudioTrack" )
93     set_description( N_( "Android AudioTrack audio output" ) )
94     set_capability( "audio output", 180 )
95     set_category( CAT_AUDIO )
96     set_subcategory( SUBCAT_AUDIO_AOUT )
97     add_sw_gain()
98     add_shortcut( "audiotrack" )
99     set_callbacks( Open, Close )
100 vlc_module_end ()
101
102 struct thread_cmd
103 {
104     TAILQ_ENTRY(thread_cmd) next;
105     enum {
106         CMD_START,
107         CMD_STOP,
108         CMD_PLAY,
109         CMD_PAUSE,
110         CMD_TIME_GET,
111         CMD_FLUSH,
112         CMD_DONE,
113     } id;
114     union {
115         struct {
116             audio_sample_format_t *p_fmt;
117         } start;
118         struct {
119             block_t *p_buffer;
120         } play;
121         struct {
122             bool b_pause;
123             mtime_t i_date;
124         } pause;
125         struct {
126             bool b_wait;
127         } flush;
128     } in;
129     union {
130         struct {
131             int i_ret;
132             audio_sample_format_t *p_fmt;
133         } start;
134         struct {
135             int i_ret;
136             mtime_t i_delay;
137         } time_get;
138     } out;
139     void ( *pf_destroy )( struct thread_cmd * );
140 };
141
142 #define THREAD_NAME "android_audiotrack"
143
144 extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
145 extern void jni_detach_thread();
146 extern int jni_get_env(JNIEnv **env);
147
148 static struct
149 {
150     struct {
151         jclass clazz;
152         jmethodID ctor;
153         jmethodID release;
154         jmethodID getState;
155         jmethodID play;
156         jmethodID stop;
157         jmethodID flush;
158         jmethodID pause;
159         jmethodID write;
160         jmethodID writeV21;
161         jmethodID getPlaybackHeadPosition;
162         jmethodID getTimestamp;
163         jmethodID getMinBufferSize;
164         jint STATE_INITIALIZED;
165         jint MODE_STREAM;
166         jint ERROR;
167         jint ERROR_BAD_VALUE;
168         jint ERROR_INVALID_OPERATION;
169         jint WRITE_NON_BLOCKING;
170     } AudioTrack;
171     struct {
172         jint ENCODING_PCM_8BIT;
173         jint ENCODING_PCM_16BIT;
174         jint ENCODING_PCM_FLOAT;
175         bool has_ENCODING_PCM_FLOAT;
176         jint CHANNEL_OUT_MONO;
177         jint CHANNEL_OUT_STEREO;
178         jint CHANNEL_OUT_FRONT_LEFT;
179         jint CHANNEL_OUT_FRONT_RIGHT;
180         jint CHANNEL_OUT_BACK_LEFT;
181         jint CHANNEL_OUT_BACK_RIGHT;
182         jint CHANNEL_OUT_FRONT_CENTER;
183         jint CHANNEL_OUT_LOW_FREQUENCY;
184         jint CHANNEL_OUT_BACK_CENTER;
185         jint CHANNEL_OUT_5POINT1;
186         jint CHANNEL_OUT_SIDE_LEFT;
187         jint CHANNEL_OUT_SIDE_RIGHT;
188         bool has_CHANNEL_OUT_SIDE;
189     } AudioFormat;
190     struct {
191         jint ERROR_DEAD_OBJECT;
192         bool has_ERROR_DEAD_OBJECT;
193         jint STREAM_MUSIC;
194     } AudioManager;
195     struct {
196         jclass clazz;
197         jmethodID ctor;
198         jfieldID framePosition;
199         jfieldID nanoTime;
200     } AudioTimestamp;
201 } jfields;
202
203 /* init all jni fields.
204  * Done only one time during the first initialisation */
205 static bool
206 InitJNIFields( audio_output_t *p_aout )
207 {
208     static vlc_mutex_t lock = VLC_STATIC_MUTEX;
209     static int i_init_state = -1;
210     bool ret, b_attached = false;
211     jclass clazz;
212     jfieldID field;
213     JNIEnv* env = NULL;
214
215     vlc_mutex_lock( &lock );
216
217     if( i_init_state != -1 )
218         goto end;
219
220     if( jni_get_env(&env) < 0 )
221     {
222         jni_attach_thread( &env, THREAD_NAME );
223         if( !env )
224         {
225             i_init_state = 0;
226             goto end;
227         }
228         b_attached = true;
229     }
230
231 #define CHECK_EXCEPTION( what, critical ) do { \
232     if( (*env)->ExceptionOccurred( env ) ) \
233     { \
234         msg_Err( p_aout, "%s failed", what ); \
235         (*env)->ExceptionClear( env ); \
236         if( (critical) ) \
237         { \
238             i_init_state = 0; \
239             goto end; \
240         } \
241     } \
242 } while( 0 )
243 #define GET_CLASS( str, critical ) do { \
244     clazz = (*env)->FindClass( env, (str) ); \
245     CHECK_EXCEPTION( str, critical ); \
246 } while( 0 )
247 #define GET_ID( get, id, str, args, critical ) do { \
248     jfields.id = (*env)->get( env, clazz, (str), (args) ); \
249     CHECK_EXCEPTION( #get, critical ); \
250 } while( 0 )
251 #define GET_CONST_INT( id, str, critical ) do { \
252     field = NULL; \
253     field = (*env)->GetStaticFieldID( env, clazz, (str), "I" ); \
254     CHECK_EXCEPTION( #id, critical ); \
255     if( field ) \
256     { \
257         jfields.id = (*env)->GetStaticIntField( env, clazz, field ); \
258         CHECK_EXCEPTION( #id, critical ); \
259     } \
260 } while( 0 )
261
262     /* AudioTrack class init */
263     GET_CLASS( "android/media/AudioTrack", true );
264     jfields.AudioTrack.clazz = (jclass) (*env)->NewGlobalRef( env, clazz );
265     CHECK_EXCEPTION( "NewGlobalRef", true );
266
267     GET_ID( GetMethodID, AudioTrack.ctor, "<init>", "(IIIIII)V", true );
268     GET_ID( GetMethodID, AudioTrack.release, "release", "()V", true );
269     GET_ID( GetMethodID, AudioTrack.getState, "getState", "()I", true );
270     GET_ID( GetMethodID, AudioTrack.play, "play", "()V", true );
271     GET_ID( GetMethodID, AudioTrack.stop, "stop", "()V", true );
272     GET_ID( GetMethodID, AudioTrack.flush, "flush", "()V", true );
273     GET_ID( GetMethodID, AudioTrack.pause, "pause", "()V", true );
274
275     GET_ID( GetMethodID, AudioTrack.writeV21, "write", "(Ljava/nio/ByteBuffer;II)I", false );
276     if( jfields.AudioTrack.writeV21 )
277     {
278         GET_CONST_INT( AudioTrack.WRITE_NON_BLOCKING, "WRITE_NON_BLOCKING", true );
279     } else
280         GET_ID( GetMethodID, AudioTrack.write, "write", "([BII)I", true );
281
282     GET_ID( GetMethodID, AudioTrack.getTimestamp,
283             "getTimestamp", "(Landroid/media/AudioTimestamp;)Z", false );
284     GET_ID( GetMethodID, AudioTrack.getPlaybackHeadPosition,
285             "getPlaybackHeadPosition", "()I", true );
286
287     GET_ID( GetStaticMethodID, AudioTrack.getMinBufferSize, "getMinBufferSize",
288             "(III)I", true );
289     GET_CONST_INT( AudioTrack.STATE_INITIALIZED, "STATE_INITIALIZED", true );
290     GET_CONST_INT( AudioTrack.MODE_STREAM, "MODE_STREAM", true );
291     GET_CONST_INT( AudioTrack.ERROR, "ERROR", true );
292     GET_CONST_INT( AudioTrack.ERROR_BAD_VALUE , "ERROR_BAD_VALUE", true );
293     GET_CONST_INT( AudioTrack.ERROR_INVALID_OPERATION,
294                    "ERROR_INVALID_OPERATION", true );
295
296     /* AudioTimestamp class init (if any) */
297     if( jfields.AudioTrack.getTimestamp )
298     {
299         GET_CLASS( "android/media/AudioTimestamp", true );
300         jfields.AudioTimestamp.clazz = (jclass) (*env)->NewGlobalRef( env,
301                                                                       clazz );
302         CHECK_EXCEPTION( "NewGlobalRef", true );
303
304         GET_ID( GetMethodID, AudioTimestamp.ctor, "<init>", "()V", true );
305         GET_ID( GetFieldID, AudioTimestamp.framePosition,
306                 "framePosition", "J", true );
307         GET_ID( GetFieldID, AudioTimestamp.nanoTime,
308                 "nanoTime", "J", true );
309     }
310
311     /* AudioFormat class init */
312     GET_CLASS( "android/media/AudioFormat", true );
313     GET_CONST_INT( AudioFormat.ENCODING_PCM_8BIT, "ENCODING_PCM_8BIT", true );
314     GET_CONST_INT( AudioFormat.ENCODING_PCM_16BIT, "ENCODING_PCM_16BIT", true );
315 #ifdef AUDIOTRACK_USE_FLOAT
316     GET_CONST_INT( AudioFormat.ENCODING_PCM_FLOAT, "ENCODING_PCM_FLOAT",
317                    false );
318     jfields.AudioFormat.has_ENCODING_PCM_FLOAT = field != NULL;
319 #else
320     jfields.AudioFormat.has_ENCODING_PCM_FLOAT = false;
321 #endif
322     GET_CONST_INT( AudioFormat.CHANNEL_OUT_MONO, "CHANNEL_OUT_MONO", true );
323     GET_CONST_INT( AudioFormat.CHANNEL_OUT_STEREO, "CHANNEL_OUT_STEREO", true );
324     GET_CONST_INT( AudioFormat.CHANNEL_OUT_FRONT_LEFT, "CHANNEL_OUT_FRONT_LEFT", true );
325     GET_CONST_INT( AudioFormat.CHANNEL_OUT_FRONT_RIGHT, "CHANNEL_OUT_FRONT_RIGHT", true );
326     GET_CONST_INT( AudioFormat.CHANNEL_OUT_5POINT1, "CHANNEL_OUT_5POINT1", true );
327     GET_CONST_INT( AudioFormat.CHANNEL_OUT_BACK_LEFT, "CHANNEL_OUT_BACK_LEFT", true );
328     GET_CONST_INT( AudioFormat.CHANNEL_OUT_BACK_RIGHT, "CHANNEL_OUT_BACK_RIGHT", true );
329     GET_CONST_INT( AudioFormat.CHANNEL_OUT_FRONT_CENTER, "CHANNEL_OUT_FRONT_CENTER", true );
330     GET_CONST_INT( AudioFormat.CHANNEL_OUT_LOW_FREQUENCY, "CHANNEL_OUT_LOW_FREQUENCY", true );
331     GET_CONST_INT( AudioFormat.CHANNEL_OUT_BACK_CENTER, "CHANNEL_OUT_BACK_CENTER", true );
332     GET_CONST_INT( AudioFormat.CHANNEL_OUT_SIDE_LEFT, "CHANNEL_OUT_SIDE_LEFT", false );
333     if( field != NULL )
334     {
335         GET_CONST_INT( AudioFormat.CHANNEL_OUT_SIDE_RIGHT, "CHANNEL_OUT_SIDE_RIGHT", true );
336         jfields.AudioFormat.has_CHANNEL_OUT_SIDE = true;
337     } else
338         jfields.AudioFormat.has_CHANNEL_OUT_SIDE = false;
339
340     /* AudioManager class init */
341     GET_CLASS( "android/media/AudioManager", true );
342     GET_CONST_INT( AudioManager.ERROR_DEAD_OBJECT, "ERROR_DEAD_OBJECT", false );
343     jfields.AudioManager.has_ERROR_DEAD_OBJECT = field != NULL;
344     GET_CONST_INT( AudioManager.STREAM_MUSIC, "STREAM_MUSIC", true );
345
346 #undef CHECK_EXCEPTION
347 #undef GET_CLASS
348 #undef GET_ID
349 #undef GET_CONST_INT
350
351     i_init_state = 1;
352 end:
353     ret = i_init_state == 1;
354     if( !ret )
355         msg_Err( p_aout, "AudioTrack jni init failed" );
356     if( b_attached )
357         jni_detach_thread();
358     vlc_mutex_unlock( &lock );
359     return ret;
360 }
361
362 static inline bool
363 check_exception( JNIEnv *env, audio_output_t *p_aout,
364                  const char *method )
365 {
366     if( (*env)->ExceptionOccurred( env ) )
367     {
368         aout_sys_t *p_sys = p_aout->sys;
369
370         p_sys->b_audiotrack_exception = true;
371         (*env)->ExceptionClear( env );
372         msg_Err( p_aout, "AudioTrack.%s triggered an exception !", method );
373         return true;
374     } else
375         return false;
376 }
377 #define CHECK_AT_EXCEPTION( method ) check_exception( env, p_aout, method )
378
379 #define JNI_CALL( what, obj, method, ... ) (*env)->what( env, obj, method, ##__VA_ARGS__ )
380
381 #define JNI_CALL_INT( obj, method, ... ) JNI_CALL( CallIntMethod, obj, method, ##__VA_ARGS__ )
382 #define JNI_CALL_BOOL( obj, method, ... ) JNI_CALL( CallBooleanMethod, obj, method, ##__VA_ARGS__ )
383 #define JNI_CALL_VOID( obj, method, ... ) JNI_CALL( CallVoidMethod, obj, method, ##__VA_ARGS__ )
384 #define JNI_CALL_STATIC_INT( clazz, method, ... ) JNI_CALL( CallStaticIntMethod, clazz, method, ##__VA_ARGS__ )
385
386 #define JNI_AT_NEW( ... ) JNI_CALL( NewObject, jfields.AudioTrack.clazz, jfields.AudioTrack.ctor, ##__VA_ARGS__ )
387 #define JNI_AT_CALL_INT( method, ... ) JNI_CALL_INT( p_sys->p_audiotrack, jfields.AudioTrack.method, ##__VA_ARGS__ )
388 #define JNI_AT_CALL_BOOL( method, ... ) JNI_CALL_BOOL( p_sys->p_audiotrack, jfields.AudioTrack.method, ##__VA_ARGS__ )
389 #define JNI_AT_CALL_VOID( method, ... ) JNI_CALL_VOID( p_sys->p_audiotrack, jfields.AudioTrack.method, ##__VA_ARGS__ )
390 #define JNI_AT_CALL_STATIC_INT( method, ... ) JNI_CALL( CallStaticIntMethod, jfields.AudioTrack.clazz, jfields.AudioTrack.method, ##__VA_ARGS__ )
391
392 #define JNI_AUDIOTIMESTAMP_GET_LONG( field ) JNI_CALL( GetLongField, p_sys->p_audioTimestamp, jfields.AudioTimestamp.field )
393
394 static inline mtime_t
395 frames_to_us( aout_sys_t *p_sys, uint32_t i_nb_frames )
396 {
397     return  i_nb_frames * CLOCK_FREQ / p_sys->fmt.i_rate;
398 }
399 #define FRAMES_TO_US(x) frames_to_us( p_sys, (x) )
400
401 static struct thread_cmd *
402 ThreadCmd_New( int id )
403 {
404     struct thread_cmd *p_cmd = calloc( 1, sizeof(struct thread_cmd) );
405
406     if( p_cmd )
407         p_cmd->id = id;
408
409     return p_cmd;
410 }
411
412 static void
413 ThreadCmd_InsertHead( aout_sys_t *p_sys, struct thread_cmd *p_cmd )
414 {
415     TAILQ_INSERT_HEAD( &p_sys->thread_cmd_queue, p_cmd, next);
416     vlc_cond_signal( &p_sys->cond );
417 }
418
419 static void
420 ThreadCmd_InsertTail( aout_sys_t *p_sys, struct thread_cmd *p_cmd )
421 {
422     TAILQ_INSERT_TAIL( &p_sys->thread_cmd_queue, p_cmd, next);
423     vlc_cond_signal( &p_sys->cond );
424 }
425
426 static bool
427 ThreadCmd_Wait( aout_sys_t *p_sys, struct thread_cmd *p_cmd )
428 {
429     while( p_cmd->id != CMD_DONE )
430         vlc_cond_wait( &p_sys->cond, &p_sys->mutex );
431
432     return p_cmd->id == CMD_DONE;
433 }
434
435 static void
436 ThreadCmd_FlushQueue( aout_sys_t *p_sys )
437 {
438     struct thread_cmd *p_cmd, *p_cmd_next;
439
440     for ( p_cmd = TAILQ_FIRST( &p_sys->thread_cmd_queue );
441           p_cmd != NULL; p_cmd = p_cmd_next )
442     {
443         p_cmd_next = TAILQ_NEXT( p_cmd, next );
444         TAILQ_REMOVE( &p_sys->thread_cmd_queue, p_cmd, next );
445         if( p_cmd->pf_destroy )
446             p_cmd->pf_destroy( p_cmd );
447     }
448 }
449
450 static void
451 JNIThread_InitDelay( JNIEnv *env, audio_output_t *p_aout )
452 {
453     aout_sys_t *p_sys = p_aout->sys;
454
455     if( p_sys->p_audiotrack )
456         p_sys->i_pos_initial = JNI_AT_CALL_INT( getPlaybackHeadPosition );
457     else
458         p_sys->i_pos_initial = 0;
459
460     /* HACK: On some broken devices, head position is still moving after a
461      * flush or a stop. So, wait for the head position to be stabilized. */
462     if( unlikely( p_sys->i_pos_initial != 0 ) )
463     {
464         uint32_t i_last_pos;
465         do {
466             i_last_pos = p_sys->i_pos_initial;
467             msleep( 50000 );
468             p_sys->i_pos_initial = JNI_AT_CALL_INT( getPlaybackHeadPosition );
469         } while( p_sys->i_pos_initial != i_last_pos );
470     }
471     p_sys->i_samples_written = 0;
472     p_sys->i_samples_queued = 0;
473 }
474
475 static uint32_t
476 JNIThread_GetAudioTrackPos( JNIEnv *env, audio_output_t *p_aout )
477 {
478     aout_sys_t *p_sys = p_aout->sys;
479
480     /* Android doc:
481      * getPlaybackHeadPosition: Returns the playback head position expressed in
482      * frames. Though the "int" type is signed 32-bits, the value should be
483      * reinterpreted as if it is unsigned 32-bits. That is, the next position
484      * after 0x7FFFFFFF is (int) 0x80000000. This is a continuously advancing
485      * counter. It will wrap (overflow) periodically, for example approximately
486      * once every 27:03:11 hours:minutes:seconds at 44.1 kHz. It is reset to
487      * zero by flush(), reload(), and stop().
488      */
489
490     return JNI_AT_CALL_INT( getPlaybackHeadPosition ) - p_sys->i_pos_initial;
491 }
492
493 static int
494 JNIThread_TimeGet( JNIEnv *env, audio_output_t *p_aout, mtime_t *p_delay )
495 {
496     aout_sys_t *p_sys = p_aout->sys;
497     jlong i_frame_pos;
498     uint32_t i_audiotrack_delay = 0;
499
500     if( p_sys->i_samples_queued == 0 )
501         return -1;
502     if( p_sys->p_audioTimestamp )
503     {
504         mtime_t i_current_time = mdate();
505         /* Android doc:
506          * getTimestamp: Poll for a timestamp on demand.
507          *
508          * If you need to track timestamps during initial warmup or after a
509          * routing or mode change, you should request a new timestamp once per
510          * second until the reported timestamps show that the audio clock is
511          * stable. Thereafter, query for a new timestamp approximately once
512          * every 10 seconds to once per minute. Calling this method more often
513          * is inefficient. It is also counter-productive to call this method
514          * more often than recommended, because the short-term differences
515          * between successive timestamp reports are not meaningful. If you need
516          * a high-resolution mapping between frame position and presentation
517          * time, consider implementing that at application level, based on
518          * low-resolution timestamps.
519          */
520
521         if( JNI_AT_CALL_BOOL( getTimestamp, p_sys->p_audioTimestamp ) )
522         {
523             jlong i_frame_time = JNI_AUDIOTIMESTAMP_GET_LONG( nanoTime ) / 1000;
524             /* frame time should be after last play time
525              * frame time shouldn't be in the future
526              * frame time should be less than 10 seconds old */
527             if( i_frame_time > p_sys->i_play_time
528                 && i_current_time > i_frame_time
529                 && ( i_current_time - i_frame_time ) <= INT64_C(10000000) )
530             {
531                 jlong i_time_diff = i_current_time - i_frame_time;
532                 jlong i_frames_diff = i_time_diff *  p_sys->fmt.i_rate
533                                       / CLOCK_FREQ;
534                 i_frame_pos = JNI_AUDIOTIMESTAMP_GET_LONG( framePosition )
535                               + i_frames_diff;
536                 if( p_sys->i_samples_written > i_frame_pos )
537                     i_audiotrack_delay =  p_sys->i_samples_written - i_frame_pos;
538             }
539         }
540     }
541     if( i_audiotrack_delay == 0 )
542     {
543         uint32_t i_audiotrack_pos = JNIThread_GetAudioTrackPos( env, p_aout );
544
545         if( p_sys->i_samples_written > i_audiotrack_pos )
546             i_audiotrack_delay = p_sys->i_samples_written - i_audiotrack_pos;
547     }
548
549     if( i_audiotrack_delay > 0 )
550     {
551         *p_delay = FRAMES_TO_US( p_sys->i_samples_queued + i_audiotrack_delay );
552         return 0;
553     } else
554         return -1;
555 }
556
557 static void
558 AudioTrack_GetChanOrder( uint16_t i_physical_channels, uint32_t p_chans_out[] )
559 {
560 #define HAS_CHAN( x ) ( ( i_physical_channels & (x) ) == (x) )
561     /* samples will be in the following order: FL FR FC LFE BL BR BC SL SR */
562     int i = 0;
563
564     if( HAS_CHAN( AOUT_CHAN_LEFT ) )
565         p_chans_out[i++] = AOUT_CHAN_LEFT;
566     if( HAS_CHAN( AOUT_CHAN_RIGHT ) )
567         p_chans_out[i++] = AOUT_CHAN_RIGHT;
568
569     if( HAS_CHAN( AOUT_CHAN_CENTER ) )
570         p_chans_out[i++] = AOUT_CHAN_CENTER;
571
572     if( HAS_CHAN( AOUT_CHAN_LFE ) )
573         p_chans_out[i++] = AOUT_CHAN_LFE;
574
575     if( HAS_CHAN( AOUT_CHAN_REARLEFT ) )
576         p_chans_out[i++] = AOUT_CHAN_REARLEFT;
577     if( HAS_CHAN( AOUT_CHAN_REARRIGHT ) )
578         p_chans_out[i++] = AOUT_CHAN_REARRIGHT;
579
580     if( HAS_CHAN( AOUT_CHAN_REARCENTER ) )
581         p_chans_out[i++] = AOUT_CHAN_REARCENTER;
582
583     if( HAS_CHAN( AOUT_CHAN_MIDDLELEFT ) )
584         p_chans_out[i++] = AOUT_CHAN_MIDDLELEFT;
585     if( HAS_CHAN( AOUT_CHAN_MIDDLERIGHT ) )
586         p_chans_out[i++] = AOUT_CHAN_MIDDLERIGHT;
587
588     assert( i <= AOUT_CHAN_MAX );
589 #undef HAS_CHAN
590 }
591
592 /**
593  * Configure and create an Android AudioTrack.
594  * returns NULL on configuration error
595  */
596 static jobject
597 JNIThread_NewAudioTrack( JNIEnv *env, audio_output_t *p_aout,
598                          unsigned int i_rate,
599                          vlc_fourcc_t i_vlc_format,
600                          uint16_t i_physical_channels,
601                          int *p_audiotrack_size )
602 {
603     int i_size, i_min_buffer_size, i_channel_config, i_format;
604     jobject p_audiotrack;
605
606     switch( i_vlc_format )
607     {
608         case VLC_CODEC_U8:
609             i_format = jfields.AudioFormat.ENCODING_PCM_8BIT;
610             break;
611         case VLC_CODEC_S16N:
612             i_format = jfields.AudioFormat.ENCODING_PCM_16BIT;
613             break;
614         case VLC_CODEC_FL32:
615             i_format = jfields.AudioFormat.ENCODING_PCM_FLOAT;
616             break;
617         default:
618             vlc_assert_unreachable();
619     }
620
621     switch( i_physical_channels )
622     {
623         case AOUT_CHANS_7_1:
624             /* bitmask of CHANNEL_OUT_7POINT1 doesn't correspond to 5POINT1 and
625              * SIDES */
626             i_channel_config = jfields.AudioFormat.CHANNEL_OUT_5POINT1 |
627                                jfields.AudioFormat.CHANNEL_OUT_SIDE_LEFT |
628                                jfields.AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
629             break;
630         case AOUT_CHANS_5_1:
631             i_channel_config = jfields.AudioFormat.CHANNEL_OUT_5POINT1;
632             break;
633         case AOUT_CHAN_LEFT:
634             i_channel_config = jfields.AudioFormat.CHANNEL_OUT_MONO;
635             break;
636         default:
637         case AOUT_CHANS_STEREO:
638             i_channel_config = jfields.AudioFormat.CHANNEL_OUT_STEREO;
639             break;
640     }
641
642     i_min_buffer_size = JNI_AT_CALL_STATIC_INT( getMinBufferSize, i_rate,
643                                                 i_channel_config, i_format );
644     if( i_min_buffer_size <= 0 )
645     {
646         msg_Warn( p_aout, "getMinBufferSize returned an invalid size" ) ;
647         return NULL;
648     }
649     i_size = i_min_buffer_size * 4;
650
651     /* create AudioTrack object */
652     p_audiotrack = JNI_AT_NEW( jfields.AudioManager.STREAM_MUSIC, i_rate,
653                                i_channel_config, i_format, i_size,
654                                jfields.AudioTrack.MODE_STREAM );
655     if( CHECK_AT_EXCEPTION( "AudioTrack<init>" ) || !p_audiotrack )
656     {
657         msg_Warn( p_aout, "AudioTrack Init failed" ) ;
658         return NULL;
659     }
660     if( JNI_CALL_INT( p_audiotrack, jfields.AudioTrack.getState )
661         != jfields.AudioTrack.STATE_INITIALIZED )
662     {
663         JNI_CALL_VOID( p_audiotrack, jfields.AudioTrack.release );
664         (*env)->DeleteLocalRef( env, p_audiotrack );
665         msg_Err( p_aout, "AudioTrack getState failed" );
666         return NULL;
667     }
668     *p_audiotrack_size = i_size;
669
670     return p_audiotrack;
671 }
672
673 static int
674 JNIThread_Start( JNIEnv *env, audio_output_t *p_aout )
675 {
676     aout_sys_t *p_sys = p_aout->sys;
677     jobject p_audiotrack = NULL;
678     int i_nb_channels, i_audiotrack_size;
679     uint32_t p_chans_out[AOUT_CHAN_MAX];
680
681     aout_FormatPrint( p_aout, "VLC is looking for:", &p_sys->fmt );
682
683     p_sys->fmt.i_original_channels = p_sys->fmt.i_physical_channels;
684
685     /* 4000 <= frequency <= 48000 */
686     p_sys->fmt.i_rate = VLC_CLIP( p_sys->fmt.i_rate, 4000, 48000 );
687
688     /* We can only accept U8, S16N, FL32, and AC3 */
689     switch( p_sys->fmt.i_format )
690     {
691         case VLC_CODEC_U8:
692             break;
693         case VLC_CODEC_S16N:
694             break;
695         case VLC_CODEC_FL32:
696             if( !jfields.AudioFormat.has_ENCODING_PCM_FLOAT )
697                 p_sys->fmt.i_format = VLC_CODEC_S16N;
698             break;
699         default:
700             p_sys->fmt.i_format = VLC_CODEC_S16N;
701             break;
702     }
703
704     /* Android AudioTrack supports only mono, stereo, 5.1 and 7.1.
705      * Android will downmix to stereo if audio output doesn't handle 5.1 or 7.1
706      */
707     i_nb_channels = aout_FormatNbChannels( &p_sys->fmt );
708     if( i_nb_channels > 5 )
709     {
710         if( i_nb_channels > 7 && jfields.AudioFormat.has_CHANNEL_OUT_SIDE )
711             p_sys->fmt.i_physical_channels = AOUT_CHANS_7_1;
712         else
713             p_sys->fmt.i_physical_channels = AOUT_CHANS_5_1;
714     } else
715     {
716         if( i_nb_channels == 1 )
717             p_sys->fmt.i_physical_channels = AOUT_CHAN_LEFT;
718         else
719             p_sys->fmt.i_physical_channels = AOUT_CHANS_STEREO;
720     }
721     i_nb_channels = aout_FormatNbChannels( &p_sys->fmt );
722
723     do
724     {
725         /* Try to create an AudioTrack with the most advanced channel and
726          * format configuration. If NewAudioTrack fails, try again with a less
727          * advanced format (PCM S16N). If it fails again, try again with Stereo
728          * channels. */
729         p_audiotrack = JNIThread_NewAudioTrack( env, p_aout, p_sys->fmt.i_rate,
730                                                 p_sys->fmt.i_format,
731                                                 p_sys->fmt.i_physical_channels,
732                                                 &i_audiotrack_size );
733         if( !p_audiotrack )
734         {
735             if( p_sys->fmt.i_format == VLC_CODEC_FL32 )
736             {
737                 msg_Warn( p_aout, "FL32 configuration failed, "
738                                   "fallback to S16N PCM" );
739                 p_sys->fmt.i_format = VLC_CODEC_S16N;
740             }
741             else if( i_nb_channels > 5 )
742             {
743                 msg_Warn( p_aout, "5.1 or 7.1 configuration failed, "
744                                   "fallback to Stereo" );
745                 p_sys->fmt.i_physical_channels = AOUT_CHANS_STEREO;
746                 i_nb_channels = aout_FormatNbChannels( &p_sys->fmt );
747             }
748             else
749                 break;
750         }
751     } while( !p_audiotrack );
752
753     if( !p_audiotrack )
754         return VLC_EGENERIC;
755
756     p_sys->p_audiotrack = (*env)->NewGlobalRef( env, p_audiotrack );
757     (*env)->DeleteLocalRef( env, p_audiotrack );
758     if( !p_sys->p_audiotrack )
759         return VLC_EGENERIC;
760
761     memset( p_chans_out, 0, sizeof(p_chans_out) );
762     AudioTrack_GetChanOrder( p_sys->fmt.i_physical_channels, p_chans_out );
763     p_sys->i_chans_to_reorder =
764         aout_CheckChannelReorder( NULL, p_chans_out,
765                                   p_sys->fmt.i_physical_channels,
766                                   p_sys->p_chan_table );
767
768     p_sys->i_bytes_per_frame = i_nb_channels *
769                                aout_BitsPerSample( p_sys->fmt.i_format ) /
770                                8;
771     p_sys->i_max_audiotrack_samples = i_audiotrack_size /
772                                       p_sys->i_bytes_per_frame;
773
774 #ifdef AUDIOTRACK_USE_TIMESTAMP
775     if( jfields.AudioTimestamp.clazz )
776     {
777         /* create AudioTimestamp object */
778         jobject p_audioTimestamp = JNI_CALL( NewObject,
779                                              jfields.AudioTimestamp.clazz,
780                                              jfields.AudioTimestamp.ctor );
781         if( !p_audioTimestamp )
782         {
783             JNIThread_Stop( env, p_aout );
784             return VLC_EGENERIC;
785         }
786         p_sys->p_audioTimestamp = (*env)->NewGlobalRef( env, p_audioTimestamp );
787         (*env)->DeleteLocalRef( env, p_audioTimestamp );
788         if( !p_sys->p_audioTimestamp )
789         {
790             JNIThread_Stop( env, p_aout );
791             return VLC_EGENERIC;
792         }
793     }
794 #endif
795
796     JNI_AT_CALL_VOID( play );
797     CHECK_AT_EXCEPTION( "play" );
798     p_sys->i_play_time = mdate();
799
800     aout_FormatPrint( p_aout, "VLC will output:", &p_sys->fmt );
801
802     return VLC_SUCCESS;
803 }
804
805 static void
806 JNIThread_Stop( JNIEnv *env, audio_output_t *p_aout )
807 {
808     aout_sys_t *p_sys = p_aout->sys;
809
810     if( p_sys->p_audiotrack )
811     {
812         if( !p_sys->b_audiotrack_exception )
813         {
814             JNI_AT_CALL_VOID( stop );
815             if( !CHECK_AT_EXCEPTION( "stop" ) )
816                 JNI_AT_CALL_VOID( release );
817         }
818         (*env)->DeleteGlobalRef( env, p_sys->p_audiotrack );
819         p_sys->p_audiotrack = NULL;
820     }
821     p_sys->b_audiotrack_exception = false;
822
823     if( p_sys->p_audioTimestamp )
824     {
825         (*env)->DeleteGlobalRef( env, p_sys->p_audioTimestamp );
826         p_sys->p_audioTimestamp = NULL;
827     }
828 }
829
830 /**
831  * Non blocking write function.
832  * Do a calculation between current position and audiotrack position and assure
833  * that we won't wait in AudioTrack.write() method
834  */
835 static int
836 JNIThread_Write( JNIEnv *env, audio_output_t *p_aout, block_t *p_buffer )
837 {
838     aout_sys_t *p_sys = p_aout->sys;
839     uint8_t *p_data = p_buffer->p_buffer;
840     size_t i_data;
841     uint32_t i_samples;
842     uint32_t i_audiotrack_pos;
843     uint32_t i_samples_pending;
844
845     i_audiotrack_pos = JNIThread_GetAudioTrackPos( env, p_aout );
846     if( i_audiotrack_pos > p_sys->i_samples_written )
847     {
848         msg_Warn( p_aout, "audiotrack position is ahead. Should NOT happen" );
849         JNIThread_InitDelay( env, p_aout );
850         return 0;
851     }
852     i_samples_pending = p_sys->i_samples_written - i_audiotrack_pos;
853
854     /* check if audiotrack buffer is not full before writing on it. */
855     if( i_samples_pending >= p_sys->i_max_audiotrack_samples )
856     {
857
858         /* HACK: AudioFlinger can drop frames without notifying us and there is
859          * no way to know it. It it happens, i_audiotrack_pos won't move and
860          * the current code will be stuck because it'll assume that audiotrack
861          * internal buffer is full when it's not. It can happen only after
862          * Android 4.4.2 if we send frames too quickly. This HACK is just an
863          * other precaution since it shouldn't happen anymore thanks to the
864          * HACK in JNIThread_Play */
865
866         p_sys->i_audiotrack_stuck_count++;
867         if( p_sys->i_audiotrack_stuck_count > 100 )
868         {
869             msg_Warn( p_aout, "AudioFlinger underrun, force write" );
870             i_samples_pending = 0;
871             p_sys->i_audiotrack_stuck_count = 0;
872         }
873     } else
874         p_sys->i_audiotrack_stuck_count = 0;
875     i_samples = __MIN( p_sys->i_max_audiotrack_samples - i_samples_pending,
876                        p_buffer->i_nb_samples );
877
878     i_data = i_samples * p_sys->i_bytes_per_frame;
879
880     /* check if we need to realloc a ByteArray */
881     if( i_data > p_sys->i_bytearray_size )
882     {
883         jbyteArray p_bytearray;
884
885         if( p_sys->p_bytearray )
886         {
887             (*env)->DeleteGlobalRef( env, p_sys->p_bytearray );
888             p_sys->p_bytearray = NULL;
889         }
890
891         p_bytearray = (*env)->NewByteArray( env, i_data );
892         if( p_bytearray )
893         {
894             p_sys->p_bytearray = (*env)->NewGlobalRef( env, p_bytearray );
895             (*env)->DeleteLocalRef( env, p_bytearray );
896         }
897         p_sys->i_bytearray_size = i_data;
898     }
899     if( !p_sys->p_bytearray )
900         return jfields.AudioTrack.ERROR_BAD_VALUE;
901
902     /* copy p_buffer in to ByteArray */
903     (*env)->SetByteArrayRegion( env, p_sys->p_bytearray, 0, i_data,
904                                 (jbyte *)p_data);
905
906     return JNI_AT_CALL_INT( write, p_sys->p_bytearray, 0, i_data );
907 }
908
909 /**
910  * Non blocking write function for Lollipop and after.
911  * It calls a new write method with WRITE_NON_BLOCKING flags.
912  */
913 static int
914 JNIThread_WriteV21( JNIEnv *env, audio_output_t *p_aout, block_t *p_buffer )
915 {
916     aout_sys_t *p_sys = p_aout->sys;
917     int i_ret;
918
919     if( !p_sys->p_bytebuffer )
920     {
921         jobject p_bytebuffer;
922
923         p_bytebuffer = (*env)->NewDirectByteBuffer( env, p_buffer->p_buffer,
924                                                     p_buffer->i_buffer );
925         if( !p_bytebuffer )
926             return jfields.AudioTrack.ERROR_BAD_VALUE;
927
928         p_sys->p_bytebuffer = (*env)->NewGlobalRef( env, p_bytebuffer );
929         (*env)->DeleteLocalRef( env, p_bytebuffer );
930
931         if( !p_sys->p_bytebuffer || (*env)->ExceptionOccurred( env ) )
932         {
933             p_sys->p_bytebuffer = NULL;
934             (*env)->ExceptionClear( env );
935             return jfields.AudioTrack.ERROR_BAD_VALUE;
936         }
937     }
938
939     i_ret = JNI_AT_CALL_INT( writeV21, p_sys->p_bytebuffer, p_buffer->i_buffer,
940                              jfields.AudioTrack.WRITE_NON_BLOCKING );
941     if( i_ret > 0 )
942     {
943         /* don't delete the bytebuffer if we wrote nothing, keep it for next
944          * call */
945         (*env)->DeleteGlobalRef( env, p_sys->p_bytebuffer );
946         p_sys->p_bytebuffer = NULL;
947     }
948     return i_ret;
949 }
950
951 static int
952 JNIThread_Play( JNIEnv *env, audio_output_t *p_aout,
953                 block_t **pp_buffer, mtime_t *p_wait )
954 {
955     aout_sys_t *p_sys = p_aout->sys;
956     block_t *p_buffer = *pp_buffer;
957     int i_ret;
958
959     if( jfields.AudioTrack.writeV21 )
960         i_ret = JNIThread_WriteV21( env, p_aout, p_buffer );
961     else
962         i_ret = JNIThread_Write( env, p_aout, p_buffer );
963
964     if( i_ret < 0 ) {
965         if( jfields.AudioManager.has_ERROR_DEAD_OBJECT
966             && i_ret == jfields.AudioManager.ERROR_DEAD_OBJECT )
967         {
968             msg_Warn( p_aout, "ERROR_DEAD_OBJECT: "
969                               "try recreating AudioTrack" );
970             JNIThread_Stop( env, p_aout );
971             i_ret = JNIThread_Start( env, p_aout );
972         } else
973         {
974             const char *str;
975             if( i_ret == jfields.AudioTrack.ERROR_INVALID_OPERATION )
976                 str = "ERROR_INVALID_OPERATION";
977             else if( i_ret == jfields.AudioTrack.ERROR_BAD_VALUE )
978                 str = "ERROR_BAD_VALUE";
979             else
980                 str = "ERROR";
981             msg_Err( p_aout, "Write failed: %s", str );
982         }
983     } else if( i_ret == 0 )
984     {
985         /* audiotrack internal buffer is full, wait a little: between 10ms and
986          * 20ms depending on devices or rate */
987         *p_wait = FRAMES_TO_US( p_sys->i_max_audiotrack_samples / 20 );
988     } else
989     {
990         uint32_t i_samples = i_ret / p_sys->i_bytes_per_frame;
991         p_sys->i_samples_queued -= i_samples;
992         p_sys->i_samples_written += i_samples;
993
994         p_buffer->p_buffer += i_ret;
995         p_buffer->i_buffer -= i_ret;
996         p_buffer->i_nb_samples -= i_samples;
997         if( p_buffer->i_buffer == 0 )
998             *pp_buffer = NULL;
999
1000         /* HACK: There is a known issue in audiotrack, "due to an internal
1001          * timeout within the AudioTrackThread". It happens after android
1002          * 4.4.2, it's not a problem for Android 5.0 since we use an other way
1003          * to write samples. A working hack is to wait a little between each
1004          * write. This hack is done only for API 19 (AudioTimestamp was added
1005          * in API 19). */
1006
1007         if( jfields.AudioTimestamp.clazz && !jfields.AudioTrack.writeV21 )
1008             *p_wait = FRAMES_TO_US( i_samples ) / 2;
1009     }
1010     return i_ret >= 0 ? VLC_SUCCESS : VLC_EGENERIC;
1011 }
1012
1013 static void
1014 JNIThread_Pause( JNIEnv *env, audio_output_t *p_aout,
1015                  bool b_pause, mtime_t i_date )
1016 {
1017     VLC_UNUSED( i_date );
1018
1019     aout_sys_t *p_sys = p_aout->sys;
1020
1021     if( b_pause )
1022     {
1023         JNI_AT_CALL_VOID( pause );
1024         CHECK_AT_EXCEPTION( "pause" );
1025     } else
1026     {
1027         JNI_AT_CALL_VOID( play );
1028         CHECK_AT_EXCEPTION( "play" );
1029         p_sys->i_play_time = mdate();
1030     }
1031 }
1032
1033 static void
1034 JNIThread_Flush( JNIEnv *env, audio_output_t *p_aout,
1035                  bool b_wait )
1036 {
1037     aout_sys_t *p_sys = p_aout->sys;
1038
1039     /* Android doc:
1040      * stop(): Stops playing the audio data. When used on an instance created
1041      * in MODE_STREAM mode, audio will stop playing after the last buffer that
1042      * was written has been played. For an immediate stop, use pause(),
1043      * followed by flush() to discard audio data that hasn't been played back
1044      * yet.
1045      *
1046      * flush(): Flushes the audio data currently queued for playback. Any data
1047      * that has not been played back will be discarded.  No-op if not stopped
1048      * or paused, or if the track's creation mode is not MODE_STREAM.
1049      */
1050     if( b_wait )
1051     {
1052         JNI_AT_CALL_VOID( stop );
1053         if( CHECK_AT_EXCEPTION( "stop" ) )
1054             return;
1055     } else
1056     {
1057         JNI_AT_CALL_VOID( pause );
1058         if( CHECK_AT_EXCEPTION( "pause" ) )
1059             return;
1060         JNI_AT_CALL_VOID( flush );
1061     }
1062     JNI_AT_CALL_VOID( play );
1063     CHECK_AT_EXCEPTION( "play" );
1064     p_sys->i_play_time = mdate();
1065
1066     if( p_sys->p_bytebuffer )
1067     {
1068         (*env)->DeleteGlobalRef( env, p_sys->p_bytebuffer );
1069         p_sys->p_bytebuffer = NULL;
1070     }
1071 }
1072
1073 static void *
1074 JNIThread( void *data )
1075 {
1076     audio_output_t *p_aout = data;
1077     aout_sys_t *p_sys = p_aout->sys;
1078     bool b_error = false;
1079     bool b_paused = false;
1080     block_t *p_buffer = NULL;
1081     mtime_t i_play_deadline = 0;
1082     JNIEnv* env;
1083
1084     jni_attach_thread( &env, THREAD_NAME );
1085
1086     vlc_mutex_lock( &p_sys->mutex );
1087     if( !env )
1088         goto end;
1089
1090     while( p_sys->b_thread_run )
1091     {
1092         struct thread_cmd *p_cmd;
1093         bool b_remove_cmd = true;
1094
1095         /* wait to process a command */
1096         while( ( p_cmd = TAILQ_FIRST( &p_sys->thread_cmd_queue ) ) == NULL
1097                && p_sys->b_thread_run )
1098             vlc_cond_wait( &p_sys->cond, &p_sys->mutex );
1099
1100         if( !p_sys->b_thread_run || p_cmd == NULL )
1101             break;
1102
1103         if( b_paused && p_cmd->id == CMD_PLAY )
1104         {
1105             vlc_cond_wait( &p_sys->cond, &p_sys->mutex );
1106             continue;
1107         }
1108
1109         if( p_cmd->id == CMD_PLAY && i_play_deadline > 0 )
1110         {
1111             if( mdate() > i_play_deadline )
1112                 i_play_deadline = 0;
1113             else
1114             {
1115                 int i_ret = 0;
1116                 while( p_cmd == TAILQ_FIRST( &p_sys->thread_cmd_queue )
1117                        && i_ret != ETIMEDOUT && p_sys->b_thread_run )
1118                     i_ret = vlc_cond_timedwait( &p_sys->cond, &p_sys->mutex,
1119                                                 i_play_deadline );
1120                 continue;
1121             }
1122         }
1123
1124         /* process a command */
1125         switch( p_cmd->id )
1126         {
1127             case CMD_START:
1128                 assert( !p_sys->p_audiotrack );
1129                 if( b_error ) {
1130                     p_cmd->out.start.i_ret = -1;
1131                     break;
1132                 }
1133                 p_sys->fmt = *p_cmd->in.start.p_fmt;
1134                 p_cmd->out.start.i_ret =
1135                         JNIThread_Start( env, p_aout );
1136                 JNIThread_InitDelay( env, p_aout );
1137                 p_cmd->out.start.p_fmt = &p_sys->fmt;
1138                 b_paused = false;
1139                 break;
1140             case CMD_STOP:
1141                 assert( p_sys->p_audiotrack );
1142                 JNIThread_Stop( env, p_aout );
1143                 JNIThread_InitDelay( env, p_aout );
1144                 b_paused = false;
1145                 b_error = false;
1146                 p_buffer = NULL;
1147                 break;
1148             case CMD_PLAY:
1149             {
1150                 mtime_t i_play_wait = 0;
1151
1152                 assert( p_sys->p_audiotrack );
1153                 if( b_error )
1154                     break;
1155                 if( p_buffer == NULL )
1156                 {
1157                     p_buffer = p_cmd->in.play.p_buffer;
1158                     if( p_sys->i_chans_to_reorder )
1159                        aout_ChannelReorder( p_buffer->p_buffer,
1160                                             p_buffer->i_buffer,
1161                                             p_sys->i_chans_to_reorder,
1162                                             p_sys->p_chan_table,
1163                                             p_sys->fmt.i_format );
1164
1165                 }
1166                 b_error = JNIThread_Play( env, p_aout, &p_buffer,
1167                                           &i_play_wait ) != VLC_SUCCESS;
1168                 if( p_buffer != NULL )
1169                     b_remove_cmd = false;
1170                 if( i_play_wait > 0 )
1171                     i_play_deadline = mdate() + i_play_wait;
1172                 break;
1173             }
1174             case CMD_PAUSE:
1175                 assert( p_sys->p_audiotrack );
1176                 if( b_error )
1177                     break;
1178                 JNIThread_Pause( env, p_aout,
1179                                  p_cmd->in.pause.b_pause,
1180                                  p_cmd->in.pause.i_date );
1181                 b_paused = p_cmd->in.pause.b_pause;
1182                 break;
1183             case CMD_TIME_GET:
1184                 assert( p_sys->p_audiotrack );
1185                 if( b_error )
1186                     break;
1187                 p_cmd->out.time_get.i_ret =
1188                         JNIThread_TimeGet( env, p_aout,
1189                                            &p_cmd->out.time_get.i_delay );
1190                 break;
1191             case CMD_FLUSH:
1192                 assert( p_sys->p_audiotrack );
1193                 if( b_error )
1194                     break;
1195                 JNIThread_Flush( env, p_aout,
1196                                  p_cmd->in.flush.b_wait );
1197                 JNIThread_InitDelay( env, p_aout );
1198                 p_buffer = NULL;
1199                 break;
1200             default:
1201                 vlc_assert_unreachable();
1202         }
1203         if( p_sys->b_audiotrack_exception )
1204             b_error = true;
1205
1206         if( b_remove_cmd )
1207         {
1208             TAILQ_REMOVE( &p_sys->thread_cmd_queue, p_cmd, next );
1209             p_cmd->id = CMD_DONE;
1210             if( p_cmd->pf_destroy )
1211                 p_cmd->pf_destroy( p_cmd );
1212         }
1213
1214         /* signal that command is processed */
1215         vlc_cond_signal( &p_sys->cond );
1216     }
1217 end:
1218     if( env )
1219     {
1220         if( p_sys->p_bytearray )
1221             (*env)->DeleteGlobalRef( env, p_sys->p_bytearray );
1222         if( p_sys->p_bytebuffer )
1223             (*env)->DeleteGlobalRef( env, p_sys->p_bytebuffer );
1224         jni_detach_thread();
1225     }
1226     vlc_mutex_unlock( &p_sys->mutex );
1227     return NULL;
1228 }
1229
1230 static int
1231 Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt )
1232 {
1233     int i_ret = VLC_EGENERIC;
1234     struct thread_cmd *p_cmd;
1235     aout_sys_t *p_sys = p_aout->sys;
1236
1237     vlc_mutex_lock( &p_sys->mutex );
1238
1239     p_cmd = ThreadCmd_New( CMD_START );
1240     if( p_cmd )
1241     {
1242         /* ask the thread to process the Start command */
1243         p_cmd->in.start.p_fmt = p_fmt;
1244
1245         ThreadCmd_InsertHead( p_sys, p_cmd );
1246         if( ThreadCmd_Wait( p_sys, p_cmd ) )
1247         {
1248             i_ret = p_cmd->out.start.i_ret;
1249             if( i_ret == VLC_SUCCESS )
1250                 *p_fmt = *p_cmd->out.start.p_fmt;
1251         }
1252         free( p_cmd );
1253     }
1254
1255     vlc_mutex_unlock( &p_sys->mutex );
1256
1257     if( i_ret == VLC_SUCCESS )
1258         aout_SoftVolumeStart( p_aout );
1259
1260     return i_ret;
1261 }
1262
1263 static void
1264 Stop( audio_output_t *p_aout )
1265 {
1266     aout_sys_t *p_sys = p_aout->sys;
1267     struct thread_cmd *p_cmd;
1268
1269     vlc_mutex_lock( &p_sys->mutex );
1270
1271     ThreadCmd_FlushQueue( p_sys );
1272
1273     p_cmd = ThreadCmd_New( CMD_STOP );
1274     if( p_cmd )
1275     {
1276         /* ask the thread to process the Stop command */
1277         ThreadCmd_InsertHead( p_sys, p_cmd );
1278         ThreadCmd_Wait( p_sys, p_cmd );
1279
1280         free( p_cmd );
1281     }
1282
1283     vlc_mutex_unlock( &p_sys->mutex );
1284 }
1285
1286 static void
1287 PlayCmd_Destroy( struct thread_cmd *p_cmd )
1288 {
1289     block_Release( p_cmd->in.play.p_buffer );
1290     free( p_cmd );
1291 }
1292
1293 static void
1294 Play( audio_output_t *p_aout, block_t *p_buffer )
1295 {
1296     aout_sys_t *p_sys = p_aout->sys;
1297     struct thread_cmd *p_cmd;
1298
1299     vlc_mutex_lock( &p_sys->mutex );
1300
1301     while( p_sys->i_samples_queued != 0
1302            && FRAMES_TO_US( p_sys->i_samples_queued +
1303                             p_buffer->i_nb_samples ) >= MAX_QUEUE_US )
1304         vlc_cond_wait( &p_sys->cond, &p_sys->mutex );
1305
1306     p_cmd = ThreadCmd_New( CMD_PLAY );
1307     if( p_cmd )
1308     {
1309         /* ask the thread to process the Play command */
1310         p_cmd->in.play.p_buffer = p_buffer;
1311         p_cmd->pf_destroy = PlayCmd_Destroy;
1312
1313         ThreadCmd_InsertTail( p_sys, p_cmd );
1314
1315         p_sys->i_samples_queued += p_buffer->i_nb_samples;
1316     } else
1317          block_Release( p_cmd->in.play.p_buffer );
1318
1319     vlc_mutex_unlock( &p_sys->mutex );
1320 }
1321
1322 static void
1323 Pause( audio_output_t *p_aout, bool b_pause, mtime_t i_date )
1324 {
1325     aout_sys_t *p_sys = p_aout->sys;
1326     struct thread_cmd *p_cmd;
1327
1328     vlc_mutex_lock( &p_sys->mutex );
1329
1330     p_cmd = ThreadCmd_New( CMD_PAUSE );
1331     if( p_cmd )
1332     {
1333         /* ask the thread to process the Pause command */
1334         p_cmd->in.pause.b_pause = b_pause;
1335         p_cmd->in.pause.i_date = i_date;
1336
1337         ThreadCmd_InsertHead( p_sys, p_cmd );
1338         ThreadCmd_Wait( p_sys, p_cmd );
1339
1340         free( p_cmd );
1341     }
1342
1343     vlc_mutex_unlock( &p_sys->mutex );
1344 }
1345
1346 static void
1347 Flush( audio_output_t *p_aout, bool b_wait )
1348 {
1349     aout_sys_t *p_sys = p_aout->sys;
1350     struct thread_cmd *p_cmd;
1351
1352     vlc_mutex_lock( &p_sys->mutex );
1353
1354     ThreadCmd_FlushQueue( p_sys );
1355
1356     p_cmd = ThreadCmd_New( CMD_FLUSH );
1357     if( p_cmd)
1358     {
1359         /* ask the thread to process the Flush command */
1360         p_cmd->in.flush.b_wait = b_wait;
1361
1362         ThreadCmd_InsertHead( p_sys, p_cmd );
1363         ThreadCmd_Wait( p_sys, p_cmd );
1364
1365         free( p_cmd );
1366     }
1367
1368     vlc_mutex_unlock( &p_sys->mutex );
1369 }
1370
1371 static int
1372 TimeGet( audio_output_t *p_aout, mtime_t *restrict p_delay )
1373 {
1374     aout_sys_t *p_sys = p_aout->sys;
1375     struct thread_cmd *p_cmd;
1376     int i_ret = -1;
1377
1378     vlc_mutex_lock( &p_sys->mutex );
1379
1380     p_cmd = ThreadCmd_New( CMD_TIME_GET );
1381     if( p_cmd)
1382     {
1383         ThreadCmd_InsertHead( p_sys, p_cmd );
1384         ThreadCmd_Wait( p_sys, p_cmd );
1385
1386         i_ret = p_cmd->out.time_get.i_ret;
1387         *p_delay = p_cmd->out.time_get.i_delay;
1388         free( p_cmd );
1389     }
1390
1391     vlc_mutex_unlock( &p_sys->mutex );
1392
1393     return i_ret;
1394 }
1395
1396
1397 static int
1398 Open( vlc_object_t *obj )
1399 {
1400     audio_output_t *p_aout = (audio_output_t *) obj;
1401     aout_sys_t *p_sys;
1402
1403     if( !InitJNIFields( p_aout ) )
1404         return VLC_EGENERIC;
1405
1406     p_sys = calloc( 1, sizeof (aout_sys_t) );
1407
1408     if( unlikely( p_sys == NULL ) )
1409         return VLC_ENOMEM;
1410
1411     vlc_mutex_init( &p_sys->mutex );
1412     vlc_cond_init( &p_sys->cond );
1413     TAILQ_INIT( &p_sys->thread_cmd_queue );
1414
1415     p_aout->sys = p_sys;
1416     p_aout->start = Start;
1417     p_aout->stop = Stop;
1418     p_aout->play = Play;
1419     p_aout->pause = Pause;
1420     p_aout->flush = Flush;
1421     p_aout->time_get = TimeGet;
1422
1423     aout_SoftVolumeInit( p_aout );
1424
1425     /* create JNIThread */
1426     p_sys->b_thread_run = true;
1427     if( vlc_clone( &p_sys->thread,
1428                    JNIThread, p_aout, VLC_THREAD_PRIORITY_AUDIO ) )
1429     {
1430         msg_Err( p_aout, "JNIThread creation failed" );
1431         p_sys->b_thread_run = false;
1432         Close( obj );
1433         return VLC_EGENERIC;
1434     }
1435
1436     return VLC_SUCCESS;
1437 }
1438
1439 static void
1440 Close( vlc_object_t *obj )
1441 {
1442     audio_output_t *p_aout = (audio_output_t *) obj;
1443     aout_sys_t *p_sys = p_aout->sys;
1444
1445     /* kill the thread */
1446     vlc_mutex_lock( &p_sys->mutex );
1447     if( p_sys->b_thread_run )
1448     {
1449         p_sys->b_thread_run = false;
1450         vlc_cond_signal( &p_sys->cond );
1451         vlc_mutex_unlock( &p_sys->mutex );
1452         vlc_join( p_sys->thread, NULL );
1453     } else
1454         vlc_mutex_unlock( &p_sys->mutex );
1455
1456     vlc_mutex_destroy( &p_sys->mutex );
1457     vlc_cond_destroy( &p_sys->cond );
1458
1459     free( p_sys );
1460 }