[vlc-devel] [PATCH 2/3] audiotrack: move AudioTimestamp into a separate function

Thomas Guillem thomas at gllm.fr
Tue Apr 14 19:44:52 CEST 2015


---
 modules/audio_output/audiotrack.c | 104 +++++++++++++++++++++-----------------
 1 file changed, 58 insertions(+), 46 deletions(-)

diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c
index 655e6a7..8744647 100644
--- a/modules/audio_output/audiotrack.c
+++ b/modules/audio_output/audiotrack.c
@@ -438,6 +438,56 @@ AudioTrack_GetPosition( JNIEnv *env, audio_output_t *p_aout )
         - p_sys->headpos.i_initial;
 }
 
+static mtime_t
+AudioTrack_GetTimestampPositionUs( JNIEnv *env, audio_output_t *p_aout )
+{
+    aout_sys_t *p_sys = p_aout->sys;
+    mtime_t i_now;
+
+    if( !p_sys->p_audioTimestamp )
+        return 0;
+
+    i_now = mdate();
+
+    /* Android doc:
+     * getTimestamp: Poll for a timestamp on demand.
+     *
+     * If you need to track timestamps during initial warmup or after a
+     * routing or mode change, you should request a new timestamp once per
+     * second until the reported timestamps show that the audio clock is
+     * stable. Thereafter, query for a new timestamp approximately once
+     * every 10 seconds to once per minute. Calling this method more often
+     * is inefficient. It is also counter-productive to call this method
+     * more often than recommended, because the short-term differences
+     * between successive timestamp reports are not meaningful. If you need
+     * a high-resolution mapping between frame position and presentation
+     * time, consider implementing that at application level, based on
+     * low-resolution timestamps.
+     */
+
+    if( JNI_AT_CALL_BOOL( getTimestamp, p_sys->p_audioTimestamp ) )
+    {
+        jlong i_frame_time = JNI_AUDIOTIMESTAMP_GET_LONG( nanoTime ) / 1000;
+        /* frame time should be after last play time
+         * frame time shouldn't be in the future
+         * frame time should be less than 10 seconds old */
+        if( i_frame_time > p_sys->i_play_time
+            && i_now > i_frame_time
+            && ( i_now - i_frame_time ) <= INT64_C(10000000) )
+        {
+            jlong i_time_diff = i_now - i_frame_time;
+            jlong i_frames_diff = i_time_diff *  p_sys->fmt.i_rate
+                                  / CLOCK_FREQ;
+            jlong i_frame_pos = JNI_AUDIOTIMESTAMP_GET_LONG( framePosition )
+                                + i_frames_diff;
+            if( i_frame_pos > 0
+             && p_sys->i_samples_written > (uint64_t) i_frame_pos )
+                return FRAMES_TO_US( i_frame_pos );
+        }
+    }
+    return 0;
+}
+
 static void
 AudioTrack_InitDelay( JNIEnv *env, audio_output_t *p_aout )
 {
@@ -468,8 +518,7 @@ static int
 TimeGet( audio_output_t *p_aout, mtime_t *restrict p_delay )
 {
     aout_sys_t *p_sys = p_aout->sys;
-    jlong i_frame_pos;
-    uint64_t i_audiotrack_delay = 0;
+    mtime_t i_audiotrack_us;
     JNIEnv *env;
 
     if( p_sys->b_error || !( env = jni_get_env( THREAD_NAME ) ) )
@@ -477,57 +526,20 @@ TimeGet( audio_output_t *p_aout, mtime_t *restrict p_delay )
 
     if( p_sys->b_spdif )
         return -1;
-    if( p_sys->p_audioTimestamp )
-    {
-        mtime_t i_current_time = mdate();
-        /* Android doc:
-         * getTimestamp: Poll for a timestamp on demand.
-         *
-         * If you need to track timestamps during initial warmup or after a
-         * routing or mode change, you should request a new timestamp once per
-         * second until the reported timestamps show that the audio clock is
-         * stable. Thereafter, query for a new timestamp approximately once
-         * every 10 seconds to once per minute. Calling this method more often
-         * is inefficient. It is also counter-productive to call this method
-         * more often than recommended, because the short-term differences
-         * between successive timestamp reports are not meaningful. If you need
-         * a high-resolution mapping between frame position and presentation
-         * time, consider implementing that at application level, based on
-         * low-resolution timestamps.
-         */
-
-        if( JNI_AT_CALL_BOOL( getTimestamp, p_sys->p_audioTimestamp ) )
-        {
-            jlong i_frame_time = JNI_AUDIOTIMESTAMP_GET_LONG( nanoTime ) / 1000;
-            /* frame time should be after last play time
-             * frame time shouldn't be in the future
-             * frame time should be less than 10 seconds old */
-            if( i_frame_time > p_sys->i_play_time
-                && i_current_time > i_frame_time
-                && ( i_current_time - i_frame_time ) <= INT64_C(10000000) )
-            {
-                jlong i_time_diff = i_current_time - i_frame_time;
-                jlong i_frames_diff = i_time_diff *  p_sys->fmt.i_rate
-                                      / CLOCK_FREQ;
-                i_frame_pos = JNI_AUDIOTIMESTAMP_GET_LONG( framePosition )
-                              + i_frames_diff;
-                if( i_frame_pos > 0
-                 && p_sys->i_samples_written > (uint64_t) i_frame_pos )
-                    i_audiotrack_delay =  p_sys->i_samples_written - i_frame_pos;
-            }
-        }
-    }
-    if( i_audiotrack_delay == 0 )
+
+    i_audiotrack_us = AudioTrack_GetTimestampPositionUs( env, p_aout );
+
+    if( i_audiotrack_us == 0 )
     {
         uint64_t i_audiotrack_pos = AudioTrack_GetPosition( env, p_aout );
 
         if( p_sys->i_samples_written > i_audiotrack_pos )
-            i_audiotrack_delay = p_sys->i_samples_written - i_audiotrack_pos;
+            i_audiotrack_us = FRAMES_TO_US( i_audiotrack_pos );
     }
 
-    if( i_audiotrack_delay > 0 )
+    if( i_audiotrack_us > 0 )
     {
-        *p_delay = FRAMES_TO_US( i_audiotrack_delay );
+        *p_delay = FRAMES_TO_US( p_sys->i_samples_written ) - i_audiotrack_us;
         return 0;
     } else
         return -1;
-- 
2.1.3




More information about the vlc-devel mailing list