diff options
author | Marton Balint <cus@passwd.hu> | 2013-02-16 23:36:07 +0100 |
---|---|---|
committer | Marton Balint <cus@passwd.hu> | 2013-02-27 21:34:12 +0100 |
commit | 26c208cf0ff59efd7786528884a64d35fc42e9bf (patch) | |
tree | 2d9e17fa2ddaccab57c804f7571298152914bc38 /ffplay.c | |
parent | 38f649662c12c0d23d1be6f066c6ca597f6c1cbb (diff) | |
download | ffmpeg-26c208cf0ff59efd7786528884a64d35fc42e9bf.tar.gz |
ffplay: if audio or video clock is invalid return NAN
This helps us not to make bad decision (frame dropping, audio compensation)
right after seeking when we do not know yet the recent audio or video clock.
Signed-off-by: Marton Balint <cus@passwd.hu>
Diffstat (limited to 'ffplay.c')
-rw-r--r-- | ffplay.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -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; |