summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-04-29 15:18:35 +0200
committerwm4 <wm4@nowhere>2014-05-02 01:08:05 +0200
commitd6dc8642aeb470a183cec351b1155463b278b643 (patch)
tree88763338ceda2707f049c9bf22d5af4daa46edd2 /video
parent90a039a5991c20c3a185667348bf7c69dbb4cd19 (diff)
downloadmpv-d6dc8642aeb470a183cec351b1155463b278b643.tar.bz2
mpv-d6dc8642aeb470a183cec351b1155463b278b643.tar.xz
vo_vdpau: always use mp_image for internal buffer queue
Diffstat (limited to 'video')
-rw-r--r--video/out/vo_vdpau.c83
1 files changed, 39 insertions, 44 deletions
diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c
index 97b8245401..9aa081f409 100644
--- a/video/out/vo_vdpau.c
+++ b/video/out/vo_vdpau.c
@@ -84,13 +84,9 @@ struct vdpctx {
VdpOutputSurface screenshot_surface;
int num_output_surfaces;
VdpOutputSurface rgb_surfaces[NUM_BUFFERED_VIDEO];
+ bool rgb_surfaces_used[NUM_BUFFERED_VIDEO];
VdpOutputSurface black_pixel;
- struct buffered_video_surface {
- // Either mpi or rgb_surface is used (never both)
- VdpOutputSurface rgb_surface;
- double pts;
- mp_image_t *mpi;
- } buffered_video[NUM_BUFFERED_VIDEO];
+ struct mp_image *buffered_video[NUM_BUFFERED_VIDEO];
int buffer_pos;
// State for redrawing the screen after seek-reset
@@ -165,7 +161,6 @@ static int render_video_to_output_surface(struct vo *vo,
struct vdp_functions *vdp = vc->vdp;
VdpTime dummy;
VdpStatus vdp_st;
- struct buffered_video_surface *bv = vc->buffered_video;
int dp = vc->buffer_pos;
// Redraw frame from before seek reset?
@@ -181,6 +176,8 @@ static int render_video_to_output_surface(struct vo *vo,
return -1;
}
+ struct mp_image *mpi = vc->buffered_video[dp];
+
vdp_st = vdp->presentation_queue_block_until_surface_idle(vc->flip_queue,
output_surface,
&dummy);
@@ -188,6 +185,7 @@ static int render_video_to_output_surface(struct vo *vo,
"vdp_presentation_queue_block_until_surface_idle");
if (vc->rgb_mode) {
+ VdpOutputSurface surface = (uintptr_t)mpi->planes[0];
int flags = VDP_OUTPUT_SURFACE_RENDER_ROTATE_0;
vdp_st = vdp->output_surface_render_output_surface(output_surface,
NULL, vc->black_pixel,
@@ -196,7 +194,7 @@ static int render_video_to_output_surface(struct vo *vo,
CHECK_VDP_WARNING(vo, "Error clearing screen");
vdp_st = vdp->output_surface_render_output_surface(output_surface,
output_rect,
- bv[dp].rgb_surface,
+ surface,
video_rect,
NULL, NULL, flags);
CHECK_VDP_WARNING(vo, "Error when calling "
@@ -204,7 +202,7 @@ static int render_video_to_output_surface(struct vo *vo,
return 0;
}
- struct mp_image *mpi = bv[dp].mpi;
+
struct mp_vdpau_mixer_frame *frame = mp_vdpau_mixed_frame_get(mpi);
struct mp_vdpau_mixer_opts opts = {0};
if (frame)
@@ -257,31 +255,26 @@ static void set_next_frame_info(struct vo *vo, bool eof)
vo->frame_loaded = true;
// Set pts values
- struct buffered_video_surface *bv = vc->buffered_video;
+ struct mp_image **bv = &vc->buffered_video[0];
if (dqp == 0) { // no future frame/pts available
- vo->next_pts = bv[0].pts;
+ vo->next_pts = bv[0]->pts;
vo->next_pts2 = MP_NOPTS_VALUE;
} else {
- vo->next_pts = bv[dqp].pts;
- vo->next_pts2 = bv[dqp - 1].pts;
+ vo->next_pts = bv[dqp]->pts;
+ vo->next_pts2 = bv[dqp - 1]->pts;
}
}
-static void add_new_video_surface(struct vo *vo, VdpOutputSurface rgb_surface,
- struct mp_image *reserved_mpi, double pts)
+static void add_new_video_surface(struct vo *vo, struct mp_image *mpi)
{
struct vdpctx *vc = vo->priv;
- struct buffered_video_surface *bv = vc->buffered_video;
+ struct mp_image **bv = vc->buffered_video;
- mp_image_unrefp(&bv[NUM_BUFFERED_VIDEO - 1].mpi);
+ mp_image_unrefp(&bv[NUM_BUFFERED_VIDEO - 1]);
for (int i = NUM_BUFFERED_VIDEO - 1; i > 0; i--)
bv[i] = bv[i - 1];
- bv[0] = (struct buffered_video_surface){
- .mpi = reserved_mpi,
- .rgb_surface = rgb_surface,
- .pts = pts,
- };
+ bv[0] = mpi;
vc->buffer_pos = FFMIN(vc->buffer_pos + 1, NUM_BUFFERED_VIDEO - 2);
set_next_frame_info(vo, false);
@@ -301,13 +294,8 @@ static void forget_frames(struct vo *vo, bool seek_reset)
vc->buffer_pos = -1001;
vc->dropped_frame = false;
if (vc->prev_buffer_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){
- .rgb_surface = VDP_INVALID_HANDLE,
- };
- }
+ for (int i = 0; i < NUM_BUFFERED_VIDEO; i++)
+ mp_image_unrefp(&vc->buffered_video[i]);
}
}
@@ -459,6 +447,7 @@ static void free_video_specific(struct vo *vo)
vc->screenshot_surface = VDP_INVALID_HANDLE;
for (int n = 0; n < NUM_BUFFERED_VIDEO; n++) {
+ assert(!vc->rgb_surfaces_used[n]);
if (vc->rgb_surfaces[n] != VDP_INVALID_HANDLE) {
vdp_st = vdp->output_surface_destroy(vc->rgb_surfaces[n]);
CHECK_VDP_WARNING(vo, "Error when calling vdp_output_surface_destroy");
@@ -960,28 +949,30 @@ static void flip_page_timed(struct vo *vo, int64_t pts_us, int duration)
vc->surface_num = WRAP_ADD(vc->surface_num, 1, vc->num_output_surfaces);
}
-static VdpOutputSurface get_rgb_surface(struct vo *vo)
+static void free_rgb_surface(void *ptr)
+{
+ bool *entry = ptr;
+ *entry = false;
+}
+
+static struct mp_image *get_rgb_surface(struct vo *vo)
{
struct vdpctx *vc = vo->priv;
assert(vc->rgb_mode);
for (int n = 0; n < NUM_BUFFERED_VIDEO; n++) {
- VdpOutputSurface surface = vc->rgb_surfaces[n];
- // Note: we expect to be called before add_new_video_surface(), which
- // will lead to vc->buffered_video[NUM_BUFFERED_VIDEO - 1] to be
- // marked unused. So this entries rgb_surface can be reused
- // freely.
- for (int i = 0; i < NUM_BUFFERED_VIDEO - 1; i++) {
- if (vc->buffered_video[i].rgb_surface == surface)
- goto in_use;
+ bool *used = &vc->rgb_surfaces_used[n];
+ if (!*used) {
+ *used = true;
+ struct mp_image mpi = {0};
+ mpi.planes[0] = (void *)(uintptr_t)vc->rgb_surfaces[n];
+ return mp_image_new_custom_ref(&mpi, used, free_rgb_surface);
}
- return surface;
- in_use:;
}
MP_ERR(vo, "no surfaces available in get_rgb_surface\n");
- return VDP_INVALID_HANDLE;
+ return NULL;
}
static void draw_image(struct vo *vo, mp_image_t *mpi)
@@ -989,16 +980,19 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
struct vdpctx *vc = vo->priv;
struct vdp_functions *vdp = vc->vdp;
struct mp_image *reserved_mpi = NULL;
- VdpOutputSurface rgb_surface = VDP_INVALID_HANDLE;
VdpStatus vdp_st;
// Forget previous frames, as we can display a new one now.
vc->prev_buffer_pos = -1001;
+ mp_image_unrefp(&vc->buffered_video[NUM_BUFFERED_VIDEO - 1]);
if (vc->image_format == IMGFMT_VDPAU) {
reserved_mpi = mp_image_new_ref(mpi);
} else if (vc->rgb_mode) {
- rgb_surface = get_rgb_surface(vo);
+ reserved_mpi = get_rgb_surface(vo);
+ if (!reserved_mpi)
+ return;
+ VdpOutputSurface rgb_surface = (uintptr_t)reserved_mpi->planes[0];
if (rgb_surface != VDP_INVALID_HANDLE) {
vdp_st = vdp->output_surface_put_bits_native(rgb_surface,
&(const void *){mpi->planes[0]},
@@ -1025,7 +1019,8 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
}
}
- add_new_video_surface(vo, rgb_surface, reserved_mpi, mpi->pts);
+ reserved_mpi->pts = mpi->pts;
+ add_new_video_surface(vo, reserved_mpi);
return;
}