[vlc-commits] xcb: add X11 visual type helper

Rémi Denis-Courmont git at videolan.org
Wed Dec 19 20:11:38 CET 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Dec 19 19:37:37 2018 +0200| [57cd6ed67b64c5f5d2c2ae6e9ae1b0aee3a4a354] | committer: Rémi Denis-Courmont

xcb: add X11 visual type helper

This converts an X11 visual type to a VLC video format.

Given that the PutImage request (and the likes of it) can only identify
the pixmap format by depth, the helper assumes that there is only one
pixmap format for a given depth.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=57cd6ed67b64c5f5d2c2ae6e9ae1b0aee3a4a354
---

 modules/video_output/xcb/pictures.c | 103 ++++++++++++++++++++++++++++++++++++
 modules/video_output/xcb/pictures.h |  10 +++-
 2 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/modules/video_output/xcb/pictures.c b/modules/video_output/xcb/pictures.c
index bcace0f76c..602a1a1b4f 100644
--- a/modules/video_output/xcb/pictures.c
+++ b/modules/video_output/xcb/pictures.c
@@ -45,6 +45,109 @@
 #include "pictures.h"
 #include "events.h"
 
+const xcb_format_t *vlc_xcb_DepthToPixmapFormat(const xcb_setup_t *setup,
+                                                uint_fast8_t depth)
+{
+    const xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
+
+    for (int i = xcb_setup_pixmap_formats_length(setup); i > 0; i--, fmt++)
+        if (fmt->depth == depth)
+        {   /* Sanity check: unusable format is as good as none. */
+            if (unlikely(fmt->bits_per_pixel < depth
+                      || (fmt->scanline_pad % fmt->bits_per_pixel)))
+                return NULL;
+            return fmt;
+        }
+    return NULL; /* should never happen, buggy server */
+}
+
+/** Convert X11 visual to VLC video format */
+bool vlc_xcb_VisualToFormat(const xcb_setup_t *setup, uint_fast8_t depth,
+                            const xcb_visualtype_t *vt,
+                            video_format_t *restrict f)
+{
+    if (vt->_class == XCB_VISUAL_CLASS_TRUE_COLOR)
+    {
+        /* Check that VLC supports the TrueColor visual. */
+        switch (depth)
+        {
+            /* TODO: 32 bits RGBA */
+            /* TODO: 30 bits HDR RGB */
+            case 24:
+                if (vlc_popcount(vt->red_mask) == 8
+                 && vlc_popcount(vt->green_mask) == 8
+                 && vlc_popcount(vt->red_mask) == 8)
+                    break; /* 32-bits ARGB or 24-bits RGB */
+                return false;
+            case 16:
+            case 15:
+                if (vlc_popcount(vt->red_mask) == 5
+                 && vlc_popcount(vt->green_mask) == (depth - 10)
+                 && vlc_popcount(vt->red_mask) == 5)
+                    break; /* 16-bits or 15-bits RGB */
+                return false;
+            case 8:
+                /* XXX: VLC does not use masks for 8-bits. Untested. */
+                break;
+            default:
+                return false;
+        }
+    }
+    else
+    if (vt->_class == XCB_VISUAL_CLASS_STATIC_GRAY)
+    {
+        if (depth != 8)
+            return false;
+    }
+
+    const xcb_format_t *fmt = vlc_xcb_DepthToPixmapFormat(setup, depth);
+    if (unlikely(fmt == NULL))
+        return false;
+
+    /* Byte sex is a non-issue for 8-bits. It can be worked around with
+     * RGB masks for 24-bits. Too bad for 15-bits and 16-bits. */
+    if (fmt->bits_per_pixel == 16 && setup->image_byte_order != ORDER)
+        return false;
+
+    /* Check that VLC supports the pixel format. */
+    switch (fmt->depth)
+    {
+        case 24:
+            if (fmt->bits_per_pixel == 32)
+                f->i_chroma = VLC_CODEC_RGB32;
+            else if (fmt->bits_per_pixel == 24)
+                f->i_chroma = VLC_CODEC_RGB24;
+            else
+                return false;
+            break;
+        case 16:
+            if (fmt->bits_per_pixel != 16)
+                return false;
+            f->i_chroma = VLC_CODEC_RGB16;
+            break;
+        case 15:
+            if (fmt->bits_per_pixel != 16)
+                return false;
+            f->i_chroma = VLC_CODEC_RGB15;
+            break;
+        case 8:
+            if (fmt->bits_per_pixel != 8)
+                return false;
+            if (vt->_class == XCB_VISUAL_CLASS_TRUE_COLOR)
+                f->i_chroma = VLC_CODEC_RGB8;
+            else
+                f->i_chroma = VLC_CODEC_GREY;
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
+
+    f->i_rmask = vt->red_mask;
+    f->i_gmask = vt->green_mask;
+    f->i_bmask = vt->blue_mask;
+    return true;
+}
+
 /** Check MIT-SHM shared memory support */
 bool XCB_shm_Check (vlc_object_t *obj, xcb_connection_t *conn)
 {
diff --git a/modules/video_output/xcb/pictures.h b/modules/video_output/xcb/pictures.h
index 9cb2deae24..3e58abef6a 100644
--- a/modules/video_output/xcb/pictures.h
+++ b/modules/video_output/xcb/pictures.h
@@ -26,9 +26,17 @@
 # define ORDER XCB_IMAGE_ORDER_LSB_FIRST
 #endif
 
+#include <stdbool.h>
+#include <stdint.h>
+#include <xcb/xcb.h>
+#include <xcb/shm.h>
 #include <vlc_picture.h>
 #include <vlc_vout_display.h>
-#include <xcb/shm.h>
+
+const xcb_format_t *vlc_xcb_DepthToPixmapFormat(const xcb_setup_t *,
+                                                uint_fast8_t depth);
+bool vlc_xcb_VisualToFormat(const xcb_setup_t *, uint_fast8_t depth,
+                            const xcb_visualtype_t *, video_format_t *);
 
 bool XCB_shm_Check (vlc_object_t *obj, xcb_connection_t *conn);
 int XCB_picture_Alloc (vout_display_t *, picture_resource_t *, size_t size,



More information about the vlc-commits mailing list