summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-10-01 23:45:30 +0200
committerwm4 <wm4@nowhere>2013-10-02 00:38:23 +0200
commit7be13b4690fa179cc83b0dcfd0f3bd2f8b680847 (patch)
treeea210f30312cbe19e72272a4d414f89d38d354bd /video
parented9295c250ddfb845e48f123343e7b02326e8920 (diff)
downloadmpv-7be13b4690fa179cc83b0dcfd0f3bd2f8b680847.tar.bz2
mpv-7be13b4690fa179cc83b0dcfd0f3bd2f8b680847.tar.xz
vo_vdpau: don't blank screen on VOCTRL_RESET
vo_vdpau is the only VO which implements VOCTRL_RESET. Redrawing the last output frame is hard, because the output could consist of several source video frames with certain types of post-processing (deinterlacing). Implement redrawing as special case by keeping the previous video frames aside until at least one new frame is decoded. This improves the previous commit, but is separate, because it's rather complicated.
Diffstat (limited to 'video')
-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))