+ if( p_sys->p_audioTimestamp )
+ {
+ /* 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;
+ b_frame_delay_set = true;
+ }
+ }
+ }
+ if( !b_frame_delay_set )
+ {
+ /* Android doc:
+ * getPlaybackHeadPosition: Returns the playback head position
+ * expressed in frames. Though the "int" type is signed 32-bits, the
+ * value should be reinterpreted as if it is unsigned 32-bits. That is,
+ * the next position after 0x7FFFFFFF is (int) 0x80000000. This is a
+ * continuously advancing counter. It will wrap (overflow)
+ * periodically, for example approximately once every 27:03:11
+ * hours:minutes:seconds at 44.1 kHz. It is reset to zero by flush(),
+ * reload(), and stop().
+ */
+
+ uint32_t i_head_pos = JNI_AT_CALL_INT( getPlaybackHeadPosition );
+ i_frame_pos = i_head_pos - p_sys->i_pos_initial;
+ b_frame_delay_set = true;
+ }