summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-07 21:50:16 +0200
committerwm4 <wm4@nowhere>2014-05-07 21:50:16 +0200
commitf3362e22ebd8a39419c8225c3254fbbebe57d6e9 (patch)
treed520b97bc5b948b060417b2f7a4bdf8d4b8824cb /player
parentbd2bcc4399a86420523a1c0bdf3d3e2a9d683513 (diff)
downloadmpv-f3362e22ebd8a39419c8225c3254fbbebe57d6e9.tar.bz2
mpv-f3362e22ebd8a39419c8225c3254fbbebe57d6e9.tar.xz
player: remove VO from seeking code path
Until recently, the VO was an unavoidable part of the seeking code path. This was because vdpau deinterlacing could double the framerate, and hr- seek and framestepping etc. all had to "see" the additional frames. But we've removed the frame doubling from the vdpau VO and moved it into a video filter (vf_vdpaupp), and there's no reason left why the VO should participate in seeking. Instead of queuing frames to the VO during seek and skipping them afterwards, drop the frames early. This actually might make seeking with vo_vdpau and software decoding faster, although I haven't measured it.
Diffstat (limited to 'player')
-rw-r--r--player/playloop.c5
-rw-r--r--player/video.c32
2 files changed, 26 insertions, 11 deletions
diff --git a/player/playloop.c b/player/playloop.c
index 56ad70c484..e7637b07f5 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -736,6 +736,8 @@ void add_frame_pts(struct MPContext *mpctx, double pts)
mpctx->vo_pts_history_seek_ts++; // mark discontinuity
return;
}
+ if (mpctx->vo_pts_history_pts[0] == pts) // may be called multiple times
+ return;
for (int n = MAX_NUM_VO_PTS - 1; n >= 1; n--) {
mpctx->vo_pts_history_seek[n] = mpctx->vo_pts_history_seek[n - 1];
mpctx->vo_pts_history_pts[n] = mpctx->vo_pts_history_pts[n - 1];
@@ -1021,9 +1023,6 @@ void run_playloop(struct MPContext *mpctx)
video_left = r > 0;
- if (mpctx->video_next_pts != MP_NOPTS_VALUE && endpts != MP_NOPTS_VALUE)
- video_left &= mpctx->video_next_pts < endpts;
-
if (r == 2)
MP_VERBOSE(mpctx, "frametime=%5.3f\n", frame_time);
diff --git a/player/video.c b/player/video.c
index 35ad3e7b39..957d4d86ac 100644
--- a/player/video.c
+++ b/player/video.c
@@ -424,7 +424,8 @@ static void init_vo(struct MPContext *mpctx)
// Fill the VO buffer with a newly filtered or decoded image.
// Returns: -1: error, 0: EOF, 1: ok or progress was made
-static int video_output_image(struct MPContext *mpctx, bool reconfig_ok)
+static int video_output_image(struct MPContext *mpctx, double endpts,
+ bool reconfig_ok)
{
struct vf_chain *vf = mpctx->d_video->vfilter;
struct vo *vo = mpctx->video_out;
@@ -439,6 +440,27 @@ static int video_output_image(struct MPContext *mpctx, bool reconfig_ok)
if (r < 0)
return r; // error
+ vf_output_frame(vf, false);
+ if (vf->output) {
+ double pts = vf->output->pts;
+
+ // Always add these; they make backstepping after seeking faster.
+ add_frame_pts(mpctx, pts);
+
+ bool drop = false;
+ if (mpctx->hrseek_active && pts < mpctx->hrseek_pts - .005)
+ drop = true;
+ if (endpts != MP_NOPTS_VALUE && pts >= endpts) {
+ drop = true;
+ r = 0; // EOF
+ }
+ if (drop) {
+ talloc_free(vf->output);
+ vf->output = NULL;
+ return r;
+ }
+ }
+
// Filter output is different from VO input?
bool need_vo_reconfig = !vo->params ||
!mp_image_params_equals(&vf->output_params, vo->params);
@@ -496,7 +518,7 @@ int update_video(struct MPContext *mpctx, double endpts, bool reconfig_ok,
return 0;
}
- int r = video_output_image(mpctx, reconfig_ok);
+ int r = video_output_image(mpctx, endpts, reconfig_ok);
if (r < 0)
return r;
@@ -512,12 +534,6 @@ int update_video(struct MPContext *mpctx, double endpts, bool reconfig_ok,
}
double pts = vo_get_next_pts(video_out, 0);
- if (endpts == MP_NOPTS_VALUE || pts < endpts)
- add_frame_pts(mpctx, pts);
- if (mpctx->hrseek_active && pts < mpctx->hrseek_pts - .005) {
- vo_skip_frame(video_out);
- return 1;
- }
mpctx->hrseek_active = false;
double last_pts = mpctx->video_next_pts;
if (last_pts == MP_NOPTS_VALUE)