summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/vo_vdpau.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c
index 581daf2659..bd2b5703ff 100644
--- a/video/out/vo_vdpau.c
+++ b/video/out/vo_vdpau.c
@@ -97,6 +97,10 @@ struct vdpctx {
mp_image_t *mpi;
} buffered_video[NUM_BUFFERED_VIDEO];
int deint_queue_pos;
+
+ // State for redrawing the screen after seek-reset
+ int prev_deint_queue_pos;
+
int output_surface_width, output_surface_height;
int force_yuv;
@@ -222,7 +226,13 @@ static int render_video_to_output_surface(struct vo *vo,
struct vdp_functions *vdp = vc->vdp;
VdpTime dummy;
VdpStatus vdp_st;
- if (vc->deint_queue_pos < 0) {
+ struct buffered_video_surface *bv = vc->buffered_video;
+ int dp = vc->deint_queue_pos;
+
+ // Redraw frame from before seek reset?
+ if (dp < 0)
+ dp = vc->prev_deint_queue_pos;
+ if (dp < 0) {
// At least clear the screen if there is nothing to render
int flags = VDP_OUTPUT_SURFACE_RENDER_ROTATE_0;
vdp_st = vdp->output_surface_render_output_surface(output_surface,
@@ -232,9 +242,6 @@ static int render_video_to_output_surface(struct vo *vo,
return -1;
}
- struct buffered_video_surface *bv = vc->buffered_video;
- unsigned int dp = vc->deint_queue_pos;
-
vdp_st = vdp->presentation_queue_block_until_surface_idle(vc->flip_queue,
output_surface,
&dummy);
@@ -362,19 +369,28 @@ static void add_new_video_surface(struct vo *vo, VdpVideoSurface surface,
set_next_frame_info(vo, false);
}
-static void forget_frames(struct vo *vo)
+static void forget_frames(struct vo *vo, bool seek_reset)
{
struct vdpctx *vc = vo->priv;
+ if (seek_reset) {
+ if (vc->deint_queue_pos >= 0)
+ vc->prev_deint_queue_pos = vc->deint_queue_pos;
+ } else {
+ vc->prev_deint_queue_pos = -1001;
+ }
+
vc->deint_queue_pos = -1001;
vc->dropped_frame = false;
- for (int i = 0; i < NUM_BUFFERED_VIDEO; i++) {
- struct buffered_video_surface *p = vc->buffered_video + i;
- mp_image_unrefp(&p->mpi);
- *p = (struct buffered_video_surface){
- .surface = VDP_INVALID_HANDLE,
- .rgb_surface = VDP_INVALID_HANDLE,
- };
+ if (vc->prev_deint_queue_pos < 0) {
+ for (int i = 0; i < NUM_BUFFERED_VIDEO; i++) {
+ struct buffered_video_surface *p = vc->buffered_video + i;
+ mp_image_unrefp(&p->mpi);
+ *p = (struct buffered_video_surface){
+ .surface = VDP_INVALID_HANDLE,
+ .rgb_surface = VDP_INVALID_HANDLE,
+ };
+ }
}
}
@@ -704,7 +720,7 @@ static void free_video_specific(struct vo *vo)
struct vdp_functions *vdp = vc->vdp;
VdpStatus vdp_st;
- forget_frames(vo);
+ forget_frames(vo, false);
if (vc->video_mixer != VDP_INVALID_HANDLE) {
vdp_st = vdp->video_mixer_destroy(vc->video_mixer);
@@ -775,7 +791,7 @@ static int initialize_vdpau_objects(struct vo *vo)
return -1;
}
- forget_frames(vo);
+ forget_frames(vo, false);
resize(vo);
return 0;
}
@@ -788,7 +804,7 @@ static void mark_vdpau_objects_uninitialized(struct vo *vo)
vc->video_surfaces[i].surface = VDP_INVALID_HANDLE;
for (int i = 0; i < NUM_BUFFERED_VIDEO; i++)
vc->rgb_surfaces[i] = VDP_INVALID_HANDLE;
- forget_frames(vo);
+ forget_frames(vo, false);
vc->black_pixel = VDP_INVALID_HANDLE;
vc->video_mixer = VDP_INVALID_HANDLE;
vc->flip_queue = VDP_INVALID_HANDLE;
@@ -1317,6 +1333,9 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
VdpOutputSurface rgb_surface = VDP_INVALID_HANDLE;
VdpStatus vdp_st;
+ // Forget previous frames, as we can display a new one now.
+ vc->prev_deint_queue_pos = -1001;
+
if (IMGFMT_IS_VDPAU(vc->image_format)) {
surface = (VdpVideoSurface)(intptr_t)mpi->planes[3];
reserved_mpi = mp_image_new_ref(mpi);
@@ -1636,7 +1655,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
video_to_output_surface(vo);
return true;
case VOCTRL_RESET:
- forget_frames(vo);
+ forget_frames(vo, true);
return true;
case VOCTRL_SCREENSHOT: {
if (!status_ok(vo))