Signed-off-by: Ung, Teng En <teng.en....@intel.com> --- src/Makefile.am | 4 +- src/va_xv.c | 351 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/va_xv.h | 51 ++++++++ src/va_xv_ddx.h | 43 +++++++ src/va_xvcommon.h | 57 +++++++++ 5 files changed, 504 insertions(+), 2 deletions(-) create mode 100644 src/va_xv.c create mode 100644 src/va_xv.h create mode 100644 src/va_xv_ddx.h create mode 100644 src/va_xvcommon.h
diff --git a/src/Makefile.am b/src/Makefile.am index 48a49f1..462426e 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -130,8 +130,8 @@ if USE_X11 source_c += i965_output_dri.c source_h += i965_output_dri.h if USE_XV -source_c += i965_output_xv.c -source_h += i965_output_xv.h +source_c += i965_output_xv.c va_xv.c +source_h += i965_output_xv.h va_xv.h va_xvcommon.h driver_cflags += -lXext -lX11 -lXv endif endif diff --git a/src/va_xv.c b/src/va_xv.c new file mode 100644 index 0000000..214fe58 --- /dev/null +++ b/src/va_xv.c @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2012 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <errno.h> + +#include <X11/extensions/XShm.h> + +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvlib.h> +#include <sys/shm.h> + +#include <string.h> + +#include <va/va_backend.h> +#include "va_xv.h" +#include "va_xv_ddx.h" + +/* Will have to move to some structure if in libva layer. */ +static XShmSegmentInfo va_xv_shminfo; +static XvImage *va_xv_img = NULL; +static GC va_xv_gc = None; + + +static int _vaxv_QueryPortVersion(VADriverContextP ctx, int port, unsigned short *major, unsigned short *minor); + +int va_xvQueryVersion(VADriverContextP ctx, unsigned short *major, unsigned short *minor) +{ + if ((ctx == NULL) || (major == NULL) || (minor == NULL)) { + return VA_XV_STATUS_ERROR; + } + + *major = VAXV_MAJOR; + *minor = VAXV_MINOR; + + return VA_XV_STATUS_SUCCESS; +} + +int va_xvFindAndReservePort(VADriverContextP ctx, int *port_id) +{ + XvAdaptorInfo *xv_adaptors = NULL; + XvAttribute *xv_attribs = NULL; + XvImageFormatValues *xv_formats = NULL; + XvPortID xv_port_id = 0; + unsigned int num_xv_adaptors, num_xv_formats, i, j, k; + unsigned short major, minor; + int num_xv_attribs, ret = VA_XV_STATUS_ERROR; + + if ((ctx == NULL) || (ctx->native_dpy == NULL) || (port_id == NULL)) { + goto error; + } + + if (!XShmQueryExtension(ctx->native_dpy)) { + goto error; + } + + if (XvQueryAdaptors(ctx->native_dpy, DefaultRootWindow(ctx->native_dpy), + &num_xv_adaptors, &xv_adaptors) != Success) { + goto error; + } + + for (i = 0; i < num_xv_adaptors; ++i) + { + if ((xv_adaptors[i].type & XvInputMask) && + (xv_adaptors[i].type & XvImageMask)) { + for (j = 0; j < xv_adaptors[i].num_ports; ++j) { + xv_port_id = xv_adaptors[i].base_id + j; + + xv_formats = XvListImageFormats(ctx->native_dpy, xv_port_id, (int *) &num_xv_formats); + + // Port that support VAXV have FOURCC_VAXV in the supported image formats. + for (k = 0; k < num_xv_formats; ++k) { + if (xv_formats[k].id == FOURCC_VAXV) break; + } + + if (xv_formats) { + XFree(xv_formats); + } + + if (k >= num_xv_formats) { + xv_port_id = 0; + continue; + } + + // Port that support FOURCC_VAXV have VAXV attribute as well. + xv_attribs = XvQueryPortAttributes(ctx->native_dpy, xv_port_id, (int *) &num_xv_attribs); + if (xv_attribs != NULL) { + for (k = 0; k < num_xv_attribs; ++k) { + if (!strcmp(xv_attribs[k].name, VAXV_ATTR_STR)) { + break; + } + } + + XFree(xv_attribs); + + if (k >= num_xv_attribs) { + xv_port_id = 0; + continue; + } + } else { + xv_port_id = 0; + continue; + } + + if (!XvGrabPort(ctx->native_dpy, xv_port_id, CurrentTime)) { + + // Set the VAXV attribute to 1. + if (XvSetPortAttribute(ctx->native_dpy, xv_port_id, + XInternAtom(ctx->native_dpy, VAXV_ATTR_STR, 1), + 1) != Success) { + XvUngrabPort(ctx->native_dpy, xv_port_id, CurrentTime); + xv_port_id = 0; + } else { + break; + } + } else { + xv_port_id = 0; + } + } + + /* If port id is not zero, then already found and grab the port. + * just break out from the for loop. + */ + if (xv_port_id) { + break; + } + } + } + + XvFreeAdaptorInfo(xv_adaptors); + + if (!xv_port_id) { + ret = VA_XV_STATUS_ERROR_PORT_NOT_FOUND; + goto error; + } else { + ret = _vaxv_QueryPortVersion(ctx, xv_port_id, &major, &minor); + if (ret == VA_XV_STATUS_SUCCESS) { + if ((major != VAXV_MAJOR) || (minor != VAXV_MINOR)) { + ret = VA_XV_STATUS_ERROR_PORT_VERSION_MISSMATCH; + } + } + } + + /* Already grab the port, need to ungrab if have error. */ + if (ret == VA_XV_STATUS_SUCCESS) { + *port_id = (int) xv_port_id; + } else { + va_xvFreePort(ctx->native_dpy, xv_port_id); + } + +error: + return ret; +} + +void va_xvFreePort(VADriverContextP ctx, int port) +{ + if ((ctx == NULL) || (ctx->native_dpy == NULL)) + return; + + if (port) { + XvSetPortAttribute(ctx->native_dpy, port, + XInternAtom(ctx->native_dpy, VAXV_ATTR_STR, 1), + 0); + XvUngrabPort(ctx->native_dpy, port, CurrentTime); + } + + if (va_xv_img) { + XFree(va_xv_img); + va_xv_img = NULL; + } + + if (va_xv_shminfo.shmid) { + XShmDetach(ctx->native_dpy, &va_xv_shminfo); + shmdt(va_xv_shminfo.shmaddr); + va_xv_shminfo.shmid = 0; + } + + if (va_xv_gc) { + XFree(va_xv_gc); + } +} + +int va_xvGetPortAttribute(VADriverContextP ctx, int port, const char *attrib_name, int *val) +{ + Atom atom = None; + + if ((ctx == NULL) || (ctx->native_dpy == NULL) || (val == NULL)) { + return VA_XV_STATUS_ERROR; + } + + if (!port) { + return VA_XV_STATUS_ERROR_PORT_UNKNOWN; + } + + atom = XInternAtom(ctx->native_dpy, attrib_name, 1); + + if (atom == None) { + return VA_XV_STATUS_ERROR_MISSING_ATTRIBUTE; + } + + if (XvGetPortAttribute(ctx->native_dpy, port, atom, val) != Success) { + return VA_XV_STATUS_ERROR; + } + + return VA_XV_STATUS_SUCCESS; + +} + +int va_xvSetPortAttribute(VADriverContextP ctx, int port, const char *attrib_name, int val) +{ + Atom atom = None; + + if ((ctx == NULL) || (ctx->native_dpy == NULL)) { + return VA_XV_STATUS_ERROR; + } + + if (!port) { + return VA_XV_STATUS_ERROR_PORT_UNKNOWN; + } + + atom = XInternAtom(ctx->native_dpy, attrib_name, 1); + + if (atom == None) { + return VA_XV_STATUS_ERROR_MISSING_ATTRIBUTE; + } + + if (XvSetPortAttribute(ctx->native_dpy, port, atom, val) != Success) { + return VA_XV_STATUS_ERROR; + } + + return VA_XV_STATUS_SUCCESS; +} + +static int _vaxv_QueryPortVersion(VADriverContextP ctx, int port, unsigned short *major, unsigned short *minor) +{ + unsigned int version; + int ret; + + if ((major == NULL) || (minor == NULL)) { + return VA_XV_STATUS_ERROR; + } + + ret = va_xvGetPortAttribute(ctx, port, VAXV_VERSION_ATTR_STR, + (int *) &version); + + if (ret == VA_XV_STATUS_SUCCESS) { + *minor = (unsigned short) (version & 0x0000ffff); + *major = (unsigned short) (version >> 16); + } + + return ret; +} + +int va_xvQueryPortFormat(VADriverContextP ctx, int port, unsigned int *fourcc) +{ + return va_xvGetPortAttribute(ctx, port, VAXV_FORMAT_ATTR_STR, (int *) fourcc); + +} + +int va_xvQueryPortCapabilities(VADriverContextP ctx, int port, unsigned int *port_caps) +{ + return va_xvGetPortAttribute(ctx, port, VAXV_CAPS_ATTR_STR, (int *) port_caps); +} + +int va_xvPutImage(VADriverContextP ctx, int port, void *window, const va_xv_buf_t *buf_info, + short src_x, short src_y, unsigned short src_w, unsigned short src_h, + short dst_x, short dst_y, unsigned short dst_w, unsigned short dst_h, + unsigned int flags) +{ + va_xv_put_image_t *vaxv_putimage = NULL; + int ret; + + if ((ctx == NULL) || (ctx->native_dpy == NULL) || + (window == NULL) || (buf_info == NULL)) { + return VA_XV_STATUS_ERROR; + } + + if (!va_xv_img) { + va_xv_img = (XvImage *) XvShmCreateImage(ctx->native_dpy, port, FOURCC_VAXV, + NULL, 1, 1, &va_xv_shminfo); + } + + if (!va_xv_shminfo.shmid) { + va_xv_shminfo.shmid = + shmget(IPC_PRIVATE, sizeof(va_xv_put_image_t), IPC_CREAT | 0666); + va_xv_shminfo.shmaddr = (char *) shmat(va_xv_shminfo.shmid, 0, 0); + va_xv_shminfo.readOnly = False; + + va_xv_img->data = va_xv_shminfo.shmaddr; + + XShmAttach(ctx->native_dpy, &va_xv_shminfo); + } + + if (!va_xv_gc) { + va_xv_gc = XCreateGC(ctx->native_dpy, (Drawable) window, 0, NULL); + } + + if (!va_xv_shminfo.shmid || !va_xv_img || !va_xv_gc) goto error; + + vaxv_putimage = (va_xv_put_image_t *) va_xv_shminfo.shmaddr; + + vaxv_putimage->size = sizeof(va_xv_put_image_t); + vaxv_putimage->flags = flags; + + vaxv_putimage->video_image.buf_handle = buf_info->buf_handle; + vaxv_putimage->video_image.pixel_format = buf_info->pixel_format; + vaxv_putimage->video_image.buf_width = buf_info->buf_width; + vaxv_putimage->video_image.buf_height = buf_info->buf_height; + vaxv_putimage->video_image.pitches[0] = buf_info->pitches[0]; + vaxv_putimage->video_image.pitches[1] = buf_info->pitches[1]; + vaxv_putimage->video_image.pitches[2] = buf_info->pitches[2]; + vaxv_putimage->video_image.offsets[0] = buf_info->offsets[0]; + vaxv_putimage->video_image.offsets[1] = buf_info->offsets[1]; + vaxv_putimage->video_image.offsets[2] = buf_info->offsets[2]; + + + ret = XvShmPutImage(ctx->native_dpy, port, (Drawable) window, + va_xv_gc, va_xv_img, src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h, False); + + if (Success != ret) goto error; + + XSync(ctx->native_dpy, False); + + return VA_XV_STATUS_SUCCESS; + +error: + return VA_XV_STATUS_ERROR; +} diff --git a/src/va_xv.h b/src/va_xv.h new file mode 100644 index 0000000..1444450 --- /dev/null +++ b/src/va_xv.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2012 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef VA_XV_H +#define VA_XV_H + +#include "va_xvcommon.h" + + +#define VA_XV_STATUS_SUCCESS 0 +#define VA_XV_STATUS_ERROR -1 +#define VA_XV_STATUS_ERROR_PORT_NOT_FOUND -2 +#define VA_XV_STATUS_ERROR_PORT_VERSION_MISSMATCH -3 +#define VA_XV_STATUS_ERROR_PORT_UNKNOWN -4 +#define VA_XV_STATUS_ERROR_MISSING_ATTRIBUTE -5 + + +int va_xvQueryVersion(VADriverContextP ctx, unsigned short *major, unsigned short *minor); +int va_xvFindAndReservePort(VADriverContextP ctx, int *port); +int va_xvQueryPortCapabilities(VADriverContextP ctx, int port, unsigned int *port_caps); +int va_xvQueryPortFormat(VADriverContextP ctx, int port, unsigned int *fourcc); +int va_xvGetPortAttribute(VADriverContextP ctx, int port, const char *attrib_name, int *val); +int va_xvSetPortAttribute(VADriverContextP ctx, int port, const char *attrib_name, int val); +int va_xvPutImage(VADriverContextP ctx, int port, void *window, const va_xv_buf_t *buf_info, + short src_x, short src_y, unsigned short src_w, unsigned short src_h, + short dst_x, short dst_y, unsigned short dst_w, unsigned short dst_h, + unsigned int flags); +void va_xvFreePort(VADriverContextP ctx, int port); + +#endif diff --git a/src/va_xv_ddx.h b/src/va_xv_ddx.h new file mode 100644 index 0000000..943b98b --- /dev/null +++ b/src/va_xv_ddx.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2012 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef VA_XV_DDX_H +#define VA_XV_DDX_H + +#include "va_xvcommon.h" + +#define VAXV_ATTR_STR "VAXV_SHMBO" +#define VAXV_VERSION_ATTR_STR "VAXV_VERSION" +#define VAXV_CAPS_ATTR_STR "VAXV_CAPS" +#define VAXV_FORMAT_ATTR_STR "VAXV_FORMAT" + +#define FOURCC_VAXV (('V' << 24) | ('X' << 16) | ('A' << 8) | 'V') + +typedef struct _va_xv_put_image { + int size; + va_xv_buf_t video_image; + unsigned int flags; +} va_xv_put_image_t; + +#endif diff --git a/src/va_xvcommon.h b/src/va_xvcommon.h new file mode 100644 index 0000000..3dde65a --- /dev/null +++ b/src/va_xvcommon.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2012 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef VA_XVCOMMON_H +#define VA_XVCOMMON_H + +#define VAXV_MAJOR 0 +#define VAXV_MINOR 1 + +#define VAXV_VERSION ((VAXV_MAJOR << 16) | VAXV_MINOR) + +/* VAXV port cababilities + */ +/* The shared buffer object in put image are directly used on overlay/sprite */ +#define VAXV_CAP_DIRECT_BUFFER 1 + +/* Scalling support */ +#define VAXV_CAP_SCALLING_UP (1 << 4) +#define VAXV_CAP_SCALLING_DOWN (1 << 5) +#define VAXV_CAP_SCALLING_FLAG VAXV_CAP_SCALLING_UP | VAXV_CAP_SCALLING_DOWN + +/* Rotation support */ +#define VAXV_CAP_ROTATION_90 (1 << 8) +#define VAXV_CAP_ROTATION_180 (1 << 9) +#define VAXV_CAP_ROTATION_270 (1 << 10) +#define VAXV_CAP_ROTATION_FLAG VAXV_CAP_ROTATION_90 | VAXV_CAP_ROTATION_180 | VAXV_CAP_ROTATION_270 + +typedef struct _va_xv_buf { + unsigned int buf_handle; + unsigned long pixel_format; + int buf_width, buf_height; + unsigned int pitches[3]; + unsigned int offsets[3]; +} va_xv_buf_t; + +#endif -- 1.8.4 _______________________________________________ Libva mailing list Libva@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libva