[vlc-commits] [Git][videolan/vlc][master] 5 commits: xcb/x11: retain picture placement

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Tue Mar 15 08:35:56 UTC 2022



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
3d1449c2 by Rémi Denis-Courmont at 2022-03-15T08:06:11+00:00
xcb/x11: retain picture placement

- - - - -
d321530a by Rémi Denis-Courmont at 2022-03-15T08:06:11+00:00
xcb/x11: cover the whole parent window

To plot the black borders, we need our drawable to cover the entirety
of the parent window.

Refs #26495.

Note that this engenders two regressions that need fixing in following
changesets:
- The video is drawn in the top left, regardless of the video
  alignment setting.
- If the video is shrunk without moving the window (e.g. by cropping),
  damaged pixels are not blacked out.

- - - - -
9223f0d8 by Rémi Denis-Courmont at 2022-03-15T08:06:11+00:00
xcb/x11: place SHM picture correctly

- - - - -
5e93159d by Rémi Denis-Courmont at 2022-03-15T08:06:11+00:00
xcb/x11: place non-SHM picture correctly

- - - - -
3168e929 by Rémi Denis-Courmont at 2022-03-15T08:06:11+00:00
xcb/x11: black out the borders

Fixes #26495.

- - - - -


1 changed file:

- modules/video_output/xcb/x11.c


Changes:

=====================================
modules/video_output/xcb/x11.c
=====================================
@@ -48,6 +48,7 @@ typedef struct vout_display_sys_t
     bool attached;
     uint8_t depth; /* useful bits per pixel */
     video_format_t fmt;
+    vout_display_place_t place;
 } vout_display_sys_t;
 
 static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
@@ -93,6 +94,42 @@ static void Display (vout_display_t *vd, picture_t *pic)
 
     vlc_xcb_Manage(vd, sys->conn);
 
