@ -243,13 +243,8 @@ typedef struct VideoState {
SDL_cond * subpq_cond ;
SDL_cond * subpq_cond ;
double frame_timer ;
double frame_timer ;
double frame_last_pts ;
double frame_last_duration ;
double frame_last_dropped_pts ;
double frame_last_returned_time ;
double frame_last_returned_time ;
double frame_last_filter_delay ;
double frame_last_filter_delay ;
int64_t frame_last_dropped_pos ;
int frame_last_dropped_serial ;
int video_stream ;
int video_stream ;
AVStream * video_st ;
AVStream * video_st ;
PacketQueue videoq ;
PacketQueue videoq ;
@ -1340,14 +1335,12 @@ static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial
set_clock ( & is - > vidclk , pts , serial ) ;
set_clock ( & is - > vidclk , pts , serial ) ;
sync_clock_to_slave ( & is - > extclk , & is - > vidclk ) ;
sync_clock_to_slave ( & is - > extclk , & is - > vidclk ) ;
is - > video_current_pos = pos ;
is - > video_current_pos = pos ;
is - > frame_last_pts = pts ;
}
}
/* called to display each frame */
/* called to display each frame */
static void video_refresh ( void * opaque , double * remaining_time )
static void video_refresh ( void * opaque , double * remaining_time )
{
{
VideoState * is = opaque ;
VideoState * is = opaque ;
VideoPicture * vp ;
double time ;
double time ;
SubPicture * sp , * sp2 ;
SubPicture * sp , * sp2 ;
@ -1370,17 +1363,14 @@ static void video_refresh(void *opaque, double *remaining_time)
redisplay = pictq_prev_picture ( is ) ;
redisplay = pictq_prev_picture ( is ) ;
retry :
retry :
if ( is - > pictq_size = = 0 ) {
if ( is - > pictq_size = = 0 ) {
SDL_LockMutex ( is - > pictq_mutex ) ;
if ( is - > frame_last_dropped_pts ! = AV_NOPTS_VALUE & & is - > frame_last_dropped_pts > is - > frame_last_pts ) {
update_video_pts ( is , is - > frame_last_dropped_pts , is - > frame_last_dropped_pos , is - > frame_last_dropped_serial ) ;
is - > frame_last_dropped_pts = AV_NOPTS_VALUE ;
}
SDL_UnlockMutex ( is - > pictq_mutex ) ;
// nothing to do, no picture to display in the queue
// nothing to do, no picture to display in the queue
} else {
} else {
double last_duration , duration , delay ;
double last_duration , duration , delay ;
VideoPicture * vp , * lastvp ;
/* dequeue the picture */
/* dequeue the picture */
vp = & is - > pictq [ is - > pictq_rindex ] ;
vp = & is - > pictq [ is - > pictq_rindex ] ;
lastvp = & is - > pictq [ ( is - > pictq_rindex + VIDEO_PICTURE_QUEUE_SIZE - 1 ) % VIDEO_PICTURE_QUEUE_SIZE ] ;
if ( vp - > serial ! = is - > videoq . serial ) {
if ( vp - > serial ! = is - > videoq . serial ) {
pictq_next_picture ( is ) ;
pictq_next_picture ( is ) ;
@ -1392,15 +1382,11 @@ retry:
goto display ;
goto display ;
/* compute nominal last_duration */
/* compute nominal last_duration */
last_duration = vp - > pts - is - > frame_last_pts ;
last_duration = vp_duration ( is , lastvp , vp ) ;
if ( ! isnan ( last_duration ) & & last_duration > 0 & & last_duration < is - > max_frame_duration ) {
/* if duration of the last frame was sane, update last_duration in video state */
is - > frame_last_duration = last_duration ;
}
if ( redisplay )
if ( redisplay )
delay = 0.0 ;
delay = 0.0 ;
else
else
delay = compute_target_delay ( is - > frame_ last_duration, is ) ;
delay = compute_target_delay ( last_duration , is ) ;
time = av_gettime ( ) / 1000000.0 ;
time = av_gettime ( ) / 1000000.0 ;
if ( time < is - > frame_timer + delay & & ! redisplay ) {
if ( time < is - > frame_timer + delay & & ! redisplay ) {
@ -1689,10 +1675,7 @@ static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *s
SDL_CondWait ( is - > pictq_cond , is - > pictq_mutex ) ;
SDL_CondWait ( is - > pictq_cond , is - > pictq_mutex ) ;
}
}
is - > video_current_pos = - 1 ;
is - > video_current_pos = - 1 ;
is - > frame_last_pts = AV_NOPTS_VALUE ;
is - > frame_last_duration = 0 ;
is - > frame_timer = ( double ) av_gettime ( ) / 1000000.0 ;
is - > frame_timer = ( double ) av_gettime ( ) / 1000000.0 ;
is - > frame_last_dropped_pts = AV_NOPTS_VALUE ;
SDL_UnlockMutex ( is - > pictq_mutex ) ;
SDL_UnlockMutex ( is - > pictq_mutex ) ;
return 0 ;
return 0 ;
}
}
@ -1721,23 +1704,17 @@ static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *s
frame - > sample_aspect_ratio = av_guess_sample_aspect_ratio ( is - > ic , is - > video_st , frame ) ;
frame - > sample_aspect_ratio = av_guess_sample_aspect_ratio ( is - > ic , is - > video_st , frame ) ;
if ( framedrop > 0 | | ( framedrop & & get_master_sync_type ( is ) ! = AV_SYNC_VIDEO_MASTER ) ) {
if ( framedrop > 0 | | ( framedrop & & get_master_sync_type ( is ) ! = AV_SYNC_VIDEO_MASTER ) ) {
SDL_LockMutex ( is - > pictq_mutex ) ;
if ( frame - > pts ! = AV_NOPTS_VALUE ) {
if ( is - > frame_last_pts ! = AV_NOPTS_VALUE & & frame - > pts ! = AV_NOPTS_VALUE ) {
double diff = dpts - get_master_clock ( is ) ;
double clockdiff = get_clock ( & is - > vidclk ) - get_master_clock ( is ) ;
if ( ! isnan ( diff ) & & fabs ( diff ) < AV_NOSYNC_THRESHOLD & &
double ptsdiff = dpts - is - > frame_last_pts ;
diff - is - > frame_last_filter_delay < 0 & &
if ( ! isnan ( clockdiff ) & & fabs ( clockdiff ) < AV_NOSYNC_THRESHOLD & &
* serial = = is - > vidclk . serial & &
! isnan ( ptsdiff ) & & ptsdiff > 0 & & ptsdiff < AV_NOSYNC_THRESHOLD & &
clockdiff + ptsdiff - is - > frame_last_filter_delay < 0 & &
is - > videoq . nb_packets ) {
is - > videoq . nb_packets ) {
is - > frame_last_dropped_pos = av_frame_get_pkt_pos ( frame ) ;
is - > frame_last_dropped_pts = dpts ;
is - > frame_last_dropped_serial = * serial ;
is - > frame_drops_early + + ;
is - > frame_drops_early + + ;
av_frame_unref ( frame ) ;
av_frame_unref ( frame ) ;
ret = 0 ;
ret = 0 ;
}
}
}
}
SDL_UnlockMutex ( is - > pictq_mutex ) ;
}
}
return ret ;
return ret ;