diff options
-rw-r--r-- | video/out/vo_x11.c | 117 |
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); |