vlc | branch: master | Thomas Guillem <[email protected]> | Mon Nov 23 14:21:15 2020 +0100| [560221d6621c9354ae25e2a00e62f19f6a76d454] | committer: Thomas Guillem
audiotrack: use AudioTrack.getLatency() Instead of AudioSystem.getOutputLatency(). That way, we are sure the get the latency of the current output device. Note: both methods are hidden and should not be used in favor or AudioTrack.getTimestamp(). Unfortunately, getTimestamp() returns a valid timestamp too late (after few seconds) or doesn't work with some phones. Therefore, the usage of the hidden API is still needed as a backup plan. cf. https://github.com/google/ExoPlayer/issues/5763 The android team allow the usage of this hidden API, waiting for a new method in next Android versions. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=560221d6621c9354ae25e2a00e62f19f6a76d454 --- modules/audio_output/audiotrack.c | 60 ++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c index 8237af217f..a371104730 100644 --- a/modules/audio_output/audiotrack.c +++ b/modules/audio_output/audiotrack.c @@ -118,7 +118,6 @@ typedef struct vlc_tick_t p_us[SMOOTHPOS_SAMPLE_COUNT]; vlc_tick_t i_us; vlc_tick_t i_last_time; - vlc_tick_t i_latency_us; } smoothpos; uint32_t i_max_audiotrack_samples; @@ -211,6 +210,7 @@ static struct jmethodID writeShortV23; jmethodID writeBufferV21; jmethodID writeFloat; + jmethodID getLatency; jmethodID getPlaybackHeadPosition; jmethodID getTimestamp; jmethodID getMinBufferSize; @@ -274,10 +274,6 @@ static struct bool has_ERROR_DEAD_OBJECT; jint STREAM_MUSIC; } AudioManager; - struct { - jclass clazz; - jmethodID getOutputLatency; - } AudioSystem; struct { jclass clazz; jmethodID ctor; @@ -364,6 +360,10 @@ InitJNIFields( audio_output_t *p_aout, JNIEnv* env ) } else GET_ID( GetMethodID, AudioTrack.write, "write", "([BII)I", true ); +#ifdef AUDIOTRACK_HW_LATENCY + GET_ID( GetMethodID, AudioTrack.getLatency, "getLatency", "()I", false ); +#endif + GET_ID( GetMethodID, AudioTrack.getTimestamp, "getTimestamp", "(Landroid/media/AudioTimestamp;)Z", false ); GET_ID( GetMethodID, AudioTrack.getPlaybackHeadPosition, @@ -431,17 +431,6 @@ InitJNIFields( audio_output_t *p_aout, JNIEnv* env ) "nanoTime", "J", true ); } -#ifdef AUDIOTRACK_HW_LATENCY - /* AudioSystem class init */ - GET_CLASS( "android/media/AudioSystem", false ); - if( clazz ) - { - jfields.AudioSystem.clazz = (jclass) (*env)->NewGlobalRef( env, clazz ); - GET_ID( GetStaticMethodID, AudioSystem.getOutputLatency, - "getOutputLatency", "(I)I", false ); - } -#endif - /* AudioFormat class init */ GET_CLASS( "android/media/AudioFormat", true ); GET_CONST_INT( AudioFormat.ENCODING_PCM_8BIT, "ENCODING_PCM_8BIT", true ); @@ -639,7 +628,6 @@ AudioTrack_ResetPositions( JNIEnv *env, audio_output_t *p_aout ) p_sys->smoothpos.i_idx = 0; p_sys->smoothpos.i_last_time = 0; p_sys->smoothpos.i_us = 0; - p_sys->smoothpos.i_latency_us = 0; } /** @@ -655,6 +643,29 @@ AudioTrack_Reset( JNIEnv *env, audio_output_t *p_aout ) p_sys->i_samples_written = 0; } +static vlc_tick_t +AudioTrack_GetLatencyUs( JNIEnv *env, audio_output_t *p_aout ) +{ + aout_sys_t *p_sys = p_aout->sys; + + if( jfields.AudioTrack.getLatency ) + { + int i_latency_ms = JNI_AT_CALL_INT( getLatency ); + + /* getLatency() includes the latency due to AudioTrack buffer size, + * AudioMixer (if any) and audio hardware driver. We only need the + * audio hardware latency */ + if( i_latency_ms > 0 ) + { + vlc_tick_t i_latency_us = VLC_TICK_FROM_MS( i_latency_ms ) + - FRAMES_TO_US( p_sys->i_max_audiotrack_samples ); + return i_latency_us >= 0 ? i_latency_us : 0; + } + } + + return 0; +} + /** * Get a smooth AudioTrack position * @@ -688,19 +699,9 @@ AudioTrack_GetSmoothPositionUs( JNIEnv *env, audio_output_t *p_aout ) p_sys->smoothpos.i_us += p_sys->smoothpos.p_us[i]; p_sys->smoothpos.i_us /= p_sys->smoothpos.i_count; - if( jfields.AudioSystem.getOutputLatency ) - { - int i_latency_ms = JNI_CALL( CallStaticIntMethod, - jfields.AudioSystem.clazz, - jfields.AudioSystem.getOutputLatency, - jfields.AudioManager.STREAM_MUSIC ); - - p_sys->smoothpos.i_latency_us = i_latency_ms > 0 ? - i_latency_ms * 1000L : 0; - } } if( p_sys->smoothpos.i_us != 0 ) - return p_sys->smoothpos.i_us + i_now - p_sys->smoothpos.i_latency_us; + return p_sys->smoothpos.i_us + i_now - AudioTrack_GetLatencyUs( env, p_aout ); else return 0; } @@ -789,9 +790,10 @@ TimeGet( audio_output_t *p_aout, vlc_tick_t *restrict p_delay ) { vlc_tick_t i_ts_us = AudioTrack_GetTimestampPositionUs( env, p_aout ); vlc_tick_t i_smooth_us = AudioTrack_GetSmoothPositionUs(env, p_aout ); + vlc_tick_t i_latency_us = AudioTrack_GetLatencyUs( env, p_aout ); msg_Err( p_aout, "TimeGet: TimeStamp: %"PRId64", Smooth: %"PRId64" (latency: %"PRId64")", - i_ts_us, i_smooth_us, p_sys->smoothpos.i_latency_us ); + i_ts_us, i_smooth_us, i_latency_us ); } #endif _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
