[vlc-commits] audiotrack: fix head position before Android 4.4
Thomas Guillem
git at videolan.org
Fri Jul 3 10:43:22 CEST 2015
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Jul 3 09:48:11 2015 +0200| [b8e2c28e8db894109e862fa73cd6654794cb8065] | committer: Thomas Guillem
audiotrack: fix head position before Android 4.4
Fix the workaround in AudioTrack_ResetPlaybackHeadPosition. Don't wait for an
unknown time that the position stabilizes but reset the AudioTrack object.
The audiotrack head position shouldn't be ahead of the module position anymore.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b8e2c28e8db894109e862fa73cd6654794cb8065
---
modules/audio_output/audiotrack.c | 60 ++++++++++++++++---------------------
1 file changed, 25 insertions(+), 35 deletions(-)
diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c
index 07ca81e..9f9ac97 100644
--- a/modules/audio_output/audiotrack.c
+++ b/modules/audio_output/audiotrack.c
@@ -68,9 +68,8 @@ struct aout_sys_t {
int i_size;
} audiotrack_args;
- /* Used by AudioTrack_GetPosition / AudioTrack_getPlaybackHeadPosition */
+ /* Used by AudioTrack_getPlaybackHeadPosition */
struct {
- uint64_t i_initial;
uint32_t i_wrap_count;
uint32_t i_last;
} headpos;
@@ -442,7 +441,7 @@ frames_to_bytes( aout_sys_t *p_sys, uint64_t i_frames )
* Get the AudioTrack position
*
* The doc says that the position is reset to zero after flush but it's not
- * true for all devices or Android versions. Use AudioTrack_GetPosition instead.
+ * true for all devices or Android versions.
*/
static uint64_t
AudioTrack_getPlaybackHeadPosition( JNIEnv *env, audio_output_t *p_aout )
@@ -471,18 +470,6 @@ AudioTrack_getPlaybackHeadPosition( JNIEnv *env, audio_output_t *p_aout )
}
/**
- * Get the AudioTrack position since the last flush or stop
- */
-static uint64_t
-AudioTrack_GetPosition( JNIEnv *env, audio_output_t *p_aout )
-{
- aout_sys_t *p_sys = p_aout->sys;
-
- return AudioTrack_getPlaybackHeadPosition( env, p_aout )
- - p_sys->headpos.i_initial;
-}
-
-/**
* Reset AudioTrack position
*
* Called after flush, or start
@@ -490,24 +477,9 @@ AudioTrack_GetPosition( JNIEnv *env, audio_output_t *p_aout )
static void
AudioTrack_ResetPlaybackHeadPosition( JNIEnv *env, audio_output_t *p_aout )
{
+ (void) env;
aout_sys_t *p_sys = p_aout->sys;
- if( p_sys->p_audiotrack )
- p_sys->headpos.i_initial = AudioTrack_getPlaybackHeadPosition( env, p_aout );
- else
- p_sys->headpos.i_initial = 0;
-
- /* HACK: On some broken devices, head position is still moving after a
- * flush or a stop. So, wait for the head position to be stabilized. */
- if( unlikely( p_sys->headpos.i_initial != 0 ) )
- {
- uint64_t i_last_pos;
- do {
- i_last_pos = p_sys->headpos.i_initial;
- msleep( 50000 );
- p_sys->headpos.i_initial = JNI_AT_CALL_INT( getPlaybackHeadPosition );
- } while( p_sys->headpos.i_initial != i_last_pos );
- }
p_sys->headpos.i_last = 0;
p_sys->headpos.i_wrap_count = 0;
}
@@ -549,7 +521,7 @@ AudioTrack_GetSmoothPositionUs( JNIEnv *env, audio_output_t *p_aout )
/* Fetch an AudioTrack position every SMOOTHPOS_INTERVAL_US (30ms) */
if( i_now - p_sys->smoothpos.i_last_time >= SMOOTHPOS_INTERVAL_US )
{
- i_audiotrack_us = FRAMES_TO_US( AudioTrack_GetPosition( env, p_aout ) );
+ i_audiotrack_us = FRAMES_TO_US( AudioTrack_getPlaybackHeadPosition( env, p_aout ) );
p_sys->smoothpos.i_last_time = i_now;
@@ -1117,12 +1089,14 @@ AudioTrack_Write( JNIEnv *env, audio_output_t *p_aout, block_t *p_buffer,
uint64_t i_samples_pending;
i_data = p_buffer->i_buffer - i_buffer_offset;
- i_audiotrack_pos = AudioTrack_GetPosition( env, p_aout );
+ i_audiotrack_pos = AudioTrack_getPlaybackHeadPosition( env, p_aout );
+
+ assert( i_audiotrack_pos <= p_sys->i_samples_written );
if( i_audiotrack_pos > p_sys->i_samples_written )
{
- msg_Warn( p_aout, "audiotrack position is ahead. Should NOT happen" );
- AudioTrack_ResetPlaybackHeadPosition( env, p_aout );
+ msg_Err( p_aout, "audiotrack position is ahead. Should NOT happen" );
p_sys->i_samples_written = 0;
+ p_sys->b_error = true;
return 0;
}
i_samples_pending = p_sys->i_samples_written - i_audiotrack_pos;
@@ -1448,6 +1422,22 @@ Flush( audio_output_t *p_aout, bool b_wait )
return;
JNI_AT_CALL_VOID( flush );
}
+
+ /* HACK: Before Android 4.4, the head position is not reset to zero and is
+ * still moving after a flush or a stop. This prevents to get a precise
+ * head position and there is no way to know when it stabilizes. Therefore
+ * recreate an AudioTrack object in that case. The AudioTimestamp class was
+ * added in API Level 19, so if this class is not found, the Android
+ * Version is 4.3 or before */
+ if( !jfields.AudioTimestamp.clazz && p_sys->i_samples_written > 0 )
+ {
+ if( AudioTrack_Reset( env, p_aout ) != 0 )
+ {
+ p_sys->b_error = true;
+ return;
+ }
+ }
+
JNI_AT_CALL_VOID( play );
CHECK_AT_EXCEPTION( "play" );
More information about the vlc-commits
mailing list