From fc38bbcd6ab3cbb137ba64d3ec0c560d63b194cf Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Fri, 23 Nov 2012 00:22:35 +0100 Subject: [PATCH 1/3] ffplay: disallow seeking before the start of the file In timestamp based seeking we update the external clock to the seek target, therefore we should use sane timestamps even if libavformat could handle seeking before the start of the file. Signed-off-by: Marton Balint --- ffplay.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ffplay.c b/ffplay.c index 5ba5164173..c5ad70fd43 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2984,6 +2984,8 @@ static void event_loop(VideoState *cur_stream) } else { pos = get_master_clock(cur_stream); 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; stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0); } break; From 2efd01a32f0cc7849794f7a866fddf3991b5f5ce Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Fri, 23 Nov 2012 00:23:11 +0100 Subject: [PATCH 2/3] ffplay: fix updating external clock after seeking Now it should work for the timestamp based and the byte based case as well. Also only update the external clock if the seeking was successful. Signed-off-by: Marton Balint --- ffplay.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index c5ad70fd43..a3bda0eea9 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2669,8 +2669,13 @@ static int read_thread(void *arg) packet_queue_flush(&is->videoq); packet_queue_put(&is->videoq, &flush_pkt); } + if (is->seek_flags & AVSEEK_FLAG_BYTE) { + //FIXME: use a cleaner way to signal obsolete external clock... + update_external_clock_pts(is, (double)AV_NOPTS_VALUE); + } else { + update_external_clock_pts(is, seek_target / (double)AV_TIME_BASE); + } } - update_external_clock_pts(is, (seek_target + ic->start_time) / (double)AV_TIME_BASE); is->seek_req = 0; eof = 0; } From f7eb50f3c0704a0d6e87dd218fc948b82a5e6329 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 3 Nov 2012 00:30:20 +0100 Subject: [PATCH 3/3] ffplay: increase maximum frame duration to 1 hour for streams without TS discontinuity Partially fixes ticket #1707. A-V sync still needs some work after seeking... Signed-off-by: Marton Balint --- ffplay.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index a3bda0eea9..842939a777 100644 --- a/ffplay.c +++ b/ffplay.c @@ -234,6 +234,7 @@ typedef struct VideoState { double video_current_pts; // current displayed pts (different from video_clock if frame fifos are used) 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 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE]; int pictq_size, pictq_rindex, pictq_windex; SDL_mutex *pictq_mutex; @@ -1318,7 +1319,7 @@ retry: /* compute nominal last_duration */ last_duration = vp->pts - is->frame_last_pts; - if (last_duration > 0 && last_duration < 10.0) { + if (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; } @@ -2557,6 +2558,8 @@ static int read_thread(void *arg) if (seek_by_bytes < 0) seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT); + is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0; + /* if seeking requested, we execute it */ if (start_time != AV_NOPTS_VALUE) { int64_t timestamp;