static int control(struct vo *vo, uint32_t request, void *data) { struct xvctx *ctx = vo->priv; switch (request) { case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: resize(vo); return VO_TRUE; case VOCTRL_SET_EQUALIZER: { vo->want_redraw = true; struct voctrl_set_equalizer_args *args = data; return xv_set_eq(vo, ctx->xv_port, args->name, args->value); } case VOCTRL_GET_EQUALIZER: { struct voctrl_get_equalizer_args *args = data; return xv_get_eq(vo, ctx->xv_port, args->name, args->valueptr); } case VOCTRL_SET_YUV_COLORSPACE:; struct mp_csp_details* given_cspc = data; int is_709 = given_cspc->format == MP_CSP_BT_709; xv_set_eq(vo, ctx->xv_port, "bt_709", is_709 * 200 - 100); read_xv_csp(vo); vo->want_redraw = true; return true; case VOCTRL_GET_YUV_COLORSPACE:; struct mp_csp_details* cspc = data; read_xv_csp(vo); *cspc = ctx->cached_csp; return true; case VOCTRL_REDRAW_FRAME: redraw_frame(vo); return true; case VOCTRL_SCREENSHOT: { struct voctrl_screenshot_args *args = data; args->out_image = get_screenshot(vo); return true; } case VOCTRL_WINDOW_TO_OSD_COORDS: { float *c = data; struct mp_rect *src = &ctx->src_rect; struct mp_rect *dst = &ctx->dst_rect; c[0] = av_clipf(c[0], dst->x0, dst->x1) - dst->x0; c[1] = av_clipf(c[1], dst->y0, dst->y1) - dst->y0; c[0] = c[0] / (dst->x1 - dst->x0) * (src->x1 - src->x0) + src->x0; c[1] = c[1] / (dst->y1 - dst->y0) * (src->y1 - src->y0) + src->y0; return VO_TRUE; } } int events = 0; int r = vo_x11_control(vo, &events, request, data); if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)) resize(vo); return r; }
static int control(struct vo *vo, uint32_t request, void *data) { struct xvctx *ctx = vo->priv; switch (request) { case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: resize(vo); return VO_TRUE; case VOCTRL_SET_EQUALIZER: { vo->want_redraw = true; struct voctrl_set_equalizer_args *args = data; return xv_set_eq(vo, ctx->xv_port, args->name, args->value); } case VOCTRL_GET_EQUALIZER: { struct voctrl_get_equalizer_args *args = data; return xv_get_eq(vo, ctx->xv_port, args->name, args->valueptr); } case VOCTRL_REDRAW_FRAME: draw_image(vo, ctx->original_image); return true; } int events = 0; int r = vo_x11_control(vo, &events, request, data); if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)) resize(vo); vo_event(vo, events); return r; }
static int control(struct vo *vo, uint32_t request, void *data) { struct xvctx *ctx = vo->priv; switch (request) { case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: resize(vo); return VO_TRUE; case VOCTRL_SET_EQUALIZER: { vo->want_redraw = true; struct voctrl_set_equalizer_args *args = data; return xv_set_eq(vo, ctx->xv_port, args->name, args->value); } case VOCTRL_GET_EQUALIZER: { struct voctrl_get_equalizer_args *args = data; return xv_get_eq(vo, ctx->xv_port, args->name, args->valueptr); } case VOCTRL_GET_COLORSPACE: { struct mp_image_params *params = data; read_xv_csp(vo); params->colorspace = ctx->cached_csp; return true; } case VOCTRL_REDRAW_FRAME: draw_image(vo, ctx->original_image); return true; case VOCTRL_SCREENSHOT: { struct voctrl_screenshot_args *args = data; args->out_image = get_screenshot(vo); return true; } } int events = 0; int r = vo_x11_control(vo, &events, request, data); if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)) resize(vo); return r; }
/* * create and map window, * allocate colors and (shared) memory */ static int reconfig(struct vo *vo, struct mp_image_params *params) { struct vo_x11_state *x11 = vo->x11; struct xvctx *ctx = vo->priv; int i; mp_image_unrefp(&ctx->original_image); ctx->image_height = params->h; ctx->image_width = params->w; ctx->image_format = params->imgfmt; if ((ctx->max_width != 0 && ctx->max_height != 0) && (ctx->image_width > ctx->max_width || ctx->image_height > ctx->max_height)) { MP_ERR(vo, "Source image dimensions are too high: %ux%u (maximum is %ux%u)\n", ctx->image_width, ctx->image_height, ctx->max_width, ctx->max_height); return -1; } /* check image formats */ ctx->xv_format = 0; for (i = 0; i < ctx->formats; i++) { MP_VERBOSE(vo, "Xvideo image format: 0x%x (%4.4s) %s\n", ctx->fo[i].id, (char *) &ctx->fo[i].id, (ctx->fo[i].format == XvPacked) ? "packed" : "planar"); if (ctx->fo[i].id == find_xv_format(ctx->image_format)) ctx->xv_format = ctx->fo[i].id; } if (!ctx->xv_format) return -1; vo_x11_config_vo_window(vo); if (!ctx->f_gc && !ctx->vo_gc) { ctx->f_gc = XCreateGC(x11->display, x11->window, 0, 0); ctx->vo_gc = XCreateGC(x11->display, x11->window, 0, NULL); XSetForeground(x11->display, ctx->f_gc, 0); } if (ctx->xv_ck_info.method == CK_METHOD_BACKGROUND) XSetWindowBackground(x11->display, x11->window, ctx->xv_colorkey); MP_VERBOSE(vo, "using Xvideo port %d for hw scaling\n", ctx->xv_port); // In case config has been called before for (i = 0; i < ctx->num_buffers; i++) deallocate_xvimage(vo, i); ctx->num_buffers = ctx->cfg_buffers; for (i = 0; i < ctx->num_buffers; i++) { if (!allocate_xvimage(vo, i)) { MP_FATAL(vo, "could not allocate Xv image data\n"); return -1; } } ctx->current_buf = 0; ctx->current_ip_buf = 0; int is_709 = params->colorspace == MP_CSP_BT_709; xv_set_eq(vo, ctx->xv_port, "bt_709", is_709 * 200 - 100); read_xv_csp(vo); resize(vo); return 0; }