@ -176,6 +176,7 @@ typedef struct VideoState {
double external_clock_speed ; ///< speed of the external clock
double audio_clock ;
int audio_clock_serial ;
double audio_diff_cum ; /* used for AV difference average computation */
double audio_diff_avg_coef ;
double audio_diff_threshold ;
@ -238,6 +239,7 @@ typedef struct VideoState {
double video_current_pts_drift ; // video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
int64_t video_current_pos ; // current displayed file pos
double max_frame_duration ; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
int video_clock_serial ;
VideoPicture pictq [ VIDEO_PICTURE_QUEUE_SIZE ] ;
int pictq_size , pictq_rindex , pictq_windex ;
SDL_mutex * pictq_mutex ;
@ -1079,6 +1081,8 @@ static void video_display(VideoState *is)
/* get the current audio clock value */
static double get_audio_clock ( VideoState * is )
{
if ( is - > audio_clock_serial ! = is - > audioq . serial )
return NAN ;
if ( is - > paused ) {
return is - > audio_current_pts ;
} else {
@ -1089,6 +1093,8 @@ static double get_audio_clock(VideoState *is)
/* get the current video clock value */
static double get_video_clock ( VideoState * is )
{
if ( is - > video_clock_serial ! = is - > videoq . serial )
return NAN ;
if ( is - > paused ) {
return is - > video_current_pts ;
} else {
@ -1230,7 +1236,7 @@ static double compute_target_delay(double delay, VideoState *is)
delay to compute the threshold . I still don ' t know
if it is the best guess */
sync_threshold = FFMAX ( AV_SYNC_THRESHOLD , delay ) ;
if ( fabs ( diff ) < AV_NOSYNC_THRESHOLD ) {
if ( ! isnan ( diff ) & & fabs ( diff ) < AV_NOSYNC_THRESHOLD ) {
if ( diff < = - sync_threshold )
delay = 0 ;
else if ( diff > = sync_threshold )
@ -1281,6 +1287,7 @@ static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial
is - > video_current_pts_drift = is - > video_current_pts - time ;
is - > video_current_pos = pos ;
is - > frame_last_pts = pts ;
is - > video_clock_serial = serial ;
if ( is - > videoq . serial = = serial )
check_external_clock_sync ( is , is - > video_current_pts ) ;
}
@ -1677,7 +1684,7 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
double clockdiff = get_video_clock ( is ) - get_master_clock ( is ) ;
double dpts = av_q2d ( is - > video_st - > time_base ) * * pts ;
double ptsdiff = dpts - is - > frame_last_pts ;
if ( fabs ( clockdiff ) < AV_NOSYNC_THRESHOLD & &
if ( ! isnan ( clockdiff ) & & fabs ( clockdiff ) < AV_NOSYNC_THRESHOLD & &
ptsdiff > 0 & & ptsdiff < AV_NOSYNC_THRESHOLD & &
clockdiff + ptsdiff - is - > frame_last_filter_delay < 0 ) {
is - > frame_last_dropped_pos = pkt - > pos ;
@ -2038,7 +2045,7 @@ static int synchronize_audio(VideoState *is, int nb_samples)
diff = get_audio_clock ( is ) - get_master_clock ( is ) ;
if ( fabs ( diff ) < AV_NOSYNC_THRESHOLD ) {
if ( ! isnan ( diff ) & & fabs ( diff ) < AV_NOSYNC_THRESHOLD ) {
is - > audio_diff_cum = diff + is - > audio_diff_avg_coef * is - > audio_diff_cum ;
if ( is - > audio_diff_avg_count < AUDIO_DIFF_AVG_NB ) {
/* not enough measures to have a correct estimate */
@ -2224,6 +2231,7 @@ static int audio_decode_frame(VideoState *is)
/* if update the audio clock with the pts */
if ( pkt - > pts ! = AV_NOPTS_VALUE ) {
is - > audio_clock = av_q2d ( is - > audio_st - > time_base ) * pkt - > pts ;
is - > audio_clock_serial = is - > audio_pkt_temp_serial ;
}
}
}
@ -2265,7 +2273,7 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
/* Let's assume the audio driver that is used by SDL has two periods. */
is - > audio_current_pts = is - > audio_clock - ( double ) ( 2 * is - > audio_hw_buf_size + is - > audio_write_buf_size ) / bytes_per_sec ;
is - > audio_current_pts_drift = is - > audio_current_pts - audio_callback_time / 1000000.0 ;
if ( is - > audioq . serial = = is - > audio_pkt_temp _serial )
if ( is - > audioq . serial = = is - > audio_clock _serial )
check_external_clock_sync ( is , is - > audio_current_pts ) ;
}
@ -2851,6 +2859,8 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
update_external_clock_speed ( is , 1.0 ) ;
is - > audio_current_pts_drift = - av_gettime ( ) / 1000000.0 ;
is - > video_current_pts_drift = is - > audio_current_pts_drift ;
is - > audio_clock_serial = - 1 ;
is - > video_clock_serial = - 1 ;
is - > av_sync_type = av_sync_type ;
is - > read_tid = SDL_CreateThread ( read_thread , is ) ;
if ( ! is - > read_tid ) {
@ -3033,6 +3043,8 @@ static void event_loop(VideoState *cur_stream)
stream_seek ( cur_stream , pos , incr , 1 ) ;
} else {
pos = get_master_clock ( cur_stream ) ;
if ( isnan ( pos ) )
pos = ( double ) cur_stream - > seek_pos / AV_TIME_BASE ;
pos + = incr ;
if ( cur_stream - > ic - > start_time ! = AV_NOPTS_VALUE & & pos < cur_stream - > ic - > start_time / ( double ) AV_TIME_BASE )
pos = cur_stream - > ic - > start_time / ( double ) AV_TIME_BASE ;