summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/vo_x11.c117
1 files changed, 52 insertions, 65 deletions
diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c
index 1cd8bdbe96..bda0f5c100 100644
--- a/video/out/vo_x11.c
+++ b/video/out/vo_x11.c
@@ -57,6 +57,7 @@ struct priv {
struct mp_image *original_image;
XImage *myximage[2];
+ struct mp_image mp_ximages[2];
int depth;
GC gc;
@@ -65,8 +66,6 @@ struct priv {
struct mp_rect src;
struct mp_rect dst;
- int src_w, src_h;
- int dst_w, dst_h;
struct mp_osd_res osd;
struct mp_sws_context *sws;
@@ -74,7 +73,6 @@ struct priv {
XVisualInfo vinfo;
int current_buf;
- bool reset_view;
int Shmem_Flag;
XShmSegmentInfo Shminfo[2];
@@ -167,8 +165,6 @@ static int reconfig(struct vo *vo, struct mp_image_params *fmt)
mp_image_unrefp(&p->original_image);
- p->sws->src = *fmt;
-
vo_x11_config_vo_window(vo);
if (!resize(vo))
@@ -181,34 +177,25 @@ static bool resize(struct vo *vo)
{
struct priv *p = vo->priv;
- for (int i = 0; i < 2; i++)
- freeMyXImage(p, i);
-
- vo_get_src_dst_rects(vo, &p->src, &p->dst, &p->osd);
-
- p->src_w = p->src.x1 - p->src.x0;
- p->src_h = p->src.y1 - p->src.y0;
- p->dst_w = p->dst.x1 - p->dst.x0;
- p->dst_h = p->dst.y1 - p->dst.y0;
+ // Attempt to align. We don't know the size in bytes yet (????), so just
+ // assume worst case (1 byte per pixel).
+ int nw = MPMAX(1, MP_ALIGN_UP(vo->dwidth, MP_IMAGE_BYTE_ALIGN));
+ int nh = MPMAX(1, vo->dheight);
- // p->osd contains the parameters assuming OSD rendering in window
- // coordinates, but OSD can only be rendered in the intersection
- // between window and video rectangle (i.e. not into panscan borders).
- p->osd.w = p->dst_w;
- p->osd.h = p->dst_h;
- p->osd.mt = MPMIN(0, p->osd.mt);
- p->osd.mb = MPMIN(0, p->osd.mb);
- p->osd.mr = MPMIN(0, p->osd.mr);
- p->osd.ml = MPMIN(0, p->osd.ml);
+ if (nw > p->image_width || nh > p->image_height) {
+ for (int i = 0; i < 2; i++)
+ freeMyXImage(p, i);
- mp_input_set_mouse_transform(vo->input_ctx, &p->dst, NULL);
+ p->image_width = nw;
+ p->image_height = nh;
- p->image_width = (p->dst_w + 7) & (~7);
- p->image_height = p->dst_h;
-
- for (int i = 0; i < 2; i++) {
- if (!getMyXImage(p, i))
- return false;
+ for (int i = 0; i < 2; i++) {
+ if (!getMyXImage(p, i)) {
+ p->image_width = 0;
+ p->image_height = 0;
+ return false;
+ }
+ }
}
int mpfmt = 0;
@@ -236,19 +223,32 @@ static bool resize(struct vo *vo)
}
MP_VERBOSE(vo, "Using mp format: %s\n", mp_imgfmt_to_name(mpfmt));
- p->sws->dst = (struct mp_image_params) {
- .imgfmt = mpfmt,
- .w = p->dst_w,
- .h = p->dst_h,
- .p_w = 1,
- .p_h = 1,
- };
- mp_image_params_guess_csp(&p->sws->dst);
+ for (int i = 0; i < 2; i++) {
+ struct mp_image *img = &p->mp_ximages[i];
+ *img = (struct mp_image){0};
+ mp_image_setfmt(img, mpfmt);
+ mp_image_set_size(img, p->image_width, p->image_height);
+ img->planes[0] = p->myximage[i]->data;
+ img->stride[0] = p->myximage[i]->bytes_per_line;
+
+ mp_image_params_guess_csp(&img->params);
+ }
- if (mp_sws_reinit(p->sws) < 0)
- return false;
+ vo_get_src_dst_rects(vo, &p->src, &p->dst, &p->osd);
+
+ if (vo->params) {
+ p->sws->src = *vo->params;
+ p->sws->src.w = mp_rect_w(p->src);
+ p->sws->src.h = mp_rect_h(p->src);
+
+ p->sws->dst = p->mp_ximages[0].params;
+ p->sws->dst.w = mp_rect_w(p->dst);
+ p->sws->dst.h = mp_rect_h(p->dst);
+
+ if (mp_sws_reinit(p->sws) < 0)
+ return false;
+ }
- p->reset_view = true;
vo->want_redraw = true;
return true;
}
@@ -259,34 +259,16 @@ static void Display_Image(struct priv *p, XImage *myximage)
XImage *x_image = p->myximage[p->current_buf];
- if (p->reset_view) {
- XFillRectangle(vo->x11->display, vo->x11->window, p->gc, 0, 0, vo->dwidth, vo->dheight);
- p->reset_view = false;
- }
-
if (p->Shmem_Flag) {
XShmPutImage(vo->x11->display, vo->x11->window, p->gc, x_image,
- 0, 0, p->dst.x0, p->dst.y0, p->dst_w, p->dst_h,
- True);
+ 0, 0, 0, 0, vo->dwidth, vo->dheight, True);
vo->x11->ShmCompletionWaitCount++;
} else {
XPutImage(vo->x11->display, vo->x11->window, p->gc, x_image,
- 0, 0, p->dst.x0, p->dst.y0, p->dst_w, p->dst_h);
+ 0, 0, 0, 0, vo->dwidth, vo->dheight);
}
}
-static struct mp_image get_x_buffer(struct priv *p, int buf_index)
-{
- struct mp_image img = {0};
- mp_image_set_params(&img, &p->sws->dst);
-
- img.planes[0] = p->myximage[buf_index]->data;
- img.stride[0] =
- p->image_width * ((p->myximage[buf_index]->bits_per_pixel + 7) / 8);
-
- return img;
-}
-
static void wait_for_completion(struct vo *vo, int max_outstanding)
{
struct priv *ctx = vo->priv;
@@ -318,21 +300,26 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
wait_for_completion(vo, 1);
- struct mp_image img = get_x_buffer(p, p->current_buf);
+ struct mp_image *img = &p->mp_ximages[p->current_buf];
if (mpi) {
+ mp_image_clear_rc_inv(img, p->dst);
+
struct mp_image src = *mpi;
struct mp_rect src_rc = p->src;
src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, src.fmt.align_x);
src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, src.fmt.align_y);
mp_image_crop_rc(&src, src_rc);
- mp_sws_scale(p->sws, &img, &src);
+ struct mp_image dst = *img;
+ mp_image_crop_rc(&dst, p->dst);
+
+ mp_sws_scale(p->sws, &dst, &src);
} else {
- mp_image_clear(&img, 0, 0, img.w, img.h);
+ mp_image_clear(img, 0, 0, img->w, img->h);
}
- osd_draw_on_image(vo->osd, p->osd, mpi ? mpi->pts : 0, 0, &img);
+ osd_draw_on_image(vo->osd, p->osd, mpi ? mpi->pts : 0, 0, img);
if (mpi != p->original_image) {
talloc_free(p->original_image);