[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