[vlc-devel] [PATCH 08/10] vdpau/display: keep the decoder device to use its internal variables
Steve Lhomme
robux4 at ycbcr.xyz
Fri Nov 22 14:12:36 CET 2019
We always match the screen selected by the decoder device as the
vlc_xcb_parent_Create() call is the same.
It has the same lifetime as the window the display module belongs to.
---
modules/hw/vdpau/display.c | 145 ++++++++++++++++---------------------
1 file changed, 62 insertions(+), 83 deletions(-)
diff --git a/modules/hw/vdpau/display.c b/modules/hw/vdpau/display.c
index d0817e7af65..1cb211b9386 100644
--- a/modules/hw/vdpau/display.c
+++ b/modules/hw/vdpau/display.c
@@ -27,8 +27,6 @@
#include <stdlib.h>
#include <assert.h>
-#include <xcb/xcb.h>
-
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_vout_display.h>
@@ -53,12 +51,10 @@ vlc_module_end()
struct vout_display_sys_t
{
- xcb_connection_t *conn; /**< XCB connection */
- vdp_t *vdp; /**< VDPAU back-end */
+ vlc_decoder_device *dec_device; /**< held reference */
picture_t *current; /**< Currently visible picture */
xcb_window_t window; /**< target window (owned by VDPAU back-end) */
- VdpDevice device; /**< VDPAU device handle */
VdpPresentationQueueTarget target; /**< VDPAU presentation queue target */
VdpPresentationQueue queue; /**< VDPAU presentation queue */
@@ -79,14 +75,16 @@ static void RenderRegion(vout_display_t *vd, VdpOutputSurface target,
#endif
VdpStatus err;
+ vdpau_decoder_device_t *vdpau_dev = GetVDPAUOpaqueDevice(sys->dec_device);
+
/* Create GPU surface for sub-picture */
- err = vdp_bitmap_surface_create(sys->vdp, sys->device, fmt,
+ err = vdp_bitmap_surface_create(vdpau_dev->vdp, vdpau_dev->device, fmt,
reg->fmt.i_visible_width, reg->fmt.i_visible_height, VDP_FALSE,
&surface);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "%s creation failure: %s", "bitmap surface",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_dev->vdp, err));
return;
}
@@ -95,12 +93,12 @@ static void RenderRegion(vout_display_t *vd, VdpOutputSurface target,
const void *data = pic->p[0].p_pixels;
uint32_t pitch = pic->p[0].i_pitch;
- err = vdp_bitmap_surface_put_bits_native(sys->vdp, surface, &data, &pitch,
+ err = vdp_bitmap_surface_put_bits_native(vdpau_dev->vdp, surface, &data, &pitch,
NULL);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "subpicture upload failure: %s",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_dev->vdp, err));
goto out;
}
@@ -132,14 +130,14 @@ static void RenderRegion(vout_display_t *vd, VdpOutputSurface target,
.blend_constant = { 0.f, 0.f, 0.f, 0.f },
};
- err = vdp_output_surface_render_bitmap_surface(sys->vdp, target, &area,
+ err = vdp_output_surface_render_bitmap_surface(vdpau_dev->vdp, target, &area,
surface, NULL, &color, &state, 0);
if (err != VDP_STATUS_OK)
msg_Err(vd, "blending failure: %s",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_dev->vdp, err));
out:/* Destroy GPU surface */
- vdp_bitmap_surface_destroy(sys->vdp, surface);
+ vdp_bitmap_surface_destroy(vdpau_dev->vdp, surface);
}
static void Queue(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
@@ -149,10 +147,11 @@ static void Queue(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
vlc_vdp_output_surface_t *p_sys = pic->p_sys;
VdpOutputSurface surface = p_sys->surface;
VdpStatus err;
+ vdpau_decoder_device_t *vdpau_dev = GetVDPAUOpaqueDevice(sys->dec_device);
VdpPresentationQueueStatus status;
VdpTime ts;
- err = vdp_presentation_queue_query_surface_status(sys->vdp, sys->queue,
+ err = vdp_presentation_queue_query_surface_status(vdpau_dev->vdp, sys->queue,
surface, &status, &ts);
if (err == VDP_STATUS_OK && status != VDP_PRESENTATION_QUEUE_STATUS_IDLE)
msg_Dbg(vd, "surface status: %u", status);
@@ -166,11 +165,11 @@ static void Queue(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
vlc_tick_t now = vlc_tick_now();
VdpTime pts;
- err = vdp_presentation_queue_get_time(sys->vdp, sys->queue, &pts);
+ err = vdp_presentation_queue_get_time(vdpau_dev->vdp, sys->queue, &pts);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "presentation queue time failure: %s",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_dev->vdp, err));
return;
}
@@ -185,17 +184,18 @@ static void Queue(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
pts += MS_FROM_VLC_TICK(delay);
/* Queue picture */
- err = vdp_presentation_queue_display(sys->vdp, sys->queue, surface, 0, 0,
+ err = vdp_presentation_queue_display(vdpau_dev->vdp, sys->queue, surface, 0, 0,
pts);
if (err != VDP_STATUS_OK)
msg_Err(vd, "presentation queue display failure: %s",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_dev->vdp, err));
}
static void Wait(vout_display_t *vd, picture_t *pic)
{
vout_display_sys_t *sys = vd->sys;
xcb_generic_event_t *ev;
+ vdpau_decoder_device_t *vdpau_dev = GetVDPAUOpaqueDevice(sys->dec_device);
picture_t *current = sys->current;
if (current != NULL)
@@ -204,12 +204,12 @@ static void Wait(vout_display_t *vd, picture_t *pic)
VdpTime pts;
VdpStatus err;
- err = vdp_presentation_queue_block_until_surface_idle(sys->vdp,
+ err = vdp_presentation_queue_block_until_surface_idle(vdpau_dev->vdp,
sys->queue, psys->surface, &pts);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "presentation queue blocking error: %s",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_dev->vdp, err));
goto out;
}
picture_Release(current);
@@ -219,13 +219,14 @@ static void Wait(vout_display_t *vd, picture_t *pic)
out:
/* Drain the event queue. TODO: remove sys->conn completely */
- while ((ev = xcb_poll_for_event(sys->conn)) != NULL)
+ while ((ev = xcb_poll_for_event(vdpau_dev->conn)) != NULL)
free(ev);
}
static int Control(vout_display_t *vd, int query, va_list ap)
{
vout_display_sys_t *sys = vd->sys;
+ vdpau_decoder_device_t *vdpau_dev = GetVDPAUOpaqueDevice(sys->dec_device);
switch (query)
{
@@ -248,7 +249,7 @@ static int Control(vout_display_t *vd, int query, va_list ap)
const uint32_t values[] = { place.x, place.y,
place.width, place.height, };
- xcb_configure_window(sys->conn, sys->window,
+ xcb_configure_window(vdpau_dev->conn, sys->window,
XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y|
XCB_CONFIG_WINDOW_WIDTH|XCB_CONFIG_WINDOW_HEIGHT,
values);
@@ -266,7 +267,7 @@ static int Control(vout_display_t *vd, int query, va_list ap)
const uint32_t values[] = { place.x, place.y,
place.width, place.height, };
- xcb_configure_window(sys->conn, sys->window,
+ xcb_configure_window(vdpau_dev->conn, sys->window,
XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y|
XCB_CONFIG_WINDOW_WIDTH|XCB_CONFIG_WINDOW_HEIGHT,
values);
@@ -281,25 +282,10 @@ static int Control(vout_display_t *vd, int query, va_list ap)
msg_Err(vd, "unknown control request %d", query);
return VLC_EGENERIC;
}
- xcb_flush (sys->conn);
+ xcb_flush (vdpau_dev->conn);
return VLC_SUCCESS;
}
-static int xcb_screen_num(xcb_connection_t *conn, const xcb_screen_t *screen)
-{
- const xcb_setup_t *setup = xcb_get_setup(conn);
- unsigned snum = 0;
-
- for (xcb_screen_iterator_t i = xcb_setup_roots_iterator(setup);
- i.rem > 0; xcb_screen_next(&i))
- {
- if (i.data->root == screen->root)
- return snum;
- snum++;
- }
- return -1;
-}
-
static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
video_format_t *fmtp, vlc_video_context *context)
{
@@ -310,34 +296,28 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
if (unlikely(sys == NULL))
return VLC_ENOMEM;
- const xcb_screen_t *screen;
- if (vlc_xcb_parent_Create(VLC_OBJECT(vd), cfg->window,
- &sys->conn, &screen) != VLC_SUCCESS)
+ sys->dec_device = context ? vlc_video_context_HoldDevice(context) : NULL;
+ if (sys->dec_device == NULL)
{
free(sys);
- return VLC_EGENERIC;
+ return VLC_EBADVAR;
}
- /* Load the VDPAU back-end and create a device instance */
- VdpStatus err = vdp_get_x11(cfg->window->display.x11,
- xcb_screen_num(sys->conn, screen),
- &sys->vdp, &sys->device);
- if (err != VDP_STATUS_OK)
- {
- msg_Dbg(vd, "device creation failure: error %d", (int)err);
- xcb_disconnect(sys->conn);
- free(sys);
- return VLC_EGENERIC;
- }
+ vdpau_decoder_device_t *vdpau_decoder = GetVDPAUOpaqueDevice(sys->dec_device);
+ if (vdpau_decoder == NULL)
+ goto error;
+
+ const xcb_screen_t *screen = vdpau_decoder->screen;
const char *info;
- if (vdp_get_information_string(sys->vdp, &info) == VDP_STATUS_OK)
+ if (vdp_get_information_string(vdpau_decoder->vdp, &info) == VDP_STATUS_OK)
msg_Dbg(vd, "using back-end %s", info);
/* Check source format */
video_format_t fmt;
VdpChromaType chroma;
VdpYCbCrFormat format;
+ VdpStatus err;
video_format_ApplyRotation(&fmt, fmtp);
@@ -351,12 +331,12 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
uint32_t w, h;
VdpBool ok;
- err = vdp_video_surface_query_capabilities(sys->vdp, sys->device,
+ err = vdp_video_surface_query_capabilities(vdpau_decoder->vdp, vdpau_decoder->device,
chroma, &ok, &w, &h);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "%s capabilities query failure: %s", "video surface",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_decoder->vdp, err));
goto error;
}
if (!ok || w < fmt.i_width || h < fmt.i_height)
@@ -366,11 +346,11 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
}
err = vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(
- sys->vdp, sys->device, chroma, format, &ok);
+ vdpau_decoder->vdp, vdpau_decoder->device, chroma, format, &ok);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "%s capabilities query failure: %s", "video surface",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_decoder->vdp, err));
goto error;
}
if (!ok)
@@ -386,14 +366,14 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
{
uint32_t min, max;
- err = vdp_video_mixer_query_parameter_value_range(sys->vdp,
- sys->device, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH,
+ err = vdp_video_mixer_query_parameter_value_range(vdpau_decoder->vdp,
+ vdpau_decoder->device, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH,
&min, &max);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "%s capabilities query failure: %s",
"video mixer surface width",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_decoder->vdp, err));
goto error;
}
if (min > fmt.i_width || fmt.i_width > max)
@@ -402,14 +382,14 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
goto error;
}
- err = vdp_video_mixer_query_parameter_value_range(sys->vdp,
- sys->device, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
+ err = vdp_video_mixer_query_parameter_value_range(vdpau_decoder->vdp,
+ vdpau_decoder->device, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
&min, &max);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "%s capabilities query failure: %s",
"video mixer surface height",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_decoder->vdp, err));
goto error;
}
if (min > fmt.i_height || fmt.i_height > max)
@@ -424,8 +404,8 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
sys->height = fmtp->i_visible_height;
/* VDPAU-X11 requires a window dedicated to the back-end */
{
- xcb_pixmap_t pix = xcb_generate_id(sys->conn);
- xcb_create_pixmap(sys->conn, screen->root_depth, pix,
+ xcb_pixmap_t pix = xcb_generate_id(vdpau_decoder->conn);
+ xcb_create_pixmap(vdpau_decoder->conn, screen->root_depth, pix,
screen->root, 1, 1);
uint32_t mask =
@@ -439,17 +419,17 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
vout_display_place_t place;
vout_display_PlacePicture(&place, &vd->source, cfg);
- sys->window = xcb_generate_id(sys->conn);
+ sys->window = xcb_generate_id(vdpau_decoder->conn);
xcb_void_cookie_t c =
- xcb_create_window_checked(sys->conn, screen->root_depth,
+ xcb_create_window_checked(vdpau_decoder->conn, screen->root_depth,
sys->window, cfg->window->handle.xid, place.x, place.y,
place.width, place.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual, mask, values);
- if (vlc_xcb_error_Check(vd, sys->conn, "window creation failure", c))
+ if (vlc_xcb_error_Check(vd, vdpau_decoder->conn, "window creation failure", c))
goto error;
msg_Dbg(vd, "using X11 window 0x%08"PRIx32, sys->window);
- xcb_map_window(sys->conn, sys->window);
+ xcb_map_window(vdpau_decoder->conn, sys->window);
}
/* Check bitmap capabilities (for SPU) */
@@ -463,12 +443,12 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
uint32_t w, h;
VdpBool ok;
- err = vdp_bitmap_surface_query_capabilities(sys->vdp, sys->device,
+ err = vdp_bitmap_surface_query_capabilities(vdpau_decoder->vdp, vdpau_decoder->device,
VDP_RGBA_FORMAT_R8G8B8A8, &ok, &w, &h);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "%s capabilities query failure: %s", "output surface",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_decoder->vdp, err));
ok = VDP_FALSE;
}
if (ok)
@@ -476,22 +456,22 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
}
/* Initialize VDPAU queue */
- err = vdp_presentation_queue_target_create_x11(sys->vdp, sys->device,
+ err = vdp_presentation_queue_target_create_x11(vdpau_decoder->vdp, vdpau_decoder->device,
sys->window, &sys->target);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "%s creation failure: %s", "presentation queue target",
- vdp_get_error_string(sys->vdp, err));
+ vdp_get_error_string(vdpau_decoder->vdp, err));
goto error;
}
- err = vdp_presentation_queue_create(sys->vdp, sys->device, sys->target,
+ err = vdp_presentation_queue_create(vdpau_decoder->vdp, vdpau_decoder->device, sys->target,
&sys->queue);
if (err != VDP_STATUS_OK)
{
msg_Err(vd, "%s creation failure: %s", "presentation queue",
- vdp_get_error_string(sys->vdp, err));
- vdp_presentation_queue_target_destroy(sys->vdp, sys->target);
+ vdp_get_error_string(vdpau_decoder->vdp, err));
+ vdp_presentation_queue_target_destroy(vdpau_decoder->vdp, sys->target);
goto error;
}
@@ -510,8 +490,7 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
return VLC_SUCCESS;
error:
- vdp_release_x11(sys->vdp);
- xcb_disconnect(sys->conn);
+ vlc_decoder_device_Release(sys->dec_device);
free(sys);
return VLC_EGENERIC;
}
@@ -520,13 +499,13 @@ static void Close(vout_display_t *vd)
{
vout_display_sys_t *sys = vd->sys;
- vdp_presentation_queue_destroy(sys->vdp, sys->queue);
- vdp_presentation_queue_target_destroy(sys->vdp, sys->target);
+ vdpau_decoder_device_t *vdpau_dev = GetVDPAUOpaqueDevice(sys->dec_device);
+ vdp_presentation_queue_destroy(vdpau_dev->vdp, sys->queue);
+ vdp_presentation_queue_target_destroy(vdpau_dev->vdp, sys->target);
if (sys->current != NULL)
picture_Release(sys->current);
- vdp_release_x11(sys->vdp);
- xcb_disconnect(sys->conn);
+ vlc_decoder_device_Release(sys->dec_device);
free(sys);
}
--
2.17.1
More information about the vlc-devel
mailing list