+    /* Black out the borders */
+    xcb_rectangle_t rectv[4], *rect;
+    unsigned int rectc = 0;
+
+    if (sys->place.x > 0) {
+        rect = &rectv[rectc++];
+        rect->x = 0;
+        rect->y = 0;
+        rect->width = sys->place.x;
+        rect->height = vd->cfg->display.height;
+    }
+    if (sys->place.x + sys->place.width < vd->cfg->display.width) {
+        rect = &rectv[rectc++];
+        rect->x = sys->place.x + sys->place.width;
+        rect->y = 0;
+        rect->width = vd->cfg->display.width - rect->x;
+        rect->height = vd->cfg->display.height;
+    }
+    if (sys->place.y > 0) {
+        rect = &rectv[rectc++];
+        rect->x = sys->place.x;
+        rect->y = 0;
+        rect->width = sys->place.width;
+        rect->height = sys->place.y;
+    }
+    if (sys->place.y + sys->place.height < vd->cfg->display.height) {
+        rect = &rectv[rectc++];
+        rect->x = sys->place.x;
+        rect->y = sys->place.y + sys->place.height;
+        rect->width = sys->place.width;
+        rect->height = vd->cfg->display.height - rect->y;
+    }
+
+    xcb_poly_fill_rectangle(conn, sys->window, sys->gc, rectc, rectv);
+
+    /* Draw the picture */
     if (sys->attached)
         ck = xcb_shm_put_image_checked(conn, sys->window, sys->gc,
               /* real width */ pic->p->i_pitch / pic->p->i_pixel_pitch,
@@ -101,18 +138,34 @@ static void Display (vout_display_t *vd, picture_t *pic)
                        /* y */ sys->fmt.i_y_offset,
                    /* width */ sys->fmt.i_visible_width,
                   /* height */ sys->fmt.i_visible_height,
-                               0, 0, sys->depth, XCB_IMAGE_FORMAT_Z_PIXMAP,
-                               0, segment, buf->offset);
+                               sys->place.x, sys->place.y, sys->depth,
+                               XCB_IMAGE_FORMAT_Z_PIXMAP, 0,
+                               segment, buf->offset);
     else {
-        const size_t offset = sys->fmt.i_y_offset * pic->p->i_pitch;
-        const unsigned lines = pic->p->i_lines - sys->fmt.i_y_offset;
+        const size_t offset = sys->fmt.i_x_offset * pic->p->i_pixel_pitch
+                            + sys->fmt.i_y_offset * pic->p->i_pitch;
+        unsigned int lines = pic->p->i_lines - sys->fmt.i_y_offset;
+
+        if (sys->fmt.i_x_offset > 0) {
+            /*
+             * Draw the last line separately as the scan line padding would
+             * potentially reach beyond the end of the picture buffer.
+             */
+            lines--;
+            xcb_put_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, sys->window,
+                          sys->gc, pic->p->i_visible_pitch, 1,
+                          sys->place.x, sys->place.y + sys->place.height - 1,
+                          0, sys->depth, pic->p->i_visible_pitch,
+                          pic->p->p_pixels + offset + lines * pic->p->i_pitch);
+        }
 
         ck = xcb_put_image_checked(conn, XCB_IMAGE_FORMAT_Z_PIXMAP,
-                               sys->window, sys->gc,
-                               pic->p->i_pitch / pic->p->i_pixel_pitch,
-                               lines, -sys->fmt.i_x_offset, 0, 0, sys->depth,
-                               pic->p->i_pitch * lines,
-                               pic->p->p_pixels + offset);
+                                   sys->window, sys->gc,
+                                   pic->p->i_pitch / pic->p->i_pixel_pitch,
+                                   lines, sys->place.x, sys->place.y,
+                                   0, sys->depth, pic->p->i_pitch * lines,
+                                   pic->p->p_pixels + offset);
+
     }
 
     /* Wait for reply. This makes sure that the X server gets CPU time to
@@ -146,41 +199,38 @@ static int Control(vout_display_t *vd, int query)
     vout_display_sys_t *sys = vd->sys;
 
     switch (query) {
-    case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
+    case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: {
+        uint32_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
+        const uint32_t values[] = {
+            vd->cfg->display.width, vd->cfg->display.height,
+        };
+
+        xcb_configure_window(sys->conn, sys->window, mask, values);
+    }
+        /* fall through */
     case VOUT_DISPLAY_CHANGE_ZOOM:
     case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
     case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
     case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
     {
         video_format_t src, *fmt = &sys->fmt;
-        vout_display_place_t place;
+        vout_display_place_t *place = &sys->place;
         int ret = VLC_SUCCESS;
 
-        vout_display_PlacePicture(&place, vd->source, vd->cfg);
-
-        uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
-        const uint32_t values[] = {
-            place.x, place.y, place.width, place.height
-        };
+        vout_display_PlacePicture(place, vd->source, vd->cfg);
 
-        if (place.width  != sys->fmt.i_visible_width
-         || place.height != sys->fmt.i_visible_height)
-        {
-            mask |= XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
+        if (place->width  != sys->fmt.i_visible_width
+         || place->height != sys->fmt.i_visible_height)
             ret = VLC_EGENERIC;
-        }
-
-        /* Move the picture within the window */
-        xcb_configure_window(sys->conn, sys->window, mask, values);
 
         video_format_ApplyRotation(&src, vd->source);
-        fmt->i_width  = src.i_width  * place.width / src.i_visible_width;
-        fmt->i_height = src.i_height * place.height / src.i_visible_height;
+        fmt->i_width  = src.i_width  * place->width / src.i_visible_width;
+        fmt->i_height = src.i_height * place->height / src.i_visible_height;
 
-        fmt->i_visible_width  = place.width;
-        fmt->i_visible_height = place.height;
-        fmt->i_x_offset = src.i_x_offset * place.width / src.i_visible_width;
-        fmt->i_y_offset = src.i_y_offset * place.height / src.i_visible_height;
+        fmt->i_visible_width  = place->width;
+        fmt->i_visible_height = place->height;
+        fmt->i_x_offset = src.i_x_offset * place->width / src.i_visible_width;
+        fmt->i_y_offset = src.i_y_offset * place->height / src.i_visible_height;
 
         return ret;
     }
@@ -322,15 +372,15 @@ static int Open (vout_display_t *vd,
         /* XCB_CW_COLORMAP */
         cmap,
     };
-    vout_display_place_t place;
+    vout_display_place_t *place = &sys->place;
 
-    vout_display_PlacePicture(&place, vd->source, vd->cfg);
+    vout_display_PlacePicture(place, vd->source, vd->cfg);
     sys->window = xcb_generate_id (conn);
     sys->gc = xcb_generate_id (conn);
-
-    xcb_create_window(conn, sys->depth, sys->window, vd->cfg->window->handle.xid,
-        place.x, place.y, place.width, place.height, 0,
-        XCB_WINDOW_CLASS_INPUT_OUTPUT, vid, mask, values);
+    xcb_create_window(conn, sys->depth, sys->window,
+                      vd->cfg->window->handle.xid,
+                      0, 0, vd->cfg->display.width, vd->cfg->display.height, 0,
+                      XCB_WINDOW_CLASS_INPUT_OUTPUT, vid, mask, values);
     xcb_map_window(conn, sys->window);
     /* Create graphic context (I wonder why the heck do we need this) */
     xcb_create_gc(conn, sys->gc, sys->window, 0, NULL);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/155036d4a4a071ac21812f0d6723e5c531ed4a08...3168e9296e3b50b47e46d6547b3bbb4024afe482

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/155036d4a4a071ac21812f0d6723e5c531ed4a08...3168e9296e3b50b47e46d6547b3bbb4024afe482
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list