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