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.
This commit is contained in:
wm4 2014-05-07 21:50:16 +02:00
parent bd2bcc4399
commit f3362e22eb
4 changed files with 26 additions and 17 deletions

View File

@ -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);

View File

@ -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)

View File

@ -354,11 +354,6 @@ static void shift_queue(struct vo *vo)
vo->video_queue[n] = vo->video_queue[n + 1];
}
void vo_skip_frame(struct vo *vo)
{
shift_queue(vo);
}
void vo_new_frame_imminent(struct vo *vo)
{
assert(vo->num_video_queue > 0);

View File

@ -279,7 +279,6 @@ bool vo_get_want_redraw(struct vo *vo);
bool vo_has_next_frame(struct vo *vo, bool eof);
double vo_get_next_pts(struct vo *vo, int index);
bool vo_needs_new_image(struct vo *vo);
void vo_skip_frame(struct vo *vo);
void vo_new_frame_imminent(struct vo *vo);
void vo_draw_osd(struct vo *vo, struct osd_state *osd);
void vo_flip_page(struct vo *vo, int64_t pts_us, int duration);