[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