vlc | branch: master | Thomas Guillem <[email protected]> | Fri Jul 3 09:47:54 2015 +0200| [b83d1386d7ef2817a83c41dde370fefd5a1aaa3a] | committer: Thomas Guillem
audiotrack: add AudioTrack_Reset Refactor AudioTrack creation, and add a function that destroy and recreate an AudioTrack object using the previous arguments. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b83d1386d7ef2817a83c41dde370fefd5a1aaa3a --- modules/audio_output/audiotrack.c | 139 ++++++++++++++++++++++++------------- 1 file changed, 89 insertions(+), 50 deletions(-) diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c index 29c77dd..07ca81e 100644 --- a/modules/audio_output/audiotrack.c +++ b/modules/audio_output/audiotrack.c @@ -61,6 +61,13 @@ struct aout_sys_t { jobject p_bytebuffer; /* ByteBuffer ref (for WriteV21) */ audio_sample_format_t fmt; /* fmt setup by Start */ + struct { + unsigned int i_rate; + int i_channel_config; + int i_format; + int i_size; + } audiotrack_args; + /* Used by AudioTrack_GetPosition / AudioTrack_getPlaybackHeadPosition */ struct { uint64_t i_initial; @@ -727,19 +734,69 @@ AudioTrack_GetChanOrder( uint16_t i_physical_channels, uint32_t p_chans_out[] ) } /** + * Create an Android AudioTrack. + * returns -1 on error, 0 on success. + */ +static int +AudioTrack_New( JNIEnv *env, audio_output_t *p_aout, unsigned int i_rate, + int i_channel_config, int i_format, int i_size ) +{ + aout_sys_t *p_sys = p_aout->sys; + jobject p_audiotrack = JNI_AT_NEW( jfields.AudioManager.STREAM_MUSIC, + i_rate, i_channel_config, i_format, + i_size, jfields.AudioTrack.MODE_STREAM ); + if( CHECK_AT_EXCEPTION( "AudioTrack<init>" ) || !p_audiotrack ) + { + msg_Warn( p_aout, "AudioTrack Init failed" ) ; + return -1; + } + if( JNI_CALL_INT( p_audiotrack, jfields.AudioTrack.getState ) + != jfields.AudioTrack.STATE_INITIALIZED ) + { + JNI_CALL_VOID( p_audiotrack, jfields.AudioTrack.release ); + (*env)->DeleteLocalRef( env, p_audiotrack ); + msg_Err( p_aout, "AudioTrack getState failed" ); + return -1; + } + + p_sys->p_audiotrack = (*env)->NewGlobalRef( env, p_audiotrack ); + (*env)->DeleteLocalRef( env, p_audiotrack ); + if( !p_sys->p_audiotrack ) + return -1; + + return 0; +} + +/** + * Destroy and recreate an Android AudioTrack using the same arguments. + * returns -1 on error, 0 on success. + */ +static int +AudioTrack_Reset( JNIEnv *env, audio_output_t *p_aout ) +{ + aout_sys_t *p_sys = p_aout->sys; + + JNI_AT_CALL_VOID( release ); + (*env)->DeleteGlobalRef( env, p_sys->p_audiotrack ); + return AudioTrack_New( env, p_aout, p_sys->audiotrack_args.i_rate, + p_sys->audiotrack_args.i_channel_config, + p_sys->audiotrack_args.i_format, + p_sys->audiotrack_args.i_size ); +} + +/** * Configure and create an Android AudioTrack. - * returns NULL on configuration error + * returns -1 on configuration error, 0 on success. */ -static jobject -AudioTrack_New( JNIEnv *env, audio_output_t *p_aout, - unsigned int i_rate, - vlc_fourcc_t i_vlc_format, - uint16_t i_physical_channels, - int i_bytes_per_frame, - int *p_audiotrack_size ) +static int +AudioTrack_Create( JNIEnv *env, audio_output_t *p_aout, + unsigned int i_rate, + vlc_fourcc_t i_vlc_format, + uint16_t i_physical_channels, + int i_bytes_per_frame ) { + aout_sys_t *p_sys = p_aout->sys; int i_size, i_min_buffer_size, i_channel_config, i_format; - jobject p_audiotrack; switch( i_vlc_format ) { @@ -785,7 +842,7 @@ AudioTrack_New( JNIEnv *env, audio_output_t *p_aout, if( i_min_buffer_size <= 0 ) { msg_Warn( p_aout, "getMinBufferSize returned an invalid size" ) ; - return NULL; + return -1; } if( i_vlc_format == VLC_CODEC_SPDIFB ) i_size = ( i_min_buffer_size / AOUT_SPDIF_SIZE + 1 ) * AOUT_SPDIF_SIZE; @@ -805,25 +862,16 @@ AudioTrack_New( JNIEnv *env, audio_output_t *p_aout, } /* create AudioTrack object */ - p_audiotrack = JNI_AT_NEW( jfields.AudioManager.STREAM_MUSIC, i_rate, - i_channel_config, i_format, i_size, - jfields.AudioTrack.MODE_STREAM ); - if( CHECK_AT_EXCEPTION( "AudioTrack<init>" ) || !p_audiotrack ) - { - msg_Warn( p_aout, "AudioTrack Init failed" ) ; - return NULL; - } - if( JNI_CALL_INT( p_audiotrack, jfields.AudioTrack.getState ) - != jfields.AudioTrack.STATE_INITIALIZED ) - { - JNI_CALL_VOID( p_audiotrack, jfields.AudioTrack.release ); - (*env)->DeleteLocalRef( env, p_audiotrack ); - msg_Err( p_aout, "AudioTrack getState failed" ); - return NULL; - } - *p_audiotrack_size = i_size; + if( AudioTrack_New( env, p_aout, i_rate, i_channel_config, + i_format , i_size ) != 0 ) + return -1; - return p_audiotrack; + p_sys->audiotrack_args.i_rate = i_rate; + p_sys->audiotrack_args.i_channel_config = i_channel_config; + p_sys->audiotrack_args.i_format = i_format; + p_sys->audiotrack_args.i_size = i_size; + + return 0; } static int @@ -831,9 +879,8 @@ Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt ) { aout_sys_t *p_sys = p_aout->sys; JNIEnv *env; - jobject p_audiotrack = NULL; - int i_nb_channels, i_max_channels, i_audiotrack_size, i_bytes_per_frame, - i_native_rate = 0; + int i_nb_channels, i_max_channels, i_bytes_per_frame, i_native_rate = 0, + i_ret; unsigned int i_rate; bool b_spdif; @@ -916,15 +963,13 @@ Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt ) : (unsigned int) i_native_rate; /* Try to create an AudioTrack with the most advanced channel and - * format configuration. If AudioTrack_New fails, try again with a less - * advanced format (PCM S16N). If it fails again, try again with Stereo - * channels. */ - p_audiotrack = AudioTrack_New( env, p_aout, i_rate, - p_sys->fmt.i_format, - p_sys->fmt.i_physical_channels, - i_bytes_per_frame, - &i_audiotrack_size ); - if( !p_audiotrack ) + * format configuration. If AudioTrack_Create fails, try again with a + * less advanced format (PCM S16N). If it fails again, try again with + * Stereo channels. */ + i_ret = AudioTrack_Create( env, p_aout, i_rate, p_sys->fmt.i_format, + p_sys->fmt.i_physical_channels, + i_bytes_per_frame ); + if( i_ret != 0 ) { if( p_sys->fmt.i_format == VLC_CODEC_SPDIFB ) { @@ -950,14 +995,9 @@ Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt ) else break; } - } while( !p_audiotrack ); + } while( i_ret != 0 ); - if( !p_audiotrack ) - return VLC_EGENERIC; - - p_sys->p_audiotrack = (*env)->NewGlobalRef( env, p_audiotrack ); - (*env)->DeleteLocalRef( env, p_audiotrack ); - if( !p_sys->p_audiotrack ) + if( i_ret != 0 ) return VLC_EGENERIC; p_sys->fmt.i_rate = i_rate; @@ -980,7 +1020,7 @@ Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt ) p_sys->p_chan_table ); p_sys->i_bytes_per_frame = i_bytes_per_frame; } - p_sys->i_max_audiotrack_samples = BYTES_TO_FRAMES( i_audiotrack_size ); + p_sys->i_max_audiotrack_samples = BYTES_TO_FRAMES( p_sys->audiotrack_args.i_size ); #ifdef AUDIOTRACK_HW_LATENCY if( jfields.AudioTimestamp.clazz ) @@ -1282,8 +1322,7 @@ AudioTrack_Play( JNIEnv *env, audio_output_t *p_aout, { msg_Warn( p_aout, "ERROR_DEAD_OBJECT: " "try recreating AudioTrack" ); - Stop( p_aout ); - i_ret = Start( p_aout, &p_sys->fmt ); + i_ret = AudioTrack_Reset( env, p_aout ); } else { const char *str; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
