[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