diff options
Diffstat (limited to 'va')
-rw-r--r-- | va/Android.mk | 91 | ||||
-rw-r--r-- | va/Makefile.am | 50 | ||||
-rw-r--r-- | va/android/Makefile.am | 30 | ||||
-rw-r--r-- | va/android/drmtest.c | 139 | ||||
-rw-r--r-- | va/android/drmtest.h | 40 | ||||
-rw-r--r-- | va/android/va_android.cpp | 300 | ||||
l--------- | va/android/va_dummy.c | 1 | ||||
l--------- | va/dummy | 1 | ||||
-rw-r--r-- | va/glx/Makefile.am | 41 | ||||
-rw-r--r-- | va/glx/va_backend_glx.h | 54 | ||||
-rw-r--r-- | va/glx/va_glx.c | 165 | ||||
-rw-r--r-- | va/glx/va_glx.h | 109 | ||||
-rw-r--r-- | va/glx/va_glx_impl.c | 1078 | ||||
-rw-r--r-- | va/glx/va_glx_impl.h | 37 | ||||
-rw-r--r-- | va/glx/va_glx_private.h | 76 | ||||
-rw-r--r-- | va/va.c | 262 | ||||
-rw-r--r-- | va/va.h | 103 | ||||
-rw-r--r-- | va/va_android.h | 54 | ||||
-rw-r--r-- | va/va_backend.h | 54 | ||||
-rw-r--r-- | va/va_backend_tpi.h | 74 | ||||
l--------- | va/va_dummy.h | 1 | ||||
-rw-r--r-- | va/va_tpi.c | 130 | ||||
-rw-r--r-- | va/va_tpi.h | 73 | ||||
-rw-r--r-- | va/va_trace.c | 1115 | ||||
-rw-r--r-- | va/x11/dri1_util.c | 18 | ||||
-rw-r--r-- | va/x11/dri2_util.c | 22 | ||||
-rw-r--r-- | va/x11/va_dricommon.h | 13 | ||||
-rw-r--r-- | va/x11/va_x11.c | 48 |
28 files changed, 3932 insertions, 247 deletions
diff --git a/va/Android.mk b/va/Android.mk new file mode 100644 index 0000000..848aa83 --- /dev/null +++ b/va/Android.mk @@ -0,0 +1,91 @@ +# For libva +# ===================================================== + +LOCAL_PATH:= $(call my-dir) + +LIBVA_DRIVERS_PATH = /system/lib + +include $(CLEAR_VARS) + +#LIBVA_MINOR_VERSION := 31 +#LIBVA_MAJOR_VERSION := 0 + +LOCAL_SRC_FILES := \ + va.c \ + va_trace.c \ + +LOCAL_CFLAGS += \ + -DANDROID \ + -DVA_DRIVERS_PATH="\"$(LIBVA_DRIVERS_PATH)\"" + +LOCAL_C_INCLUDES += \ + $(TARGET_OUT_HEADERS)/libva \ + $(LOCAL_PATH)/x11 \ + $(LOCAL_PATH)/.. + +LOCAL_COPY_HEADERS := \ + va.h \ + va_version.h \ + va_backend.h \ + va_version.h.in \ + x11/va_dricommon.h + +LOCAL_COPY_HEADERS_TO := libva/va + +LOCAL_MODULE := libva + +LOCAL_SHARED_LIBRARIES := libdl libdrm libcutils + +include $(BUILD_SHARED_LIBRARY) + + +# For libva-android +# ===================================================== + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + android/va_android.cpp + +LOCAL_CFLAGS += \ + -DANDROID + +LOCAL_C_INCLUDES += \ + $(TARGET_OUT_HEADERS)/libva \ + $(LOCAL_PATH)/x11 + +LOCAL_COPY_HEADERS_TO := libva/va + +LOCAL_COPY_HEADERS := va_android.h + +LOCAL_MODULE := libva-android + +LOCAL_SHARED_LIBRARIES := libva + +include $(BUILD_SHARED_LIBRARY) + + +# For libva-tpi +# ===================================================== + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := va_tpi.c + +LOCAL_CFLAGS += -DANDROID + +LOCAL_C_INCLUDES += \ + $(TARGET_OUT_HEADERS)/libva \ + $(LOCAL_PATH)/.. + +LOCAL_COPY_HEADERS_TO := libva/va + +LOCAL_COPY_HEADERS := \ + va_tpi.h \ + va_backend_tpi.h + +LOCAL_SHARED_LIBRARIES := libva + +LOCAL_MODULE := libva-tpi + +include $(BUILD_SHARED_LIBRARY) diff --git a/va/Makefile.am b/va/Makefile.am index aeaf82f..2ff3a23 100644 --- a/va/Makefile.am +++ b/va/Makefile.am @@ -27,25 +27,61 @@ INCLUDES = \ LDADD = \ $(LIBVA_LT_LDFLAGS) -lib_LTLIBRARIES = \ - libva.la \ - libva-x11.la - +libva_la_SOURCES = va.c va_trace.c libva_ladir = $(libdir) libva_la_LDFLAGS = $(LDADD) -no-undefined libva_la_LIBADD = $(LIBVA_LIBS) -ldl +libva_tpi_la_SOURCES = va_tpi.c +libva_tpi_ladir = $(libdir) +libva_tpi_la_LDFLAGS = $(LDADD) -no-undefined +libva_tpi_la_LIBADD = $(libvacorelib) -ldl +libva_tpi_la_DEPENDENCIES = $(libvacorelib) + + +libva_x11_backend = libva-x11.la +libva_x11_backenddir = x11 + libva_x11_la_SOURCES = libva_x11_la_LIBADD = $(libvacorelib) x11/libva_x11.la $(LIBVA_LIBS) $(X11_LIBS) $(XEXT_LIBS) $(DRM_LIBS) $(XFIXES_LIBS) libva_x11_la_LDFLAGS = $(LDADD) libva_x11_la_DEPENDENCIES = $(libvacorelib) x11/libva_x11.la -SUBDIRS = x11 +if BUILD_DUMMY_BACKEND +libva_dummy_backend = libva-dummy.la +libva_dummy_backenddir = dummy + +libva_dummy_la_SOURCES = +libva_dummy_la_LIBADD = $(libvacorelib) dummy/libva_dummy.la $(LIBVA_LIBS) $(DRM_LIBS) +libva_dummy_la_LDFLAGS = $(LDADD) +libva_dummy_la_DEPENDENCIES = $(libvacorelib) dummy/libva_dummy.la +else +libva_dummy_backend = +libva_dummy_backenddir = +endif + +if USE_GLX +libva_glx_backend = libva-glx.la +libva_glx_backenddir = glx + +libva_glx_la_SOURCES = +libva_glx_la_LIBADD = $(libvacorelib) glx/libva_glx.la libva-x11.la $(GL_DEPS_LIBS) -ldl +libva_glx_la_LDFLAGS = $(LDADD) +libva_glx_la_DEPENDENCIES = $(libvacorelib) glx/libva_glx.la libva-x11.la + +else +libva_glx_backend = +libva_glx_backenddir = +endif + +lib_LTLIBRARIES = libva.la libva-tpi.la $(libva_x11_backend) $(libva_dummy_backend) $(libva_glx_backend) + +DIST_SUBDIRS = x11 glx dummy -libva_la_SOURCES = va.c +SUBDIRS = $(libva_x11_backenddir) $(libva_dummy_backenddir) $(libva_glx_backenddir) libvaincludedir = ${includedir}/va -libvainclude_HEADERS = va.h va_x11.h va_backend.h va_version.h +libvainclude_HEADERS = va.h va_tpi.h va_x11.h va_backend.h va_backend_tpi.h va_dummy.h va_version.h DISTCLEANFILES = \ va_version.h diff --git a/va/android/Makefile.am b/va/android/Makefile.am new file mode 100644 index 0000000..d86ea86 --- /dev/null +++ b/va/android/Makefile.am @@ -0,0 +1,30 @@ +# INTEL CONFIDENTIAL +# Copyright 2007 Intel Corporation. All Rights Reserved. +# +# The source code contained or described herein and all documents related to +# the source code ("Material") are owned by Intel Corporation or its suppliers +# or licensors. Title to the Material remains with Intel Corporation or its +# suppliers and licensors. The Material may contain trade secrets and +# proprietary and confidential information of Intel Corporation and its +# suppliers and licensors, and is protected by worldwide copyright and trade +# secret laws and treaty provisions. No part of the Material may be used, +# copied, reproduced, modified, published, uploaded, posted, transmitted, +# distributed, or disclosed in any way without Intel's prior express written +# permission. +# +# No license under any patent, copyright, trade secret or other intellectual +# property right is granted to or conferred upon you by disclosure or delivery +# of the Materials, either expressly, by implication, inducement, estoppel or +# otherwise. Any license under such intellectual property rights must be +# express and approved by Intel in writing. + +AM_CFLAGS = -DLINUX -I$(top_srcdir)/va -I$(top_srcdir)/va/x11 $(DRM_CFLAGS) + +noinst_LTLIBRARIES = libva_dummy.la + +libva_dummy_la_LIBADD = $(LIBVA_LIBS) -ldl -ludev + +libva_dummyincludedir = ${includedir}/va + +libva_dummy_la_SOURCES = va_dummy.c drmtest.c + diff --git a/va/android/drmtest.c b/va/android/drmtest.c new file mode 100644 index 0000000..444ef47 --- /dev/null +++ b/va/android/drmtest.c @@ -0,0 +1,139 @@ +/* + * Copyright © 2007 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <string.h> +#include <fcntl.h> +#include <fnmatch.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include "drmtest.h" + +#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE +#include <libudev.h> + +static int is_master(int fd) +{ + drm_client_t client; + int ret; + + /* Check that we're the only opener and authed. */ + client.idx = 0; + ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client); + assert (ret == 0); + if (!client.auth) + return 0; + client.idx = 1; + ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client); + if (ret != -1 || errno != EINVAL) + return 0; + + return 1; +} + +/** Open the first DRM device matching the criteria */ +int drm_open_matching(const char *pci_glob, int flags, int *vendor_id, int *device_id) +{ + struct udev *udev; + struct udev_enumerate *e; + struct udev_device *device, *parent; + struct udev_list_entry *entry; + const char *pci_id, *path; + char *tmp; + int fd; + + *vendor_id = 0; + *device_id = 0; + + udev = udev_new(); + if (udev == NULL) { + fprintf(stderr, "failed to initialize udev context\n"); + return -1; + //abort(); + } + + fd = -1; + e = udev_enumerate_new(udev); + udev_enumerate_add_match_subsystem(e, "drm"); + udev_enumerate_scan_devices(e); + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) { + path = udev_list_entry_get_name(entry); + device = udev_device_new_from_syspath(udev, path); + parent = udev_device_get_parent(device); + /* Filter out KMS output devices. */ + if (strcmp(udev_device_get_subsystem(parent), "pci") != 0) + continue; + pci_id = udev_device_get_property_value(parent, "PCI_ID"); + if (fnmatch(pci_glob, pci_id, 0) != 0) + continue; + fd = open(udev_device_get_devnode(device), O_RDWR); + if (fd < 0) + continue; + if ((flags & DRM_TEST_MASTER) && !is_master(fd)) { + close(fd); + fd = -1; + continue; + } + + break; + } + udev_enumerate_unref(e); + udev_unref(udev); + + *vendor_id = (int) strtol(pci_id, &tmp, 16); + *device_id = (int) strtol((tmp+1), NULL, 16); + + return fd; +} + +int drm_open_any(int *vendor_id, int *device_id) +{ + int fd = drm_open_matching("*:*", 0, vendor_id, device_id); + + if (fd < 0) { + fprintf(stderr, "failed to open any drm device\n"); + //abort(); + } + + return fd; +} + +/** + * Open the first DRM device we can find where we end up being the master. + */ +int drm_open_any_master(void) +{ + int vendor_id, device_id; + int fd = drm_open_matching("*:*", DRM_TEST_MASTER, &vendor_id, &device_id); + + if (fd < 0) { + fprintf(stderr, "failed to open any drm device\n"); + abort(); + } + + return fd; + +} diff --git a/va/android/drmtest.h b/va/android/drmtest.h new file mode 100644 index 0000000..5f10f08 --- /dev/null +++ b/va/android/drmtest.h @@ -0,0 +1,40 @@ +/* + * Copyright © 2007 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <assert.h> +#include <errno.h> + +#include "xf86drm.h" + +#define DRM_TEST_MASTER 0x01 + +int drm_open_any(int *vendor_id, int *device_id); +int drm_open_any_master(void); +int drm_open_matching(const char *pci_glob, int flags, int *vendor_id, int *device_id); diff --git a/va/android/va_android.cpp b/va/android/va_android.cpp new file mode 100644 index 0000000..4eb90a2 --- /dev/null +++ b/va/android/va_android.cpp @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2007 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. + */ + +#define _GNU_SOURCE 1 +#include "va.h" +#include "va_backend.h" +#include "va_android.h" +#include "va_dricommon.h" /* needs some helper functions from this file */ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <dlfcn.h> +#include <errno.h> +#ifndef ANDROID +#include <libudev.h> +#include "drmtest.h" +#endif + +#define CHECK_SYMBOL(func) { if (!func) printf("func %s not found\n", #func); return VA_STATUS_ERROR_UNKNOWN; } +#define DEVICE_NAME "/dev/card0" + +static VADisplayContextP pDisplayContexts = NULL; + +static int open_device (char *dev_name) +{ + struct stat st; + int fd; + + if (-1 == stat (dev_name, &st)) + { + printf ("Cannot identify '%s': %d, %s\n", + dev_name, errno, strerror (errno)); + return -1; + } + + if (!S_ISCHR (st.st_mode)) + { + printf ("%s is no device\n", dev_name); + return -1; + } + + fd = open (dev_name, O_RDWR); + + if (-1 == fd) + { + fprintf (stderr, "Cannot open '%s': %d, %s\n", + dev_name, errno, strerror (errno)); + return -1; + } + + return fd; +} + +static int va_DisplayContextIsValid ( + VADisplayContextP pDisplayContext + ) +{ + VADisplayContextP ctx = pDisplayContexts; + + while (ctx) + { + if (ctx == pDisplayContext && pDisplayContext->pDriverContext) + return 1; + ctx = ctx->pNext; + } + return 0; +} + +static void va_DisplayContextDestroy ( + VADisplayContextP pDisplayContext +) +{ + VADisplayContextP *ctx = &pDisplayContexts; + + /* Throw away pDisplayContext */ + while (*ctx) + { + if (*ctx == pDisplayContext) + { + *ctx = pDisplayContext->pNext; + pDisplayContext->pNext = NULL; + break; + } + ctx = &((*ctx)->pNext); + } + free(pDisplayContext->pDriverContext->dri_state); + free(pDisplayContext->pDriverContext); + free(pDisplayContext); +} + +#ifdef ANDROID +static VAStatus va_DisplayContextGetDriverName ( + VADisplayContextP pDisplayContext, + char **driver_name +) +{ + VADriverContextP ctx = pDisplayContext->pDriverContext; + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + char *driver_name_env; + int vendor_id, device_id; + + struct { + int vendor_id; + int device_id; + char driver_name[64]; + } devices[] = { + { 0x8086, 0x4100, "pvr" }, + { 0x8086, 0x0130, "pvr" }, + { 0x0, 0x0, "\0" }, + }; + + memset(dri_state, 0, sizeof(*dri_state)); + dri_state->fd = open_device(DEVICE_NAME); + + if (dri_state->fd < 0) { + fprintf(stderr,"can't open DRM devices\n"); + return VA_STATUS_ERROR_UNKNOWN; + } + + /* TBD: other vendor driver names */ + vendor_id = devices[0].vendor_id; + device_id = devices[0].device_id; + *driver_name = strdup(devices[0].driver_name); + + dri_state->driConnectedFlag = VA_DUMMY; + + return VA_STATUS_SUCCESS; +} +#else +static VAStatus va_DisplayContextGetDriverName ( + VADisplayContextP pDisplayContext, + char **driver_name +) +{ + VADriverContextP ctx = pDisplayContext->pDriverContext; + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + char *driver_name_env; + int vendor_id, device_id; + int i = 0; + + struct { + int vendor_id; + int device_id; + char driver_name[64]; + } devices[] = { + { 0x8086, 0x4100, "pvr" }, + { 0x8086, 0x0130, "pvr" }, + { 0x0, 0x0, "\0" }, + }; + + memset(dri_state, 0, sizeof(*dri_state)); + dri_state->fd = drm_open_any(&vendor_id, &device_id); + + if (dri_state->fd < 0) { + fprintf(stderr,"can't open DRM devices\n"); + return VA_STATUS_ERROR_UNKNOWN; + } + + /* TBD: other vendor driver names */ + + while (devices[i].device_id != 0) { + if ((devices[i].vendor_id == vendor_id) && + (devices[i].device_id == device_id)) + break; + i++; + } + + if (devices[i].device_id != 0) + *driver_name = strdup(devices[i].driver_name); + else { + fprintf(stderr,"device (0x%04x:0x%04x) is not supported\n", + vendor_id, device_id); + + return VA_STATUS_ERROR_UNKNOWN; + } + + printf("DRM device is opened, loading driver %s for device 0x%04x:0x%04x\n", + driver_name, vendor_id, device_id); + + dri_state->driConnectedFlag = VA_DUMMY; + + return VA_STATUS_SUCCESS; +} +#endif + +VADisplay vaGetDisplay ( + void *native_dpy /* implementation specific */ +) +{ + VADisplay dpy = NULL; + VADisplayContextP pDisplayContext = pDisplayContexts; + + if (!native_dpy) + return NULL; + + while (pDisplayContext) + { + if (pDisplayContext->pDriverContext && + pDisplayContext->pDriverContext->native_dpy == (void *)native_dpy) + { + dpy = (VADisplay)pDisplayContext; + break; + } + pDisplayContext = pDisplayContext->pNext; + } + + + if (!dpy) + { + /* create new entry */ + VADriverContextP pDriverContext; + struct dri_state *dri_state; + pDisplayContext = (VADisplayContextP)calloc(1, sizeof(*pDisplayContext)); + pDriverContext = (VADriverContextP)calloc(1, sizeof(*pDriverContext)); + dri_state = (struct dri_state*)calloc(1, sizeof(*dri_state)); + if (pDisplayContext && pDriverContext && dri_state) + { + pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC; + + pDriverContext->native_dpy = (void *)native_dpy; + pDisplayContext->pNext = pDisplayContexts; + pDisplayContext->pDriverContext = pDriverContext; + pDisplayContext->vaIsValid = va_DisplayContextIsValid; + pDisplayContext->vaDestroy = va_DisplayContextDestroy; + pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName; + pDisplayContexts = pDisplayContext; + pDriverContext->dri_state = dri_state; + dpy = (VADisplay)pDisplayContext; + } + else + { + if (pDisplayContext) + free(pDisplayContext); + if (pDriverContext) + free(pDriverContext); + if (dri_state) + free(dri_state); + } + } + + return dpy; +} + +#define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext) +#define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; } + + +#ifdef ANDROID +VAStatus vaPutSurface ( + VADisplay dpy, + VASurfaceID surface, + sp<ISurface> draw, /* Android Surface/Window */ + short srcx, + short srcy, + unsigned short srcw, + unsigned short srch, + short destx, + short desty, + unsigned short destw, + unsigned short desth, + VARectangle *cliprects, /* client supplied clip list */ + unsigned int number_cliprects, /* number of clip rects in the clip list */ + unsigned int flags /* de-interlacing flags */ +) +{ + VADriverContextP ctx; + + CHECK_DISPLAY(dpy); + ctx = CTX(dpy); + return ctx->vtable.vaPutSurface( ctx, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch, + destx, desty, destw, desth, + cliprects, number_cliprects, flags ); +} +#endif diff --git a/va/android/va_dummy.c b/va/android/va_dummy.c new file mode 120000 index 0000000..b47bd16 --- /dev/null +++ b/va/android/va_dummy.c @@ -0,0 +1 @@ +va_android.cpp
\ No newline at end of file diff --git a/va/dummy b/va/dummy new file mode 120000 index 0000000..1fd74d1 --- /dev/null +++ b/va/dummy @@ -0,0 +1 @@ +android
\ No newline at end of file diff --git a/va/glx/Makefile.am b/va/glx/Makefile.am new file mode 100644 index 0000000..337f34e --- /dev/null +++ b/va/glx/Makefile.am @@ -0,0 +1,41 @@ +# Copyright (C) 2009 Splitted-Desktop Systems. 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. + +AM_CFLAGS = -DLINUX -I$(top_srcdir)/va -I$(top_srcdir)/va/x11 + +source_c = \ + va_glx.c \ + va_glx_impl.c + +source_h = \ + va_glx.h \ + va_backend_glx.h + +source_h_priv = \ + va_glx_impl.h \ + va_glx_private.h + +noinst_LTLIBRARIES = libva_glx.la +libva_glxincludedir = ${includedir}/va +libva_glxinclude_HEADERS = $(source_h) +libva_glx_la_SOURCES = $(source_c) +noinst_HEADERS = $(source_h_priv) diff --git a/va/glx/va_backend_glx.h b/va/glx/va_backend_glx.h new file mode 100644 index 0000000..d110485 --- /dev/null +++ b/va/glx/va_backend_glx.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Splitted-Desktop Systems. 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_BACKEND_GLX_H +#define VA_BACKEND_GLX_H + +struct VADriverContext; + +struct VADriverVTableGLX { + /* Optional: create a surface used for display to OpenGL */ + VAStatus (*vaCreateSurfaceGLX)( + struct VADriverContext *ctx, + unsigned int gl_target, + unsigned int gl_texture, + void **gl_surface + ); + + /* Optional: destroy a VA/GLX surface */ + VAStatus (*vaDestroySurfaceGLX)( + struct VADriverContext *ctx, + void *gl_surface + ); + + /* Optional: copy a VA surface to a VA/GLX surface */ + VAStatus (*vaCopySurfaceGLX)( + struct VADriverContext *ctx, + void *gl_surface, + VASurfaceID surface, + unsigned int flags + ); +}; + +#endif /* VA_BACKEND_GLX_H */ diff --git a/va/glx/va_glx.c b/va/glx/va_glx.c new file mode 100644 index 0000000..1812ef5 --- /dev/null +++ b/va/glx/va_glx.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2009 Splitted-Desktop Systems. 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 <stdlib.h> +#include "va_glx_private.h" +#include "va_glx_impl.h" + +#define INIT_CONTEXT(ctx, dpy) do { \ + if (!vaDisplayIsValid(dpy)) \ + return VA_STATUS_ERROR_INVALID_DISPLAY; \ + \ + ctx = ((VADisplayContextP)(dpy))->pDriverContext; \ + if (!(ctx)) \ + return VA_STATUS_ERROR_INVALID_DISPLAY; \ + \ + VAStatus status = va_glx_init_context(ctx); \ + if (status != VA_STATUS_SUCCESS) \ + return status; \ + } while (0) + +#define INVOKE(ctx, func, args) do { \ + VADriverVTableGLXP vtable; \ + vtable = &VA_DRIVER_CONTEXT_GLX(ctx)->vtable; \ + if (!vtable->va##func##GLX) \ + return VA_STATUS_ERROR_UNIMPLEMENTED; \ + status = vtable->va##func##GLX args; \ + } while (0) + + +// Destroy VA/GLX display context +static void va_DisplayContextDestroy(VADisplayContextP pDisplayContext) +{ + VADisplayContextGLXP pDisplayContextGLX; + VADriverContextP pDriverContext; + VADriverContextGLXP pDriverContextGLX; + + if (!pDisplayContext) + return; + + pDriverContext = pDisplayContext->pDriverContext; + pDriverContextGLX = pDriverContext->glx; + if (pDriverContextGLX) { + free(pDriverContextGLX); + pDriverContext->glx = NULL; + } + + pDisplayContextGLX = pDisplayContext->opaque; + if (pDisplayContextGLX) { + vaDestroyFunc vaDestroy = pDisplayContextGLX->vaDestroy; + free(pDisplayContextGLX); + pDisplayContext->opaque = NULL; + if (vaDestroy) + vaDestroy(pDisplayContext); + } +} + +// Return a suitable VADisplay for VA API +VADisplay vaGetDisplayGLX(Display *native_dpy) +{ + VADisplay dpy = NULL; + VADisplayContextP pDisplayContext = NULL; + VADisplayContextGLXP pDisplayContextGLX = NULL; + VADriverContextP pDriverContext; + VADriverContextGLXP pDriverContextGLX = NULL; + + dpy = vaGetDisplay(native_dpy); + if (!dpy) + return NULL; + pDisplayContext = (VADisplayContextP)dpy; + pDriverContext = pDisplayContext->pDriverContext; + + pDisplayContextGLX = calloc(1, sizeof(*pDisplayContextGLX)); + if (!pDisplayContextGLX) + goto error; + + pDriverContextGLX = calloc(1, sizeof(*pDriverContextGLX)); + if (!pDriverContextGLX) + goto error; + + pDisplayContextGLX->vaDestroy = pDisplayContext->vaDestroy; + pDisplayContext->vaDestroy = va_DisplayContextDestroy; + pDisplayContext->opaque = pDisplayContextGLX; + pDriverContext->glx = pDriverContextGLX; + return dpy; + +error: + free(pDriverContextGLX); + free(pDisplayContextGLX); + pDisplayContext->vaDestroy(pDisplayContext); + return NULL; +} + +// Create a surface used for display to OpenGL +VAStatus vaCreateSurfaceGLX( + VADisplay dpy, + GLenum target, + GLuint texture, + void **gl_surface +) +{ + VADriverContextP ctx; + VAStatus status; + + /* Make sure it is a valid GL texture object */ + if (!glIsTexture(texture)) + return VA_STATUS_ERROR_INVALID_PARAMETER; + + INIT_CONTEXT(ctx, dpy); + + INVOKE(ctx, CreateSurface, (ctx, target, texture, gl_surface)); + return status; +} + +// Destroy a VA/GLX surface +VAStatus vaDestroySurfaceGLX( + VADisplay dpy, + void *gl_surface +) +{ + VADriverContextP ctx; + VAStatus status; + + INIT_CONTEXT(ctx, dpy); + + INVOKE(ctx, DestroySurface, (ctx, gl_surface)); + return status; +} + +// Copy a VA surface to a VA/GLX surface +VAStatus vaCopySurfaceGLX( + VADisplay dpy, + void *gl_surface, + VASurfaceID surface, + unsigned int flags +) +{ + VADriverContextP ctx; + VAStatus status; + + INIT_CONTEXT(ctx, dpy); + + INVOKE(ctx, CopySurface, (ctx, gl_surface, surface, flags)); + return status; +} diff --git a/va/glx/va_glx.h b/va/glx/va_glx.h new file mode 100644 index 0000000..1a0624d --- /dev/null +++ b/va/glx/va_glx.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2009 Splitted-Desktop Systems. 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_GLX_H +#define VA_GLX_H + +#include <va/va.h> +#include <GL/glx.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Return a suitable VADisplay for VA API + * + * @param[in] dpy the X11 display + * @return a VADisplay + */ +VADisplay vaGetDisplayGLX( + Display *dpy +); + +/** + * Create a surface used for display to OpenGL + * + * The application shall maintain the live GLX context itself. + * Implementations are free to use glXGetCurrentContext() and + * glXGetCurrentDrawable() functions for internal purposes. + * + * @param[in] dpy the VA display + * @param[in] target the GL target to which the texture needs to be bound + * @param[in] texture the GL texture + * @param[out] gl_surface the VA/GLX surface + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus vaCreateSurfaceGLX( + VADisplay dpy, + GLenum target, + GLuint texture, + void **gl_surface +); + +/** + * Destroy a VA/GLX surface + * + * The application shall maintain the live GLX context itself. + * Implementations are free to use glXGetCurrentContext() and + * glXGetCurrentDrawable() functions for internal purposes. + * + * @param[in] dpy the VA display + * @param[in] gl_surface the VA surface + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus vaDestroySurfaceGLX( + VADisplay dpy, + void *gl_surface +); + +/** + * Copy a VA surface to a VA/GLX surface + * + * This function will not return until the copy is completed. At this + * point, the underlying GL texture will contain the surface pixels + * in an RGB format defined by the user. + * + * The application shall maintain the live GLX context itself. + * Implementations are free to use glXGetCurrentContext() and + * glXGetCurrentDrawable() functions for internal purposes. + * + * @param[in] dpy the VA display + * @param[in] gl_surface the VA/GLX destination surface + * @param[in] surface the VA source surface + * @param[in] flags the PutSurface flags + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus vaCopySurfaceGLX( + VADisplay dpy, + void *gl_surface, + VASurfaceID surface, + unsigned int flags +); + +#ifdef __cplusplus +} +#endif + +#endif /* VA_GLX_H */ diff --git a/va/glx/va_glx_impl.c b/va/glx/va_glx_impl.c new file mode 100644 index 0000000..497b64e --- /dev/null +++ b/va/glx/va_glx_impl.c @@ -0,0 +1,1078 @@ +/* + * Copyright (C) 2009 Splitted-Desktop Systems. 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. + */ + +#define _GNU_SOURCE 1 +#include "va_glx_private.h" +#include "va_glx_impl.h" +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <assert.h> +#include <dlfcn.h> + +static void va_glx_error_message(const char *format, ...) +{ + va_list args; + va_start(args, format); + fprintf(stderr, "[%s] ", PACKAGE_NAME); + vfprintf(stderr, format, args); + va_end(args); +} + +// X error trap +static int x11_error_code = 0; +static int (*old_error_handler)(Display *, XErrorEvent *); + +static int error_handler(Display *dpy, XErrorEvent *error) +{ + x11_error_code = error->error_code; + return 0; +} + +static void x11_trap_errors(void) +{ + x11_error_code = 0; + old_error_handler = XSetErrorHandler(error_handler); +} + +static int x11_untrap_errors(void) +{ + XSetErrorHandler(old_error_handler); + return x11_error_code; +} + +// Returns a string representation of an OpenGL error +static const char *gl_get_error_string(GLenum error) +{ + static const struct { + GLenum val; + const char *str; + } + gl_errors[] = { + { GL_NO_ERROR, "no error" }, + { GL_INVALID_ENUM, "invalid enumerant" }, + { GL_INVALID_VALUE, "invalid value" }, + { GL_INVALID_OPERATION, "invalid operation" }, + { GL_STACK_OVERFLOW, "stack overflow" }, + { GL_STACK_UNDERFLOW, "stack underflow" }, + { GL_OUT_OF_MEMORY, "out of memory" }, +#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT + { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "invalid framebuffer operation" }, +#endif + { ~0, NULL } + }; + + int i; + for (i = 0; gl_errors[i].str; i++) { + if (gl_errors[i].val == error) + return gl_errors[i].str; + } + return "unknown"; +} + +static inline int gl_do_check_error(int report) +{ + GLenum error; + int is_error = 0; + while ((error = glGetError()) != GL_NO_ERROR) { + if (report) + va_glx_error_message("glError: %s caught\n", + gl_get_error_string(error)); + is_error = 1; + } + return is_error; +} + +static inline void gl_purge_errors(void) +{ + gl_do_check_error(0); +} + +static inline int gl_check_error(void) +{ + return gl_do_check_error(1); +} + +// glGetTexLevelParameteriv() wrapper +static int gl_get_texture_param(GLenum param, unsigned int *pval) +{ + GLint val; + + gl_purge_errors(); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, param, &val); + if (gl_check_error()) + return 0; + if (pval) + *pval = val; + return 1; +} + +// Returns the OpenGL VTable +static inline VAOpenGLVTableP gl_get_vtable(VADriverContextP ctx) +{ + return &VA_DRIVER_CONTEXT_GLX(ctx)->gl_vtable; +} + +// Lookup for a GLX function +typedef void (*GLFuncPtr)(void); +typedef GLFuncPtr (*GLXGetProcAddressProc)(const char *); + +static GLFuncPtr get_proc_address_default(const char *name) +{ + return NULL; +} + +static GLXGetProcAddressProc get_proc_address_func(void) +{ + GLXGetProcAddressProc get_proc_func; + + dlerror(); + get_proc_func = (GLXGetProcAddressProc) + dlsym(RTLD_DEFAULT, "glXGetProcAddress"); + if (!dlerror()) + return get_proc_func; + + get_proc_func = (GLXGetProcAddressProc) + dlsym(RTLD_DEFAULT, "glXGetProcAddressARB"); + if (!dlerror()) + return get_proc_func; + + return get_proc_address_default; +} + +static inline GLFuncPtr get_proc_address(const char *name) +{ + static GLXGetProcAddressProc get_proc_func = NULL; + if (!get_proc_func) + get_proc_func = get_proc_address_func(); + return get_proc_func(name); +} + +// Check for GLX extensions (TFP, FBO) +static int check_extension(const char *name, const char *ext) +{ + const char *end; + int name_len, n; + + if (!name || !ext) + return 0; + + end = ext + strlen(ext); + name_len = strlen(name); + while (ext < end) { + n = strcspn(ext, " "); + if (n == name_len && strncmp(name, ext, n) == 0) + return 1; + ext += (n + 1); + } + return 0; +} + +static int check_tfp_extensions(VADriverContextP ctx) +{ + const char *gl_extensions; + const char *glx_extensions; + + gl_extensions = (const char *)glGetString(GL_EXTENSIONS); + if (!check_extension("GL_ARB_texture_non_power_of_two", gl_extensions)) + return 0; + + glx_extensions = glXQueryExtensionsString((Display *)ctx->native_dpy, ctx->x11_screen); + if (!check_extension("GLX_EXT_texture_from_pixmap", glx_extensions)) + return 0; + return 1; +} + +static int check_fbo_extensions(VADriverContextP ctx) +{ + const char *gl_extensions; + + gl_extensions = (const char *)glGetString(GL_EXTENSIONS); + if (check_extension("GL_ARB_framebuffer_object", gl_extensions)) + return 1; + if (check_extension("GL_EXT_framebuffer_object", gl_extensions)) + return 1; + return 0; +} + +// Load GLX extensions +static int load_tfp_extensions(VADriverContextP ctx) +{ + VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); + + pOpenGLVTable->glx_bind_tex_image = (PFNGLXBINDTEXIMAGEEXTPROC) + get_proc_address("glXBindTexImageEXT"); + if (!pOpenGLVTable->glx_bind_tex_image) + return 0; + pOpenGLVTable->glx_release_tex_image = (PFNGLXRELEASETEXIMAGEEXTPROC) + get_proc_address("glXReleaseTexImageEXT"); + if (!pOpenGLVTable->glx_release_tex_image) + return 0; + return 1; +} + +static int load_fbo_extensions(VADriverContextP ctx) +{ + VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); + + pOpenGLVTable->gl_gen_framebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) + get_proc_address("glGenFramebuffersEXT"); + if (!pOpenGLVTable->gl_gen_framebuffers) + return 0; + pOpenGLVTable->gl_delete_framebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) + get_proc_address("glDeleteFramebuffersEXT"); + if (!pOpenGLVTable->gl_delete_framebuffers) + return 0; + pOpenGLVTable->gl_bind_framebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) + get_proc_address("glBindFramebufferEXT"); + if (!pOpenGLVTable->gl_bind_framebuffer) + return 0; + pOpenGLVTable->gl_gen_renderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC) + get_proc_address("glGenRenderbuffersEXT"); + if (!pOpenGLVTable->gl_gen_renderbuffers) + return 0; + pOpenGLVTable->gl_delete_renderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC) + get_proc_address("glDeleteRenderbuffersEXT"); + if (!pOpenGLVTable->gl_delete_renderbuffers) + return 0; + pOpenGLVTable->gl_bind_renderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC) + get_proc_address("glBindRenderbufferEXT"); + if (!pOpenGLVTable->gl_bind_renderbuffer) + return 0; + pOpenGLVTable->gl_renderbuffer_storage = (PFNGLRENDERBUFFERSTORAGEEXTPROC) + get_proc_address("glRenderbufferStorageEXT"); + if (!pOpenGLVTable->gl_renderbuffer_storage) + return 0; + pOpenGLVTable->gl_framebuffer_renderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) + get_proc_address("glFramebufferRenderbufferEXT"); + if (!pOpenGLVTable->gl_framebuffer_renderbuffer) + return 0; + pOpenGLVTable->gl_framebuffer_texture_2d = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) + get_proc_address("glFramebufferTexture2DEXT"); + if (!pOpenGLVTable->gl_framebuffer_texture_2d) + return 0; + pOpenGLVTable->gl_check_framebuffer_status = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) + get_proc_address("glCheckFramebufferStatusEXT"); + if (!pOpenGLVTable->gl_check_framebuffer_status) + return 0; + return 1; +} + + +/* ========================================================================= */ +/* === VA/GLX helpers === */ +/* ========================================================================= */ + +// OpenGL context state +typedef struct OpenGLContextState *OpenGLContextStateP; + +struct OpenGLContextState { + Display *display; + Window window; + GLXContext context; +}; + +static void +gl_destroy_context(OpenGLContextStateP cs) +{ + if (!cs) + return; + + if (cs->display && cs->context) { + if (glXGetCurrentContext() == cs->context) + glXMakeCurrent(cs->display, None, NULL); + glXDestroyContext(cs->display, cs->context); + cs->display = NULL; + cs->context = NULL; + } + free(cs); +} + +static OpenGLContextStateP +gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent) +{ + OpenGLContextStateP cs; + GLXFBConfig *fbconfigs = NULL; + int fbconfig_id, val, n, n_fbconfigs; + Status status; + + static GLint fbconfig_attrs[] = { + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DOUBLEBUFFER, True, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + None + }; + + cs = malloc(sizeof(*cs)); + if (!cs) + goto error; + + cs->display = (Display *)ctx->native_dpy; + cs->window = parent ? parent->window : None; + cs->context = NULL; + + if (parent && parent->context) { + status = glXQueryContext( + parent->display, + parent->context, + GLX_FBCONFIG_ID, &fbconfig_id + ); + if (status != Success) + goto error; + + if (fbconfig_id == GLX_DONT_CARE) + goto choose_fbconfig; + + fbconfigs = glXGetFBConfigs( + (Display *)ctx->native_dpy, + ctx->x11_screen, + &n_fbconfigs + ); + if (!fbconfigs) + goto error; + + /* Find out a GLXFBConfig compatible with the parent context */ + for (n = 0; n < n_fbconfigs; n++) { + status = glXGetFBConfigAttrib( + (Display *)ctx->native_dpy, + fbconfigs[n], + GLX_FBCONFIG_ID, &val + ); + if (status == Success && val == fbconfig_id) + break; + } + if (n == n_fbconfigs) + goto error; + } + else { + choose_fbconfig: + fbconfigs = glXChooseFBConfig( + (Display *)ctx->native_dpy, + ctx->x11_screen, + fbconfig_attrs, &n_fbconfigs + ); + if (!fbconfigs) + goto error; + + /* Select the first one */ + n = 0; + } + + cs->context = glXCreateNewContext( + (Display *)ctx->native_dpy, + fbconfigs[n], + GLX_RGBA_TYPE, + parent ? parent->context : NULL, + True + ); + if (cs->context) + goto end; + +error: + gl_destroy_context(cs); + cs = NULL; +end: + if (fbconfigs) + XFree(fbconfigs); + return cs; +} + +static void gl_get_current_context(OpenGLContextStateP cs) +{ + cs->display = glXGetCurrentDisplay(); + cs->window = glXGetCurrentDrawable(); + cs->context = glXGetCurrentContext(); +} + +static int +gl_set_current_context(OpenGLContextStateP new_cs, OpenGLContextStateP old_cs) +{ + /* If display is NULL, this could be that new_cs was retrieved from + gl_get_current_context() with none set previously. If that case, + the other fields are also NULL and we don't return an error */ + if (!new_cs->display) + return !new_cs->window && !new_cs->context; + + if (old_cs) { + if (old_cs == new_cs) + return 1; + gl_get_current_context(old_cs); + if (old_cs->display == new_cs->display && + old_cs->window == new_cs->window && + old_cs->context == new_cs->context) + return 1; + } + return glXMakeCurrent(new_cs->display, new_cs->window, new_cs->context); +} + +/** Unique VASurfaceGLX identifier */ +#define VA_SURFACE_GLX_MAGIC VA_FOURCC('V','A','G','L') + +struct VASurfaceGLX { + uint32_t magic; ///< Magic number identifying a VASurfaceGLX + GLenum target; ///< GL target to which the texture is bound + GLuint texture; ///< GL texture + VASurfaceID surface; ///< Associated VA surface + unsigned int width; + unsigned int height; + OpenGLContextStateP gl_context; + int is_bound; + Pixmap pixmap; + GLuint pix_texture; + GLXPixmap glx_pixmap; + GLuint fbo; +}; + +// Create Pixmaps for GLX texture-from-pixmap extension +static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + const unsigned int width = pSurfaceGLX->width; + const unsigned int height = pSurfaceGLX->height; + Pixmap pixmap = None; + GLXFBConfig *fbconfig = NULL; + GLXPixmap glx_pixmap = None; + Window root_window; + XWindowAttributes wattr; + int *attrib; + int n_fbconfig_attrs; + + root_window = RootWindow((Display *)ctx->native_dpy, ctx->x11_screen); + XGetWindowAttributes((Display *)ctx->native_dpy, root_window, &wattr); + if (wattr.depth != 24 && wattr.depth != 32) + return 0; + pixmap = XCreatePixmap( + (Display *)ctx->native_dpy, + root_window, + width, + height, + wattr.depth + ); + if (!pixmap) + return 0; + pSurfaceGLX->pixmap = pixmap; + + int fbconfig_attrs[32] = { + GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, + GLX_DOUBLEBUFFER, GL_TRUE, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_RENDERABLE, GL_TRUE, + GLX_Y_INVERTED_EXT, GL_TRUE, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GL_NONE, + }; + for (attrib = fbconfig_attrs; *attrib != GL_NONE; attrib += 2) + ; + *attrib++ = GLX_DEPTH_SIZE; *attrib++ = wattr.depth; + if (wattr.depth == 32) { + *attrib++ = GLX_ALPHA_SIZE; *attrib++ = 8; + *attrib++ = GLX_BIND_TO_TEXTURE_RGBA_EXT; *attrib++ = GL_TRUE; + } + else { + *attrib++ = GLX_BIND_TO_TEXTURE_RGB_EXT; *attrib++ = GL_TRUE; + } + *attrib++ = GL_NONE; + + fbconfig = glXChooseFBConfig( + (Display *)ctx->native_dpy, + ctx->x11_screen, + fbconfig_attrs, + &n_fbconfig_attrs + ); + if (!fbconfig) + return 0; + + int pixmap_attrs[10] = { + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_MIPMAP_TEXTURE_EXT, GL_FALSE, + GL_NONE, + }; + for (attrib = pixmap_attrs; *attrib != GL_NONE; attrib += 2) + ; + *attrib++ = GLX_TEXTURE_FORMAT_EXT; + if (wattr.depth == 32) + *attrib++ = GLX_TEXTURE_FORMAT_RGBA_EXT; + else + *attrib++ = GLX_TEXTURE_FORMAT_RGB_EXT; + *attrib++ = GL_NONE; + + x11_trap_errors(); + glx_pixmap = glXCreatePixmap( + (Display *)ctx->native_dpy, + fbconfig[0], + pixmap, + pixmap_attrs + ); + free(fbconfig); + if (x11_untrap_errors() != 0) + return 0; + pSurfaceGLX->glx_pixmap = glx_pixmap; + + glGenTextures(1, &pSurfaceGLX->pix_texture); + glBindTexture(GL_TEXTURE_2D, pSurfaceGLX->pix_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + return 1; +} + +// Destroy Pixmaps used for TFP +static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + if (pSurfaceGLX->pix_texture) { + glDeleteTextures(1, &pSurfaceGLX->pix_texture); + pSurfaceGLX->pix_texture = 0; + } + + if (pSurfaceGLX->glx_pixmap) { + glXDestroyPixmap((Display *)ctx->native_dpy, pSurfaceGLX->glx_pixmap); + pSurfaceGLX->glx_pixmap = None; + } + + if (pSurfaceGLX->pixmap) { + XFreePixmap((Display *)ctx->native_dpy, pSurfaceGLX->pixmap); + pSurfaceGLX->pixmap = None; + } +} + +// Bind GLX Pixmap to texture +static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); + + if (pSurfaceGLX->is_bound) + return 1; + + glBindTexture(GL_TEXTURE_2D, pSurfaceGLX->pix_texture); + + x11_trap_errors(); + pOpenGLVTable->glx_bind_tex_image( + (Display *)ctx->native_dpy, + pSurfaceGLX->glx_pixmap, + GLX_FRONT_LEFT_EXT, + NULL + ); + XSync((Display *)ctx->native_dpy, False); + if (x11_untrap_errors() != 0) { + va_glx_error_message("failed to bind pixmap\n"); + return 0; + } + + pSurfaceGLX->is_bound = 1; + return 1; +} + +// Release GLX Pixmap from texture +static int unbind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); + + if (!pSurfaceGLX->is_bound) + return 1; + + x11_trap_errors(); + pOpenGLVTable->glx_release_tex_image( + (Display *)ctx->native_dpy, + pSurfaceGLX->glx_pixmap, + GLX_FRONT_LEFT_EXT + ); + XSync((Display *)ctx->native_dpy, False); + if (x11_untrap_errors() != 0) { + va_glx_error_message("failed to release pixmap\n"); + return 0; + } + + glBindTexture(GL_TEXTURE_2D, 0); + + pSurfaceGLX->is_bound = 0; + return 1; +} + +// Render GLX Pixmap to texture +static void render_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + const unsigned int w = pSurfaceGLX->width; + const unsigned int h = pSurfaceGLX->height; + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBegin(GL_QUADS); + { + glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0); + glTexCoord2f(0.0f, 1.0f); glVertex2i(0, h); + glTexCoord2f(1.0f, 1.0f); glVertex2i(w, h); + glTexCoord2f(1.0f, 0.0f); glVertex2i(w, 0); + } + glEnd(); +} + +// Create offscreen surface +static int create_fbo_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); + GLuint fbo; + GLenum status; + + pOpenGLVTable->gl_gen_framebuffers(1, &fbo); + pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo); + pOpenGLVTable->gl_framebuffer_texture_2d( + GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + pSurfaceGLX->texture, + 0 + ); + + status = pOpenGLVTable->gl_check_framebuffer_status(GL_DRAW_FRAMEBUFFER_EXT); + pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, 0); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + return 0; + + pSurfaceGLX->fbo = fbo; + return 1; +} + +// Destroy offscreen surface +static void destroy_fbo_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); + + if (pSurfaceGLX->fbo) { + pOpenGLVTable->gl_delete_framebuffers(1, &pSurfaceGLX->fbo); + pSurfaceGLX->fbo = 0; + } +} + +// Setup matrices to match the FBO texture dimensions +static void fbo_enter(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); + const unsigned int width = pSurfaceGLX->width; + const unsigned int height = pSurfaceGLX->height; + + pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, pSurfaceGLX->fbo); + glPushAttrib(GL_VIEWPORT_BIT); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glViewport(0, 0, width, height); + glTranslatef(-1.0f, -1.0f, 0.0f); + glScalef(2.0f / width, 2.0f / height, 1.0f); +} + +// Restore original OpenGL matrices +static void fbo_leave(VADriverContextP ctx) +{ + VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); + + glPopAttrib(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, 0); +} + +// Check internal texture format is supported +static int is_supported_internal_format(GLenum format) +{ + /* XXX: we don't support other textures than RGBA */ + switch (format) { + case 4: + case GL_RGBA: + case GL_RGBA8: + return 1; + } + return 0; +} + +// Destroy VA/GLX surface +static void +destroy_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + unbind_pixmap(ctx, pSurfaceGLX); + destroy_fbo_surface(ctx, pSurfaceGLX); + destroy_tfp_surface(ctx, pSurfaceGLX); + free(pSurfaceGLX); +} + +// Create VA/GLX surface +static VASurfaceGLXP +create_surface(VADriverContextP ctx, GLenum target, GLuint texture) +{ + VASurfaceGLXP pSurfaceGLX = NULL; + unsigned int internal_format, border_width, width, height; + int is_error = 1; + + pSurfaceGLX = malloc(sizeof(*pSurfaceGLX)); + if (!pSurfaceGLX) + goto end; + + pSurfaceGLX->magic = VA_SURFACE_GLX_MAGIC; + pSurfaceGLX->target = target; + pSurfaceGLX->texture = texture; + pSurfaceGLX->surface = VA_INVALID_SURFACE; + pSurfaceGLX->gl_context = NULL; + pSurfaceGLX->is_bound = 0; + pSurfaceGLX->pixmap = None; + pSurfaceGLX->pix_texture = 0; + pSurfaceGLX->glx_pixmap = None; + pSurfaceGLX->fbo = 0; + + glEnable(target); + glBindTexture(target, texture); + if (!gl_get_texture_param(GL_TEXTURE_INTERNAL_FORMAT, &internal_format)) + goto end; + if (!is_supported_internal_format(internal_format)) + goto end; + + /* Check texture dimensions */ + if (!gl_get_texture_param(GL_TEXTURE_BORDER, &border_width)) + goto end; + if (!gl_get_texture_param(GL_TEXTURE_WIDTH, &width)) + goto end; + if (!gl_get_texture_param(GL_TEXTURE_HEIGHT, &height)) + goto end; + + width -= 2 * border_width; + height -= 2 * border_width; + if (width == 0 || height == 0) + goto end; + + pSurfaceGLX->width = width; + pSurfaceGLX->height = height; + + /* Create TFP objects */ + if (!create_tfp_surface(ctx, pSurfaceGLX)) + goto end; + + /* Create FBO objects */ + if (!create_fbo_surface(ctx, pSurfaceGLX)) + goto end; + + is_error = 0; +end: + if (is_error && pSurfaceGLX) { + destroy_surface(ctx, pSurfaceGLX); + pSurfaceGLX = NULL; + } + return pSurfaceGLX; +} + + +/* ========================================================================= */ +/* === VA/GLX implementation from the driver (fordward calls) === */ +/* ========================================================================= */ + +#define INVOKE(ctx, func, args) do { \ + VADriverVTableGLXP vtable = (ctx)->vtable.glx; \ + if (!vtable->va##func##GLX) \ + return VA_STATUS_ERROR_UNIMPLEMENTED; \ + \ + VAStatus status = vtable->va##func##GLX args; \ + if (status != VA_STATUS_SUCCESS) \ + return status; \ + } while (0) + +static VAStatus +vaCreateSurfaceGLX_impl_driver( + VADriverContextP ctx, + GLenum target, + GLuint texture, + void **gl_surface +) +{ + INVOKE(ctx, CreateSurface, (ctx, target, texture, gl_surface)); + return VA_STATUS_SUCCESS; +} + +static VAStatus +vaDestroySurfaceGLX_impl_driver(VADriverContextP ctx, void *gl_surface) +{ + INVOKE(ctx, DestroySurface, (ctx, gl_surface)); + return VA_STATUS_SUCCESS; +} + +static VAStatus +vaCopySurfaceGLX_impl_driver( + VADriverContextP ctx, + void *gl_surface, + VASurfaceID surface, + unsigned int flags +) +{ + INVOKE(ctx, CopySurface, (ctx, gl_surface, surface, flags)); + return VA_STATUS_SUCCESS; +} + +#undef INVOKE + + +/* ========================================================================= */ +/* === VA/GLX implementation from libVA (generic and suboptimal path) === */ +/* ========================================================================= */ + +#define INIT_SURFACE(surface, surface_arg) do { \ + surface = (VASurfaceGLXP)(surface_arg); \ + if (!check_surface(surface)) \ + return VA_STATUS_ERROR_INVALID_SURFACE; \ + } while (0) + +// Check VASurfaceGLX is valid +static inline int check_surface(VASurfaceGLXP pSurfaceGLX) +{ + return pSurfaceGLX && pSurfaceGLX->magic == VA_SURFACE_GLX_MAGIC; +} + +static VAStatus +vaCreateSurfaceGLX_impl_libva( + VADriverContextP ctx, + GLenum target, + GLuint texture, + void **gl_surface +) +{ + VASurfaceGLXP pSurfaceGLX; + struct OpenGLContextState old_cs, *new_cs; + + gl_get_current_context(&old_cs); + new_cs = gl_create_context(ctx, &old_cs); + if (!new_cs) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (!gl_set_current_context(new_cs, NULL)) + return VA_STATUS_ERROR_OPERATION_FAILED; + + pSurfaceGLX = create_surface(ctx, target, texture); + if (!pSurfaceGLX) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + pSurfaceGLX->gl_context = new_cs; + *gl_surface = pSurfaceGLX; + + gl_set_current_context(&old_cs, NULL); + return VA_STATUS_SUCCESS; +} + +static VAStatus +vaDestroySurfaceGLX_impl_libva(VADriverContextP ctx, void *gl_surface) +{ + VASurfaceGLXP pSurfaceGLX; + struct OpenGLContextState old_cs, *new_cs; + + INIT_SURFACE(pSurfaceGLX, gl_surface); + + new_cs = pSurfaceGLX->gl_context; + if (!gl_set_current_context(new_cs, &old_cs)) + return VA_STATUS_ERROR_OPERATION_FAILED; + + destroy_surface(ctx, pSurfaceGLX); + + gl_destroy_context(new_cs); + gl_set_current_context(&old_cs, NULL); + return VA_STATUS_SUCCESS; +} + +static inline VAStatus +deassociate_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + if (!unbind_pixmap(ctx, pSurfaceGLX)) + return VA_STATUS_ERROR_OPERATION_FAILED; + + pSurfaceGLX->surface = VA_INVALID_SURFACE; + return VA_STATUS_SUCCESS; +} + +static VAStatus +associate_surface( + VADriverContextP ctx, + VASurfaceGLXP pSurfaceGLX, + VASurfaceID surface, + unsigned int flags +) +{ + VAStatus status; + + /* XXX: optimise case where we are associating the same VA surface + as before an no changed occurred to it */ + status = deassociate_surface(ctx, pSurfaceGLX); + if (status != VA_STATUS_SUCCESS) + return status; + + x11_trap_errors(); + status = ctx->vtable.vaPutSurface( + ctx, + surface, + (void *)pSurfaceGLX->pixmap, + 0, 0, pSurfaceGLX->width, pSurfaceGLX->height, + 0, 0, pSurfaceGLX->width, pSurfaceGLX->height, + NULL, 0, + flags + ); + XSync((Display *)ctx->native_dpy, False); + if (x11_untrap_errors() != 0) + return VA_STATUS_ERROR_OPERATION_FAILED; + if (status != VA_STATUS_SUCCESS) + return status; + + pSurfaceGLX->surface = surface; + return VA_STATUS_SUCCESS; +} + +static inline VAStatus +sync_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + if (pSurfaceGLX->surface == VA_INVALID_SURFACE) + return VA_STATUS_ERROR_INVALID_SURFACE; + + return ctx->vtable.vaSyncSurface(ctx, pSurfaceGLX->surface); +} + +static inline VAStatus +begin_render_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + VAStatus status; + + status = sync_surface(ctx, pSurfaceGLX); + if (status != VA_STATUS_SUCCESS) + return status; + + if (!bind_pixmap(ctx, pSurfaceGLX)) + return VA_STATUS_ERROR_OPERATION_FAILED; + + return VA_STATUS_SUCCESS; +} + +static inline VAStatus +end_render_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) +{ + if (!unbind_pixmap(ctx, pSurfaceGLX)) + return VA_STATUS_ERROR_OPERATION_FAILED; + + return VA_STATUS_SUCCESS; +} + +static VAStatus +copy_surface( + VADriverContextP ctx, + VASurfaceGLXP pSurfaceGLX, + VASurfaceID surface, + unsigned int flags +) +{ + VAStatus status; + + /* Associate VA surface */ + status = associate_surface(ctx, pSurfaceGLX, surface, flags); + if (status != VA_STATUS_SUCCESS) + return status; + + /* Render to FBO */ + fbo_enter(ctx, pSurfaceGLX); + status = begin_render_surface(ctx, pSurfaceGLX); + if (status == VA_STATUS_SUCCESS) { + render_pixmap(ctx, pSurfaceGLX); + status = end_render_surface(ctx, pSurfaceGLX); + } + fbo_leave(ctx); + if (status != VA_STATUS_SUCCESS) + return status; + + return deassociate_surface(ctx, pSurfaceGLX); +} + +static VAStatus +vaCopySurfaceGLX_impl_libva( + VADriverContextP ctx, + void *gl_surface, + VASurfaceID surface, + unsigned int flags +) +{ + VASurfaceGLXP pSurfaceGLX; + VAStatus status; + struct OpenGLContextState old_cs; + + INIT_SURFACE(pSurfaceGLX, gl_surface); + + if (!gl_set_current_context(pSurfaceGLX->gl_context, &old_cs)) + return VA_STATUS_ERROR_OPERATION_FAILED; + + status = copy_surface(ctx, pSurfaceGLX, surface, flags); + + gl_set_current_context(&old_cs, NULL); + return status; +} + +#undef INIT_SURFACE + + +/* ========================================================================= */ +/* === Private VA/GLX vtable initialization === */ +/* ========================================================================= */ + +// Initialize GLX driver context +VAStatus va_glx_init_context(VADriverContextP ctx) +{ + VADriverContextGLXP glx_ctx = VA_DRIVER_CONTEXT_GLX(ctx); + VADriverVTableGLXP vtable = &glx_ctx->vtable; + int glx_major, glx_minor; + + if (glx_ctx->is_initialized) + return VA_STATUS_SUCCESS; + + if (ctx->vtable.glx && ctx->vtable.glx->vaCopySurfaceGLX) { + vtable->vaCreateSurfaceGLX = vaCreateSurfaceGLX_impl_driver; + vtable->vaDestroySurfaceGLX = vaDestroySurfaceGLX_impl_driver; + vtable->vaCopySurfaceGLX = vaCopySurfaceGLX_impl_driver; + } + else { + vtable->vaCreateSurfaceGLX = vaCreateSurfaceGLX_impl_libva; + vtable->vaDestroySurfaceGLX = vaDestroySurfaceGLX_impl_libva; + vtable->vaCopySurfaceGLX = vaCopySurfaceGLX_impl_libva; + + if (!glXQueryVersion((Display *)ctx->native_dpy, &glx_major, &glx_minor)) + return VA_STATUS_ERROR_UNIMPLEMENTED; + if (glx_major < 1 || (glx_major == 1 && glx_minor < 3)) { /* GLX 1.3 */ + va_glx_error_message("GLX version 1.3 expected but only " + "version %d.%d is available\n", + glx_major, glx_minor); + return VA_STATUS_ERROR_UNIMPLEMENTED; + } + + if (!check_tfp_extensions(ctx) || !load_tfp_extensions(ctx)) + return VA_STATUS_ERROR_UNIMPLEMENTED; + + if (!check_fbo_extensions(ctx) || !load_fbo_extensions(ctx)) + return VA_STATUS_ERROR_UNIMPLEMENTED; + } + + glx_ctx->is_initialized = 1; + return VA_STATUS_SUCCESS; +} diff --git a/va/glx/va_glx_impl.h b/va/glx/va_glx_impl.h new file mode 100644 index 0000000..fbdcac2 --- /dev/null +++ b/va/glx/va_glx_impl.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009 Splitted-Desktop Systems. 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_GLX_IMPL_H +#define VA_GLX_IMPL_H + +/** + * Initialize GLX driver context + * + * @param[in] ctx the VA driver context + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus va_glx_init_context(VADriverContextP ctx); + /* ATTRIBUTE_HIDDEN; */ + +#endif /* VA_GLX_IMPL_H */ diff --git a/va/glx/va_glx_private.h b/va/glx/va_glx_private.h new file mode 100644 index 0000000..6667de9 --- /dev/null +++ b/va/glx/va_glx_private.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2009 Splitted-Desktop Systems. 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_GLX_PRIVATE_H +#define VA_GLX_PRIVATE_H + +#include "config.h" +#include "va.h" +#include "va_backend.h" +#include "va_x11.h" +#include "va_glx.h" +#include "va_backend_glx.h" + +#if GLX_GLXEXT_VERSION < 18 +typedef void (*PFNGLXBINDTEXIMAGEEXTPROC)(Display *, GLXDrawable, int, const int *); +typedef void (*PFNGLXRELEASETEXIMAGEEXTPROC)(Display *, GLXDrawable, int); +#endif + +typedef struct VAOpenGLVTable *VAOpenGLVTableP; + +struct VAOpenGLVTable { + PFNGLXBINDTEXIMAGEEXTPROC glx_bind_tex_image; + PFNGLXRELEASETEXIMAGEEXTPROC glx_release_tex_image; + PFNGLGENFRAMEBUFFERSEXTPROC gl_gen_framebuffers; + PFNGLDELETEFRAMEBUFFERSEXTPROC gl_delete_framebuffers; + PFNGLBINDFRAMEBUFFEREXTPROC gl_bind_framebuffer; + PFNGLGENRENDERBUFFERSEXTPROC gl_gen_renderbuffers; + PFNGLDELETERENDERBUFFERSEXTPROC gl_delete_renderbuffers; + PFNGLBINDRENDERBUFFEREXTPROC gl_bind_renderbuffer; + PFNGLRENDERBUFFERSTORAGEEXTPROC gl_renderbuffer_storage; + PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC gl_framebuffer_renderbuffer; + PFNGLFRAMEBUFFERTEXTURE2DEXTPROC gl_framebuffer_texture_2d; + PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC gl_check_framebuffer_status; +}; + +typedef struct VADisplayContextGLX *VADisplayContextGLXP; +typedef struct VADriverContextGLX *VADriverContextGLXP; +typedef struct VASurfaceGLX *VASurfaceGLXP; +typedef struct VADriverVTableGLX *VADriverVTableGLXP; + +typedef void (*vaDestroyFunc)(VADisplayContextP); + +struct VADisplayContextGLX { + vaDestroyFunc vaDestroy; +}; + +#define VA_DRIVER_CONTEXT_GLX(ctx) ((VADriverContextGLXP)((ctx)->glx)) + +struct VADriverContextGLX { + struct VADriverVTableGLX vtable; + struct VAOpenGLVTable gl_vtable; + unsigned int is_initialized : 1; +}; + +#endif /* VA_GLX_PRIVATE_H */ @@ -23,9 +23,9 @@ */ #define _GNU_SOURCE 1 - #include "va.h" #include "va_backend.h" +#include "config.h" #include <assert.h> #include <stdarg.h> @@ -35,6 +35,11 @@ #include <dlfcn.h> #include <unistd.h> +#ifdef ANDROID +#define Bool int +#define True 1 +#define False 0 +#endif #define DRIVER_INIT_FUNC "__vaDriverInit_0_31" @@ -48,14 +53,17 @@ #define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN; #define CHECK_STRING(s, ctx, var) if (!va_checkString(ctx->str_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN; -#define TRACE(func) if (va_debug_trace) va_infoMessage("[TR] %s\n", #func); - -static int va_debug_trace = 0; +extern int trace_flag; +#define VA_TRACE(trace_func,...) \ + if (trace_flag) { \ + va_TraceMsg("========%s========\n", __func__); \ + trace_func(__VA_ARGS__); \ + } -static int vaDisplayIsValid(VADisplay dpy) +int vaDisplayIsValid(VADisplay dpy) { - VADisplayContextP pDisplayContext = (VADisplayContextP)dpy; - return pDisplayContext && (pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC) && pDisplayContext->vaIsValid(pDisplayContext); + VADisplayContextP pDisplayContext = (VADisplayContextP)dpy; + return pDisplayContext && (pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC) && pDisplayContext->vaIsValid(pDisplayContext); } static void va_errorMessage(const char *msg, ...) @@ -127,10 +135,6 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name) { /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */ search_path = getenv("LIBVA_DRIVERS_PATH"); - if (!search_path) - { - search_path = getenv("LIBGL_DRIVERS_PATH"); - } } if (!search_path) { @@ -151,8 +155,11 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name) strncat( driver_path, DRIVER_EXTENSION, strlen(DRIVER_EXTENSION) ); va_infoMessage("Trying to open %s\n", driver_path); - +#ifndef ANDROID handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE ); +#else + handle = dlopen( driver_path, RTLD_NOW| RTLD_GLOBAL); +#endif if (!handle) { /* Don't give errors for non-existing files */ @@ -324,30 +331,42 @@ VAStatus vaInitialize ( int *minor_version /* out */ ) { - char *driver_name = NULL; - VAStatus vaStatus; - - CHECK_DISPLAY(dpy); + const char *driver_name_env = NULL; + char *driver_name = NULL; + VAStatus vaStatus; - va_debug_trace = (getenv("LIBVA_DEBUG_TRACE") != NULL); + CHECK_DISPLAY(dpy); - va_infoMessage("libva version %s\n", VA_VERSION_S); + va_TraceInit(); - vaStatus = va_getDriverName(dpy, &driver_name); - va_infoMessage("va_getDriverName() returns %d\n", vaStatus); - - if (VA_STATUS_SUCCESS == vaStatus) - { - vaStatus = va_openDriver(dpy, driver_name); - va_infoMessage("va_openDriver() returns %d\n", vaStatus); - - *major_version = VA_MAJOR_VERSION; - *minor_version = VA_MINOR_VERSION; - } + va_infoMessage("libva version %s\n", VA_VERSION_S); - if (driver_name) - free(driver_name); - return vaStatus; + driver_name_env = getenv("LIBVA_DRIVER_NAME"); + if (driver_name_env && geteuid() == getuid()) + { + /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */ + driver_name = strdup(driver_name_env); + vaStatus = VA_STATUS_SUCCESS; + va_infoMessage("User requested driver '%s'\n", driver_name); + } + else + { + vaStatus = va_getDriverName(dpy, &driver_name); + va_infoMessage("va_getDriverName() returns %d\n", vaStatus); + } + + if (VA_STATUS_SUCCESS == vaStatus) + { + vaStatus = va_openDriver(dpy, driver_name); + va_infoMessage("va_openDriver() returns %d\n", vaStatus); + + *major_version = VA_MAJOR_VERSION; + *minor_version = VA_MINOR_VERSION; + } + + if (driver_name) + free(driver_name); + return vaStatus; } @@ -374,6 +393,9 @@ VAStatus vaTerminate ( if (VA_STATUS_SUCCESS == vaStatus) pDisplayContext->vaDestroy(pDisplayContext); + + va_TraceEnd(); + return vaStatus; } @@ -441,7 +463,6 @@ VAStatus vaQueryConfigEntrypoints ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaQueryConfigEntrypoints); return ctx->vtable.vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints); } @@ -457,7 +478,6 @@ VAStatus vaGetConfigAttributes ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaGetConfigAttributes); return ctx->vtable.vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs ); } @@ -471,7 +491,6 @@ VAStatus vaQueryConfigProfiles ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaQueryConfigProfiles); return ctx->vtable.vaQueryConfigProfiles ( ctx, profile_list, num_profiles ); } @@ -488,7 +507,7 @@ VAStatus vaCreateConfig ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaCreateConfig); + VA_TRACE(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id); return ctx->vtable.vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id ); } @@ -501,7 +520,6 @@ VAStatus vaDestroyConfig ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaDestroyConfig); return ctx->vtable.vaDestroyConfig ( ctx, config_id ); } @@ -518,7 +536,6 @@ VAStatus vaQueryConfigAttributes ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaQueryConfigAttributes); return ctx->vtable.vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs); } @@ -535,7 +552,7 @@ VAStatus vaCreateSurfaces ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaCreateSurfaces); + VA_TRACE(va_TraceCreateSurface, dpy, width, height, format, num_surfaces, surfaces); return ctx->vtable.vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces ); } @@ -550,7 +567,6 @@ VAStatus vaDestroySurfaces ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaDestroySurfaces); return ctx->vtable.vaDestroySurfaces( ctx, surface_list, num_surfaces ); } @@ -569,7 +585,7 @@ VAStatus vaCreateContext ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaCreateContext); + VA_TRACE(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context); return ctx->vtable.vaCreateContext( ctx, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context ); } @@ -583,7 +599,6 @@ VAStatus vaDestroyContext ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaDestroyContext); return ctx->vtable.vaDestroyContext( ctx, context ); } @@ -601,7 +616,6 @@ VAStatus vaCreateBuffer ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaCreateBuffer); return ctx->vtable.vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id); } @@ -615,7 +629,6 @@ VAStatus vaBufferSetNumElements ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaBufferSetNumElements); return ctx->vtable.vaBufferSetNumElements( ctx, buf_id, num_elements ); } @@ -630,7 +643,6 @@ VAStatus vaMapBuffer ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaMapBuffer); return ctx->vtable.vaMapBuffer( ctx, buf_id, pbuf ); } @@ -643,7 +655,6 @@ VAStatus vaUnmapBuffer ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaUnmapBuffer); return ctx->vtable.vaUnmapBuffer( ctx, buf_id ); } @@ -656,10 +667,25 @@ VAStatus vaDestroyBuffer ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaDestroyBuffer); return ctx->vtable.vaDestroyBuffer( ctx, buffer_id ); } +VAStatus vaBufferInfo ( + VADisplay dpy, + VAContextID context, /* in */ + VABufferID buf_id, /* in */ + VABufferType *type, /* out */ + unsigned int *size, /* out */ + unsigned int *num_elements /* out */ +) +{ + VADriverContextP ctx; + CHECK_DISPLAY(dpy); + ctx = CTX(dpy); + + return ctx->vtable.vaBufferInfo( ctx, context, buf_id, type, size, num_elements ); +} + VAStatus vaBeginPicture ( VADisplay dpy, VAContextID context, @@ -670,7 +696,7 @@ VAStatus vaBeginPicture ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaBeginPicture); + VA_TRACE(va_TraceBeginPicture, ctx, context, render_target); return ctx->vtable.vaBeginPicture( ctx, context, render_target ); } @@ -685,7 +711,7 @@ VAStatus vaRenderPicture ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaRenderPicture); + VA_TRACE(va_TraceRenderPicture, dpy, context, buffers, num_buffers); return ctx->vtable.vaRenderPicture( ctx, context, buffers, num_buffers ); } @@ -694,12 +720,14 @@ VAStatus vaEndPicture ( VAContextID context ) { + VAStatus va_status; VADriverContextP ctx; CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaEndPicture); - return ctx->vtable.vaEndPicture( ctx, context ); + va_status = ctx->vtable.vaEndPicture( ctx, context ); + VA_TRACE(va_TraceEndPicture, dpy, context); + return va_status; } VAStatus vaSyncSurface ( @@ -711,7 +739,6 @@ VAStatus vaSyncSurface ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaSyncSurface); return ctx->vtable.vaSyncSurface( ctx, render_target ); } @@ -725,37 +752,9 @@ VAStatus vaQuerySurfaceStatus ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaQuerySurfaceStatus); return ctx->vtable.vaQuerySurfaceStatus( ctx, render_target, status ); } -VAStatus vaPutSurface ( - VADisplay dpy, - VASurfaceID surface, - Drawable draw, /* X Drawable */ - short srcx, - short srcy, - unsigned short srcw, - unsigned short srch, - short destx, - short desty, - unsigned short destw, - unsigned short desth, - VARectangle *cliprects, /* client supplied clip list */ - unsigned int number_cliprects, /* number of clip rects in the clip list */ - unsigned int flags /* de-interlacing flags */ -) -{ - VADriverContextP ctx; - CHECK_DISPLAY(dpy); - ctx = CTX(dpy); - - TRACE(vaPutSurface); - return ctx->vtable.vaPutSurface( ctx, surface, draw, srcx, srcy, srcw, srch, - destx, desty, destw, desth, - cliprects, number_cliprects, flags ); -} - /* Get maximum number of image formats supported by the implementation */ int vaMaxNumImageFormats ( VADisplay dpy @@ -777,7 +776,6 @@ VAStatus vaQueryImageFormats ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaQueryImageFormats); return ctx->vtable.vaQueryImageFormats ( ctx, format_list, num_formats); } @@ -801,7 +799,6 @@ VAStatus vaCreateImage ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaCreateImage); return ctx->vtable.vaCreateImage ( ctx, format, width, height, image); } @@ -817,7 +814,6 @@ VAStatus vaDestroyImage ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaDestroyImage); return ctx->vtable.vaDestroyImage ( ctx, image); } @@ -831,7 +827,6 @@ VAStatus vaSetImagePalette ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaSetImagePalette); return ctx->vtable.vaSetImagePalette ( ctx, image, palette); } @@ -853,7 +848,6 @@ VAStatus vaGetImage ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaGetImage); return ctx->vtable.vaGetImage ( ctx, surface, x, y, width, height, image); } @@ -879,7 +873,6 @@ VAStatus vaPutImage ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaPutImage); return ctx->vtable.vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height ); } @@ -924,7 +917,6 @@ VAStatus vaDeriveImage ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaDeriveImage); return ctx->vtable.vaDeriveImage ( ctx, surface, image ); } @@ -958,7 +950,6 @@ VAStatus vaQuerySubpictureFormats ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaQuerySubpictureFormats); return ctx->vtable.vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats); } @@ -975,7 +966,6 @@ VAStatus vaCreateSubpicture ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaCreateSubpicture); return ctx->vtable.vaCreateSubpicture ( ctx, image, subpicture ); } @@ -991,7 +981,6 @@ VAStatus vaDestroySubpicture ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaDestroySubpicture); return ctx->vtable.vaDestroySubpicture ( ctx, subpicture); } @@ -1005,7 +994,6 @@ VAStatus vaSetSubpictureImage ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaSetSubpictureImage); return ctx->vtable.vaSetSubpictureImage ( ctx, subpicture, image); } @@ -1026,7 +1014,6 @@ VAStatus vaSetSubpictureChromakey ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaSetSubpictureChromakey); return ctx->vtable.vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask ); } @@ -1046,7 +1033,6 @@ VAStatus vaSetSubpictureGlobalAlpha ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaSetSubpictureGlobalAlpha); return ctx->vtable.vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha ); } @@ -1081,7 +1067,6 @@ VAStatus vaAssociateSubpicture ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaAssociateSubpicture); return ctx->vtable.vaAssociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height, flags ); } @@ -1099,7 +1084,6 @@ VAStatus vaDeassociateSubpicture ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaDeassociateSubpicture); return ctx->vtable.vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces ); } @@ -1131,7 +1115,6 @@ VAStatus vaQueryDisplayAttributes ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaQueryDisplayAttributes); return ctx->vtable.vaQueryDisplayAttributes ( ctx, attr_list, num_attributes ); } @@ -1151,7 +1134,6 @@ VAStatus vaGetDisplayAttributes ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaGetDisplayAttributes); return ctx->vtable.vaGetDisplayAttributes ( ctx, attr_list, num_attributes ); } @@ -1171,75 +1153,10 @@ VAStatus vaSetDisplayAttributes ( CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaSetDisplayAttributes); return ctx->vtable.vaSetDisplayAttributes ( ctx, attr_list, num_attributes ); } -/* Wrap a CI (camera imaging) frame as a VA surface to share captured video between camear - * and VA encode. With frame_id, VA driver need to call CI interfaces to get the information - * of the frame, and to determine if the frame can be wrapped as a VA surface - * - * Application should make sure the frame is idle before the frame is passed into VA stack - * and also a vaSyncSurface should be called before application tries to access the frame - * from CI stack - */ -VAStatus vaCreateSurfaceFromCIFrame ( - VADisplay dpy, - unsigned long frame_id, - VASurfaceID *surface /* out */ -) -{ - VADriverContextP ctx; - CHECK_DISPLAY(dpy); - ctx = CTX(dpy); - - TRACE(vaCreateSurfacesFromCIFrame); - - if (ctx->vtable.vaCreateSurfaceFromCIFrame) - return ctx->vtable.vaCreateSurfaceFromCIFrame( ctx, frame_id, surface ); - else - return VA_STATUS_ERROR_UNKNOWN; -} - - -/* Wrap a V4L2 buffer as a VA surface, so that V4L2 camera, VA encode - * can share the data without copy - * The VA driver should query the camera device from v4l2_fd to see - * if camera device memory/buffer can be wrapped into a VA surface - * Buffer information is passed in by v4l2_fmt and v4l2_buf structure, - * VA driver also needs do further check if the buffer can meet encode - * hardware requirement, such as dimension, fourcc, stride, etc - * - * Application should make sure the buffer is idle before the frame into VA stack - * and also a vaSyncSurface should be called before application tries to access the frame - * from V4L2 stack - */ -VAStatus vaCreateSurfaceFromV4L2Buf( - VADisplay dpy, - int v4l2_fd, /* file descriptor of V4L2 device */ - struct v4l2_format *v4l2_fmt, /* format of V4L2 */ - struct v4l2_buffer *v4l2_buf, /* V4L2 buffer */ - VASurfaceID *surface /* out */ -) -{ - VADriverContextP ctx; - CHECK_DISPLAY(dpy); - ctx = CTX(dpy); - - TRACE(vtable.vaCreateSurfaceFromV4L2Buf); - - if (ctx->vtable.vaCreateSurfaceFromV4L2Buf) - return ctx->vtable.vaCreateSurfaceFromV4L2Buf( ctx, v4l2_fd, v4l2_fmt, v4l2_buf, surface ); - else - return VA_STATUS_ERROR_UNKNOWN; -} - -/* It is a debug interface, and isn't exported in core VAAPI - * It is used to dump surface data into system memory - * Application should explicitly call free to release the buffer memory - */ - -VAStatus vaCopySurfaceToBuffer(VADisplay dpy, +VAStatus vaLockSurface(VADisplay dpy, VASurfaceID surface, unsigned int *fourcc, /* following are output argument */ unsigned int *luma_stride, @@ -1248,6 +1165,7 @@ VAStatus vaCopySurfaceToBuffer(VADisplay dpy, unsigned int *luma_offset, unsigned int *chroma_u_offset, unsigned int *chroma_v_offset, + unsigned int *buffer_name, void **buffer ) { @@ -1255,9 +1173,17 @@ VAStatus vaCopySurfaceToBuffer(VADisplay dpy, CHECK_DISPLAY(dpy); ctx = CTX(dpy); - TRACE(vaCopySurfaceToBuffer); - if (ctx->vtable.vaCopySurfaceToBuffer) - return ctx->vtable.vaCopySurfaceToBuffer( ctx, surface, fourcc, luma_stride, chroma_u_stride, chroma_v_stride, luma_offset, chroma_u_offset, chroma_v_offset, buffer); - else - return VA_STATUS_ERROR_UNKNOWN; + return ctx->vtable.vaLockSurface( ctx, surface, fourcc, luma_stride, chroma_u_stride, chroma_v_stride, luma_offset, chroma_u_offset, chroma_v_offset, buffer_name, buffer); +} + + +VAStatus vaUnlockSurface(VADisplay dpy, + VASurfaceID surface +) +{ + VADriverContextP ctx; + CHECK_DISPLAY(dpy); + ctx = CTX(dpy); + + return ctx->vtable.vaUnlockSurface( ctx, surface ); } @@ -56,6 +56,8 @@ * rev 0.31 (09/02/2009 Gwenole Beauchesne) - VC-1/H264 fields change for VDPAU and XvBA backend * Application needs to relink with the new library. * + * rev 0.31.1 (03/29/2009) - Data structure for JPEG encode + * * Acknowledgements: * Some concepts borrowed from XvMC and XvImage. * Waldo Bastian (Intel), Matt Sottek (Intel), Austin Yuan (Intel), and Gwenole Beauchesne (SDS) @@ -157,6 +159,8 @@ const char *vaErrorStr(VAStatus error_status); */ typedef void* NativeDisplay; /* window system dependent */ +int vaDisplayIsValid(VADisplay dpy); + /* * Initialize the library */ @@ -210,7 +214,8 @@ typedef enum VAProfileVC1Simple = 8, VAProfileVC1Main = 9, VAProfileVC1Advanced = 10, - VAProfileH263Baseline = 11 + VAProfileH263Baseline = 11, + VAProfileJPEGBaseline = 12 } VAProfile; /* @@ -223,7 +228,8 @@ typedef enum VAEntrypointIDCT = 3, VAEntrypointMoComp = 4, VAEntrypointDeblocking = 5, - VAEntrypointEncSlice = 6 /* slice level encode */ + VAEntrypointEncSlice = 6, /* slice level encode */ + VAEntrypointEncPicture = 7 /* pictuer encode, JPEG, etc */ } VAEntrypoint; /* Currently defined configuration attribute types */ @@ -407,20 +413,6 @@ VAStatus vaCreateSurfaces ( VASurfaceID *surfaces /* out */ ); -/* Wrap a CI (camera imaging) frame as a VA surface to share captured video between camear - * and VA encode. With frame_id, VA driver need to call CI interfaces to get the information - * of the frame, and to determine if the frame can be wrapped as a VA surface - * - * Application should make sure the frame is idle before the frame is passed into VA stack - * and also a vaSyncSurface should be called before application tries to access the frame - * from CI stack - */ -VAStatus vaCreateSurfaceFromCIFrame ( - VADisplay dpy, - unsigned long frame_id, - VASurfaceID *surface /* out */ -); - /* * vaDestroySurfaces - Destroy resources associated with surfaces. @@ -493,6 +485,7 @@ typedef enum VADeblockingParameterBufferType = 8, VAImageBufferType = 9, VAProtectedSliceDataBufferType = 10, + VAQMatrixBufferType = 11, /* Following are encode buffer types */ VAEncCodedBufferType = 21, VAEncSequenceParameterBufferType = 22, @@ -524,6 +517,27 @@ typedef struct _VASliceParameterBufferBase unsigned int slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX definitions */ } VASliceParameterBufferBase; + +/**************************** + * JEPG data structure + ***************************/ +typedef struct _VAQMatrixBufferJPEG +{ + int load_lum_quantiser_matrix; + int load_chroma_quantiser_matrix; + unsigned char lum_quantiser_matrix[64]; + unsigned char chroma_quantiser_matrix[64]; +} VAQMatrixBufferJPEG; + +typedef struct _VAEncPictureParameterBufferJPEG +{ + VASurfaceID reconstructed_picture; + unsigned short picture_width; + unsigned short picture_height; + VABufferID coded_buf; +} VAEncPictureParameterBufferJPEG; + + /**************************** * MPEG-2 data structures ****************************/ @@ -1081,6 +1095,7 @@ typedef struct _VAEncSequenceParameterBufferH264 unsigned char seq_parameter_set_id; unsigned char level_idc; unsigned int intra_period; + unsigned int intra_idr_period; unsigned int picture_width_in_mbs; unsigned int picture_height_in_mbs; unsigned int bits_per_second; @@ -1195,10 +1210,24 @@ VAStatus vaBufferSetNumElements ( unsigned int num_elements /* in */ ); + +/* + * device independent data structure for codedbuffer + */ +typedef struct _VACodedBufferSegment { + unsigned int size; /* size of the data buffer in the coded buffer segment, in bytes */ + unsigned int bit_offset;/* bit offset into the data buffer where valid bitstream data begins */ + void *buf; /* pointer to the beginning of the data buffer in the coded buffer segment */ + void *next; /* pointer to the next VACodedBufferSegment */ +} VACodedBufferSegment; + /* * Map data store of the buffer into the client's address space * vaCreateBuffer() needs to be called with "data" set to NULL before * calling vaMapBuffer() + * + * if buffer type is VAEncCodedBufferType, pbuf points to link-list of + * VACodedBufferSegment, and the list is terminated if "next" is NULL */ VAStatus vaMapBuffer ( VADisplay dpy, @@ -1645,6 +1674,35 @@ typedef struct _VARectangle * attributes are supported by the driver, and then set the appropriate attributes * before calling vaPutSurface() */ +/* PowerVR IEP Lite attributes */ +typedef enum +{ + VADISPLAYATTRIB_BLE_OFF = 0x00, + VADISPLAYATTRIB_BLE_LOW, + VADISPLAYATTRIB_BLE_MEDIUM, + VADISPLAYATTRIB_BLE_HIGH, + VADISPLAYATTRIB_BLE_NONE, +} VADisplayAttribBLEMode; + +typedef enum +{ + VADISPLAYATTRIB_CSC_FORMAT_YCC_BT601 = 0x00, + VADISPLAYATTRIB_CSC_FORMAT_YCC_BT709, + VADISPLAYATTRIB_CSC_FORMAT_YCC_SMPTE_240, + VADISPLAYATTRIB_CSC_FORMAT_RGB, + VADISPLAYATTRIB_CSC_FORMAT_NONE, +} VADisplayAttribCSCFormat; + +/* attribute value for VADisplayAttribRotation */ +#define VA_ROTATION_NONE 0x00000000 +#define VA_ROTATION_90 0x00000001 +#define VA_ROTATION_180 0x00000002 +#define VA_ROTATION_270 0x00000004 + +/* attribute value for VADisplayAttribOutOfLoopDeblock */ +#define VA_OOL_DEBLOCKING_FALSE 0x00000000 +#define VA_OOL_DEBLOCKING_TRUE 0x00000001 + /* Currently defined display attribute types */ typedef enum @@ -1664,6 +1722,19 @@ typedef enum * to PutSurface. */ VADisplayAttribDirectSurface = 5, + VADisplayAttribRotation = 6, + VADisplayAttribOutofLoopDeblock = 7, + + /* PowerVR IEP Lite specific attributes */ + VADisplayAttribBLEBlackMode = 8, + VADisplayAttribBLEWhiteMode = 9, + VADisplayAttribBlueStretch = 10, + VADisplayAttribSkinColorCorrection = 11, + VADisplayAttribCSCInputColorFormat = 12, + VADisplayAttribCSCHue = 13, + VADisplayAttribCSCSaturation = 14, + VADisplayAttribCSCBrightness = 15, + VADisplayAttribCSCContrast = 16, } VADisplayAttribType; /* flags for VADisplayAttribute */ diff --git a/va/va_android.h b/va/va_android.h new file mode 100644 index 0000000..08844f4 --- /dev/null +++ b/va/va_android.h @@ -0,0 +1,54 @@ +#ifndef _VA_ANDROID_H_ +#define _VA_ANDROID_H_ + +#include <va/va.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Returns a suitable VADisplay for VA API + */ +VADisplay vaGetDisplay ( + void *android_dpy +); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +#ifdef ANDROID +#include <ui/ISurface.h> +using namespace android; + +/* + * Output rendering + * Following is the rendering interface for Android system, + * to get the decode output surface to an ISurface object. + * It basically performs a de-interlacing (if needed), + * color space conversion and scaling to the destination + * rectangle + */ +VAStatus vaPutSurface ( + VADisplay dpy, + VASurfaceID surface, + sp<ISurface> draw, /* Android Window/Surface */ + short srcx, + short srcy, + unsigned short srcw, + unsigned short srch, + short destx, + short desty, + unsigned short destw, + unsigned short desth, + VARectangle *cliprects, /* client supplied destination clip list */ + unsigned int number_cliprects, /* number of clip rects in the clip list */ + unsigned int flags /* PutSurface flags */ +); + +#endif /* ANDROID */ +#endif /* __cplusplus */ + +#endif /* _VA_ANDROID_H_ */ diff --git a/va/va_backend.h b/va/va_backend.h index ff86744..62ac970 100644 --- a/va/va_backend.h +++ b/va/va_backend.h @@ -30,10 +30,11 @@ #define _VA_BACKEND_H_ #include <va/va.h> +#ifndef ANDROID #include <X11/Xlib.h> +#endif #include <linux/videodev2.h> - typedef struct VADriverContext *VADriverContextP; typedef struct VADisplayContext *VADisplayContextP; @@ -180,7 +181,7 @@ struct VADriverVTable VAStatus (*vaPutSurface) ( VADriverContextP ctx, VASurfaceID surface, - Drawable draw, /* X Drawable */ + void* draw, /* Drawable of window system */ short srcx, short srcy, unsigned short srcw, @@ -337,23 +338,18 @@ struct VADriverVTable int num_attributes ); - /* device specific */ - VAStatus (*vaCreateSurfaceFromCIFrame) ( - VADriverContextP ctx, - unsigned long frame_id, - VASurfaceID *surface /* out */ - ); - - - VAStatus (*vaCreateSurfaceFromV4L2Buf) ( - VADriverContextP ctx, - int v4l2_fd, /* file descriptor of V4L2 device */ - struct v4l2_format *v4l2_fmt, /* format of V4L2 */ - struct v4l2_buffer *v4l2_buf, /* V4L2 buffer */ - VASurfaceID *surface /* out */ + /* used by va trace */ + VAStatus (*vaBufferInfo) ( + VADriverContextP ctx, + VAContextID context, /* in */ + VABufferID buf_id, /* in */ + VABufferType *type, /* out */ + unsigned int *size, /* out */ + unsigned int *num_elements /* out */ ); - - VAStatus (*vaCopySurfaceToBuffer) ( + + /* lock/unlock surface for external access */ + VAStatus (*vaLockSurface) ( VADriverContextP ctx, VASurfaceID surface, unsigned int *fourcc, /* out for follow argument */ @@ -363,16 +359,30 @@ struct VADriverVTable unsigned int *luma_offset, unsigned int *chroma_u_offset, unsigned int *chroma_v_offset, - void **buffer + unsigned int *buffer_name, /* if it is not NULL, assign the low lever + * surface buffer name + */ + void **buffer /* if it is not NULL, map the surface buffer for + * CPU access + */ + ); + + VAStatus (*vaUnlockSurface) ( + VADriverContextP ctx, + VASurfaceID surface ); + + /* Optional: GLX support hooks */ + struct VADriverVTableGLX *glx; }; struct VADriverContext { void *pDriverData; struct VADriverVTable vtable; + void *vtable_tpi; /* the structure is malloc-ed */ - Display *x11_dpy; + void *native_dpy; int x11_screen; int version_major; int version_minor; @@ -387,6 +397,7 @@ struct VADriverContext void *handle; /* dlopen handle */ void *dri_state; + void *glx; /* opaque for GLX code */ }; #define VA_DISPLAY_MAGIC 0x56414430 /* VAD0 */ @@ -409,11 +420,12 @@ struct VADisplayContext VADisplayContextP ctx, char **driver_name ); + + void *opaque; /* opaque for display extensions (e.g. GLX) */ }; typedef VAStatus (*VADriverInit) ( VADriverContextP driver_context ); - #endif /* _VA_BACKEND_H_ */ diff --git a/va/va_backend_tpi.h b/va/va_backend_tpi.h new file mode 100644 index 0000000..2f40e5a --- /dev/null +++ b/va/va_backend_tpi.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2007 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. + */ + +/* + * Video Decode Acceleration -Backend API + */ + +#ifndef _VA_BACKEND_TPI_H_ +#define _VA_BACKEND_TPI_H_ + +#include <va/va.h> +#include <va/va_backend.h> + +#include <linux/videodev2.h> + +struct VADriverVTableTPI +{ + /* device specific */ + VAStatus (*vaCreateSurfaceFromCIFrame) ( + VADriverContextP ctx, + unsigned long frame_id, + VASurfaceID *surface /* out */ + ); + + VAStatus (*vaCreateSurfaceFromV4L2Buf) ( + VADriverContextP ctx, + int v4l2_fd, /* file descriptor of V4L2 device */ + struct v4l2_format *v4l2_fmt, /* format of V4L2 */ + struct v4l2_buffer *v4l2_buf, /* V4L2 buffer */ + VASurfaceID *surface /* out */ + ); + + VAStatus (*vaPutSurfaceBuf) ( + VADisplay dpy, + VASurfaceID surface, + unsigned char* data, + int* data_len, + short srcx, + short srcy, + unsigned short srcw, + unsigned short srch, + short destx, + short desty, + unsigned short destw, + unsigned short desth, + VARectangle *cliprects, /* client supplied clip list */ + unsigned int number_cliprects, /* number of clip rects in the clip list */ + unsigned int flags /* de-interlacing flags */ + ); +}; + + +#endif /* _VA_BACKEND_TPI_H_ */ diff --git a/va/va_dummy.h b/va/va_dummy.h new file mode 120000 index 0000000..69128f8 --- /dev/null +++ b/va/va_dummy.h @@ -0,0 +1 @@ +va_android.h
\ No newline at end of file diff --git a/va/va_tpi.c b/va/va_tpi.c new file mode 100644 index 0000000..1f01ef0 --- /dev/null +++ b/va/va_tpi.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2007 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. + */ + +#define _GNU_SOURCE 1 +#include "va.h" +#include "va_backend.h" +#include "va_backend_tpi.h" +#include "config.h" + +#include <assert.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dlfcn.h> +#include <unistd.h> + +#define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext) +#define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; } + +/* Wrap a CI (camera imaging) frame as a VA surface to share captured video between camear + * and VA encode. With frame_id, VA driver need to call CI interfaces to get the information + * of the frame, and to determine if the frame can be wrapped as a VA surface + * + * Application should make sure the frame is idle before the frame is passed into VA stack + * and also a vaSyncSurface should be called before application tries to access the frame + * from CI stack + */ +VAStatus vaCreateSurfaceFromCIFrame ( + VADisplay dpy, + unsigned long frame_id, + VASurfaceID *surface /* out */ +) +{ + VADriverContextP ctx; + struct VADriverVTableTPI *tpi; + CHECK_DISPLAY(dpy); + ctx = CTX(dpy); + + tpi = ( struct VADriverVTableTPI *)ctx->vtable_tpi; + if (tpi && tpi->vaCreateSurfaceFromCIFrame) { + return tpi->vaCreateSurfaceFromCIFrame( ctx, frame_id, surface ); + } else + return VA_STATUS_ERROR_UNIMPLEMENTED; + +} + +/* Wrap a V4L2 buffer as a VA surface, so that V4L2 camera, VA encode + * can share the data without copy + * The VA driver should query the camera device from v4l2_fd to see + * if camera device memory/buffer can be wrapped into a VA surface + * Buffer information is passed in by v4l2_fmt and v4l2_buf structure, + * VA driver also needs do further check if the buffer can meet encode + * hardware requirement, such as dimension, fourcc, stride, etc + * + * Application should make sure the buffer is idle before the frame into VA stack + * and also a vaSyncSurface should be called before application tries to access the frame + * from V4L2 stack + */ +VAStatus vaCreateSurfaceFromV4L2Buf( + VADisplay dpy, + int v4l2_fd, /* file descriptor of V4L2 device */ + struct v4l2_format *v4l2_fmt, /* format of V4L2 */ + struct v4l2_buffer *v4l2_buf, /* V4L2 buffer */ + VASurfaceID *surface /* out */ +) +{ + VADriverContextP ctx; + struct VADriverVTableTPI *tpi; + CHECK_DISPLAY(dpy); + ctx = CTX(dpy); + + tpi = ( struct VADriverVTableTPI *)ctx->vtable_tpi; + if (tpi && tpi->vaCreateSurfaceFromV4L2Buf) { + return tpi->vaCreateSurfaceFromV4L2Buf( ctx, v4l2_fd, v4l2_fmt, v4l2_buf, surface ); + } else + return VA_STATUS_ERROR_UNIMPLEMENTED; +} + +VAStatus vaPutSurfaceBuf ( + VADisplay dpy, + VASurfaceID surface, + unsigned char* data, + int* data_len, + short srcx, + short srcy, + unsigned short srcw, + unsigned short srch, + short destx, + short desty, + unsigned short destw, + unsigned short desth, + VARectangle *cliprects, /* client supplied clip list */ + unsigned int number_cliprects, /* number of clip rects in the clip list */ + unsigned int flags /* de-interlacing flags */ +) +{ + VADriverContextP ctx; + struct VADriverVTableTPI *tpi; + CHECK_DISPLAY(dpy); + ctx = CTX(dpy); + + tpi = ( struct VADriverVTableTPI *)ctx->vtable_tpi; + if (tpi && tpi->vaPutSurfaceBuf) { + return tpi->vaPutSurfaceBuf( ctx, surface, data, data_len, srcx, srcy, srcw, srch, + destx, desty, destw, desth, cliprects, number_cliprects, flags ); + } else + return VA_STATUS_ERROR_UNIMPLEMENTED; +} diff --git a/va/va_tpi.h b/va/va_tpi.h new file mode 100644 index 0000000..1fe4b8d --- /dev/null +++ b/va/va_tpi.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2007-2009 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 INTEL 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. + */ + +/* Wrap a CI (camera imaging) frame as a VA surface to share captured video between camear + * and VA encode. With frame_id, VA driver need to call CI interfaces to get the information + * of the frame, and to determine if the frame can be wrapped as a VA surface + * + * Application should make sure the frame is idle before the frame is passed into VA stack + * and also a vaSyncSurface should be called before application tries to access the frame + * from CI stack + */ +#include <va/va.h> + +#ifdef __cplusplus +extern "C" { +#endif + +VAStatus vaCreateSurfaceFromCIFrame ( + VADisplay dpy, + unsigned long frame_id, + VASurfaceID *surface /* out */ +); + +VAStatus vaCreateSurfaceFromV4L2Buf( + VADisplay dpy, + int v4l2_fd, /* file descriptor of V4L2 device */ + struct v4l2_format *v4l2_fmt, /* format of V4L2 */ + struct v4l2_buffer *v4l2_buf, /* V4L2 buffer */ + VASurfaceID *surface /* out */ +); + +VAStatus vaPutSurfaceBuf ( + VADisplay dpy, + VASurfaceID surface, + unsigned char* data, + int* data_len, + short srcx, + short srcy, + unsigned short srcw, + unsigned short srch, + short destx, + short desty, + unsigned short destw, + unsigned short desth, + VARectangle *cliprects, /* client supplied clip list */ + unsigned int number_cliprects, /* number of clip rects in the clip list */ + unsigned int flags /* de-interlacing flags */ +); + +#ifdef __cplusplus +} +#endif diff --git a/va/va_trace.c b/va/va_trace.c new file mode 100644 index 0000000..1713f27 --- /dev/null +++ b/va/va_trace.c @@ -0,0 +1,1115 @@ +/* + * Copyright (c) 2009 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. + */ + +#define _GNU_SOURCE 1 +#include "va.h" +#include "va_backend.h" + +#include <assert.h> +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <dlfcn.h> +#include <unistd.h> + +unsigned int trace_flag = 0; + +static const char *trace_file = 0; +static FILE *trace_fp = 0; + +static VASurfaceID trace_rendertarget; /* current render target */ +static VAProfile trace_profile; /* current entrypoint for buffers */ + +static unsigned int trace_frame; +static unsigned int trace_slice; + +static unsigned int trace_width; +static unsigned int trace_height; + +int va_TraceInit(void) +{ + trace_file = (const char *)getenv("LIBVA_TRACE"); + if (trace_file) { + trace_fp = fopen(trace_file, "w"); + if (trace_fp) + trace_flag = 1; + } +} + +int va_TraceEnd(void) +{ + if (trace_file && trace_fp) { + fclose(trace_fp); + + trace_file = NULL; + trace_fp = NULL; + + trace_flag = 0; + + trace_width = 0; + trace_height = 0; + } +} + +int va_TraceMsg(const char *msg, ...) +{ + va_list args; + + if (msg) { + va_start(args, msg); + vfprintf(trace_fp, msg, args); + va_end(args); + } else { + fflush(trace_fp); + } +} + + +int va_TraceCreateConfig( + VADisplay dpy, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, + int num_attribs, + VAConfigID *config_id /* out */ + ) +{ + int i; + + va_TraceMsg("\tprofile = %d\n", profile); + va_TraceMsg("\tentrypoint = %d\n", entrypoint); + va_TraceMsg("\tnum_attribs = %d\n", num_attribs); + for (i = 0; i < num_attribs; i++) { + va_TraceMsg("\t\tattrib_list[%d].type = 0x%08x\n", i, attrib_list[i].type); + va_TraceMsg("\t\tattrib_list[%d].value = 0x%08x\n", i, attrib_list[i].value); + } + + trace_profile = profile; +} + + +int va_TraceCreateSurface( + VADisplay dpy, + int width, + int height, + int format, + int num_surfaces, + VASurfaceID *surfaces /* out */ + ) +{ + int i; + + va_TraceMsg("\twidth = %d\n", width); + va_TraceMsg("\theight = %d\n", height); + va_TraceMsg("\tformat = %d\n", format); + va_TraceMsg("\tnum_surfaces = %d\n", num_surfaces); + + for (i = 0; i < num_surfaces; i++) + va_TraceMsg("\t\tsurfaces[%d] = 0x%08x\n", i, surfaces[i]); +} + + +int va_TraceCreateContext( + VADisplay dpy, + VAConfigID config_id, + int picture_width, + int picture_height, + int flag, + VASurfaceID *render_targets, + int num_render_targets, + VAContextID *context /* out */ + ) +{ + int i; + + va_TraceMsg("\twidth = %d\n", picture_width); + va_TraceMsg("\theight = %d\n", picture_height); + va_TraceMsg("\tflag = 0x%08x\n", flag); + va_TraceMsg("\tnum_render_targets = %d\n", num_render_targets); + for (i=0; i<num_render_targets; i++) + va_TraceMsg("\t\trender_targets[%d] = 0x%08x\n", i, render_targets[i]); + va_TraceMsg("\tcontext = 0x%08x\n", context); + + + trace_frame = 0; + trace_slice = 0; + + trace_width = picture_width; + trace_height = picture_height; +} + + +static char * buffer_type_to_string(int type) +{ + switch (type) { + case VAPictureParameterBufferType: return "VAPictureParameterBufferType"; + case VAIQMatrixBufferType: return "VAIQMatrixBufferType"; + case VABitPlaneBufferType: return "VABitPlaneBufferType"; + case VASliceGroupMapBufferType: return "VASliceGroupMapBufferType"; + case VASliceParameterBufferType: return "VASliceParameterBufferType"; + case VASliceDataBufferType: return "VASliceDataBufferType"; + case VAProtectedSliceDataBufferType: return "VAProtectedSliceDataBufferType"; + case VAMacroblockParameterBufferType: return "VAMacroblockParameterBufferType"; + case VAResidualDataBufferType: return "VAResidualDataBufferType"; + case VADeblockingParameterBufferType: return "VADeblockingParameterBufferType"; + case VAImageBufferType: return "VAImageBufferType"; + case VAEncCodedBufferType: return "VAEncCodedBufferType"; + case VAEncSequenceParameterBufferType: return "VAEncSequenceParameterBufferType"; + case VAEncPictureParameterBufferType: return "VAEncPictureParameterBufferType"; + case VAEncSliceParameterBufferType: return "VAEncSliceParameterBufferType"; + default: return "UnknowBuffer"; + } +} + + +static int va_TraceVABuffers( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *pbuf + ) +{ + int i; + unsigned char *p = pbuf; + unsigned int *pi = (unsigned int *)pbuf; + + va_TraceMsg("***Buffer Data***"); + for (i=0; i<size; i++) { + if ((i%16) == 0) + va_TraceMsg("\n0x%08x:", i); + va_TraceMsg(" %02x", p[i]); + } + + va_TraceMsg("\n"); + return 0; +} + + +static void va_TraceVAPictureParameterBufferMPEG2( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data) +{ + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, data); + + return; +} + + +static void va_TraceVAIQMatrixBufferMPEG2( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data) +{ + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, data); + + return; +} + + +static void va_TraceVASliceParameterBufferMPEG2( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data) +{ + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, data); + + return; +} + + + +static void va_TraceVAPictureParameterBufferMPEG4( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data) +{ + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, data); + + return; +} + + +static void va_TraceVAIQMatrixBufferMPEG4( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data) +{ + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, data); + + return; +} + + +static void va_TraceVASliceParameterBufferMPEG4( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data) +{ + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, data); + + return; +} + + +static void va_TraceVAPictureParameterBufferH264( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data) +{ + int i; + + VAPictureParameterBufferH264 *p = (VAPictureParameterBufferH264*)data; + + va_TraceMsg ("==========H264PicParameterBuffer============\n"); + +#if 0 + if (p->num_ref_frames > 4) + { + int num = 0; + for (i = 15; i >= 0; i--) + { + if (p->ReferenceFrames[i].flags != VA_PICTURE_H264_INVALID) + { + num++; + } + if (num > 4) + { + p->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID; + } + } + p->num_ref_frames = 4; + } +#endif + +#if 1 + va_TraceMsg("picture id: %d\n", p->CurrPic.picture_id); + va_TraceMsg("frame idx: %d\n", p->CurrPic.frame_idx); + va_TraceMsg("picture flags: %d\n", p->CurrPic.flags); + va_TraceMsg("top field order count: %d\n", p->CurrPic.TopFieldOrderCnt); + va_TraceMsg("bottom field order count: %d\n", p->CurrPic.BottomFieldOrderCnt); + + + va_TraceMsg("Reference frames: \n"); + for (i = 0; i < 16; i++) + { + if (p->ReferenceFrames[i].flags != VA_PICTURE_H264_INVALID) + { + //va_TraceMsg("%d-%d; ", p->ReferenceFrames[i].TopFieldOrderCnt, p->ReferenceFrames[i].BottomFieldOrderCnt); + va_TraceMsg("%d-%d-%d-%d; ", p->ReferenceFrames[i].TopFieldOrderCnt, p->ReferenceFrames[i].BottomFieldOrderCnt, p->ReferenceFrames[i].picture_id, p->ReferenceFrames[i].frame_idx); + } + } + va_TraceMsg("\n"); +#endif + va_TraceMsg("picture_width_in_mbs_minus1: %d\n", p->picture_width_in_mbs_minus1); + va_TraceMsg("picture_height_in_mbs_minus1: %d\n", p->picture_height_in_mbs_minus1); + va_TraceMsg("bit_depth_luma_minus8: %d\n", p->bit_depth_luma_minus8); + va_TraceMsg("bit_depth_chroma_minus8: %d\n", p->bit_depth_chroma_minus8); + va_TraceMsg("num_ref_frames: %d\n", p->num_ref_frames); + va_TraceMsg("seq fields: %d\n", p->seq_fields.value); + va_TraceMsg("\t chroma_format_idc: %d\n", p->seq_fields.bits.chroma_format_idc); + va_TraceMsg("\t residual_colour_transform_flag: %d\n", p->seq_fields.bits.residual_colour_transform_flag); + va_TraceMsg("\t frame_mbs_only_flag: %d\n", p->seq_fields.bits.frame_mbs_only_flag); + va_TraceMsg("\t mb_adaptive_frame_field_flag: %d\n", p->seq_fields.bits.mb_adaptive_frame_field_flag); + va_TraceMsg("\t direct_8x8_inference_flag: %d\n", p->seq_fields.bits.direct_8x8_inference_flag); + va_TraceMsg("\t MinLumaBiPredSize8x8: %d\n", p->seq_fields.bits.MinLumaBiPredSize8x8); + va_TraceMsg("num_slice_groups_minus1: %d\n", p->num_slice_groups_minus1); + va_TraceMsg("slice_group_map_type: %d\n", p->slice_group_map_type); + va_TraceMsg("slice_group_change_rate_minus1: %d\n", p->slice_group_change_rate_minus1); + va_TraceMsg("pic_init_qp_minus26: %d\n", p->pic_init_qp_minus26); + va_TraceMsg("pic_init_qs_minus26: %d\n", p->pic_init_qs_minus26); + va_TraceMsg("chroma_qp_index_offset: %d\n", p->chroma_qp_index_offset); + va_TraceMsg("second_chroma_qp_index_offset: %d\n", p->second_chroma_qp_index_offset); + va_TraceMsg("pic_fields: %d\n", p->pic_fields.value); + va_TraceMsg("\t entropy_coding_mode_flag: %d\n", p->pic_fields.bits.entropy_coding_mode_flag); + va_TraceMsg("\t weighted_pred_flag: %d\n", p->pic_fields.bits.weighted_pred_flag); + va_TraceMsg("\t weighted_bipred_idc: %d\n", p->pic_fields.bits.weighted_bipred_idc); + va_TraceMsg("\t transform_8x8_mode_flag: %d\n", p->pic_fields.bits.transform_8x8_mode_flag); + va_TraceMsg("\t field_pic_flag: %d\n", p->pic_fields.bits.field_pic_flag); + va_TraceMsg("\t constrained_intra_pred_flag: %d\n", p->pic_fields.bits.constrained_intra_pred_flag); + va_TraceMsg("frame_num: %d\n", p->frame_num); + + return; +} + +static void va_TraceVASliceParameterBufferH264( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data) +{ + int i; + VASliceParameterBufferH264* p = (VASliceParameterBufferH264*)data; + + va_TraceMsg ("========== SLICE HEADER ============.\n"); + va_TraceMsg("slice_data_size: %d\n", p->slice_data_size); + va_TraceMsg("slice_data_offset: %d\n", p->slice_data_offset); + va_TraceMsg("slice_data_flag: %d\n", p->slice_data_flag); + va_TraceMsg("slice_data_bit_offset: %d\n", p->slice_data_bit_offset); + va_TraceMsg("first_mb_in_slice: %d\n", p->first_mb_in_slice); + va_TraceMsg("slice_type: %d\n", p->slice_type); + va_TraceMsg("direct_spatial_mv_pred_flag: %d\n", p->direct_spatial_mv_pred_flag); + va_TraceMsg("num_ref_idx_l0_active_minus1: %d\n", p->num_ref_idx_l0_active_minus1); + va_TraceMsg("num_ref_idx_l1_active_minus1: %d\n", p->num_ref_idx_l1_active_minus1); + va_TraceMsg("cabac_init_idc: %d\n", p->cabac_init_idc); + va_TraceMsg("slice_qp_delta: %d\n", p->slice_qp_delta); + va_TraceMsg("disable_deblocking_filter_idc: %d\n", p->disable_deblocking_filter_idc); + va_TraceMsg("slice_alpha_c0_offset_div2: %d\n", p->slice_alpha_c0_offset_div2); + va_TraceMsg("slice_beta_offset_div2: %d\n", p->slice_beta_offset_div2); + +#if 1 + if (p->slice_type == 0 || p->slice_type == 1) + { + va_TraceMsg("RefPicList0:\n"); + for (i = 0; i < p->num_ref_idx_l0_active_minus1 + 1; i++) + { + //va_TraceMsg("%d-%d; ", p->RefPicList0[i].TopFieldOrderCnt, p->RefPicList0[i].BottomFieldOrderCnt); + va_TraceMsg("%d-%d-%d-%d; ", p->RefPicList0[i].TopFieldOrderCnt, p->RefPicList0[i].BottomFieldOrderCnt, p->RefPicList0[i].picture_id, p->RefPicList0[i].frame_idx); + } + va_TraceMsg("\n"); + if (p->slice_type == 1) + { + va_TraceMsg("RefPicList1:\n"); + for (i = 0; i < p->num_ref_idx_l1_active_minus1 + 1; i++) + { + //va_TraceMsg("%d-%d; ", p->RefPicList1[i].TopFieldOrderCnt, p->RefPicList1[i].BottomFieldOrderCnt); + va_TraceMsg("%d-%d-%d-%d; ", p->RefPicList1[i].TopFieldOrderCnt, p->RefPicList1[i].BottomFieldOrderCnt, p->RefPicList1[i].picture_id, p->RefPicList1[i].frame_idx); + } + } + va_TraceMsg("\n"); + } +#endif + + va_TraceMsg("luma_log2_weight_denom: %d\n", p->luma_log2_weight_denom); + va_TraceMsg("chroma_log2_weight_denom: %d\n", p->chroma_log2_weight_denom); + va_TraceMsg("luma_weight_l0_flag: %d\n", p->luma_weight_l0_flag); + if (p->luma_weight_l0_flag) + { + for (i = 0; i <= p->num_ref_idx_l0_active_minus1; i++) + { + va_TraceMsg("%d ", p->luma_weight_l0[i]); + va_TraceMsg("%d ", p->luma_offset_l0[i]); + } + va_TraceMsg("\n"); + } + + + va_TraceMsg("chroma_weight_l0_flag: %d\n", p->chroma_weight_l0_flag); + if (p->chroma_weight_l0_flag) + { + for (i = 0; i <= p->num_ref_idx_l0_active_minus1; i++) + { + va_TraceMsg("%d ", p->chroma_weight_l0[i][0]); + va_TraceMsg("%d ", p->chroma_offset_l0[i][0]); + va_TraceMsg("%d ", p->chroma_weight_l0[i][1]); + va_TraceMsg("%d ", p->chroma_offset_l0[i][1]); + } + va_TraceMsg("\n"); + } + va_TraceMsg("luma_weight_l1_flag: %d\n", p->luma_weight_l1_flag); + if (p->luma_weight_l1_flag) + { + for (i = 0; i <= p->num_ref_idx_l1_active_minus1; i++) + { + va_TraceMsg("%d ", p->luma_weight_l1[i]); + va_TraceMsg("%d ", p->luma_offset_l1[i]); + } + va_TraceMsg("\n"); + } + va_TraceMsg("chroma_weight_l1_flag: %d\n", p->chroma_weight_l1_flag); + if (p->chroma_weight_l1_flag) + { + for (i = 0; i <= p->num_ref_idx_l1_active_minus1; i++) + { + va_TraceMsg("%d ", p->chroma_weight_l1[i][0]); + va_TraceMsg("%d ", p->chroma_offset_l1[i][0]); + va_TraceMsg("%d ", p->chroma_weight_l1[i][1]); + va_TraceMsg("%d ", p->chroma_offset_l1[i][1]); + } + va_TraceMsg("\n"); + } +} + +static void va_TraceVAIQMatrixBufferH264( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data +) +{ + va_TraceMsg("========== IQMatrix ============.\n"); + VAIQMatrixBufferH264* p = (VAIQMatrixBufferH264* )data; + int i, j; + for (i = 0; i < 6; i++) + { + for (j = 0; j < 16; j++) + { + va_TraceMsg("%d\t", p->ScalingList4x4[i][j]); + if ((j + 1) % 8 == 0) + va_TraceMsg("\n"); + } + } + + for (i = 0; i < 2; i++) + { + for (j = 0; j < 64; j++) + { + va_TraceMsg("%d\t", p->ScalingList8x8[i][j]); + if ((j + 1) % 8 == 0) + va_TraceMsg("\n"); + } + } +} + +static void va_TraceVAPictureParameterBufferVC1( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *data +) +{ + VAPictureParameterBufferVC1* p = (VAPictureParameterBufferVC1*)data; + + va_TraceMsg("\tforward_reference_picture = 0x%08x\n", p->forward_reference_picture); + va_TraceMsg("\tbackward_reference_picture = 0x%08x\n", p->backward_reference_picture); + va_TraceMsg("\tinloop_decoded_picture = 0x%08x\n", p->inloop_decoded_picture); + + va_TraceMsg("\tpulldown = %d\n", p->sequence_fields.bits.pulldown); + va_TraceMsg("\tinterlace = %d\n", p->sequence_fields.bits.interlace); + va_TraceMsg("\ttfcntrflag = %d\n", p->sequence_fields.bits.tfcntrflag); + va_TraceMsg("\tfinterpflag = %d\n", p->sequence_fields.bits.finterpflag); + va_TraceMsg("\tpsf = %d.\n", + p->sequence_fields.bits.psf); + va_TraceMsg("\tmultires = %d.\n", + p->sequence_fields.bits.multires); + va_TraceMsg("\toverlap = %d.\n", + p->sequence_fields.bits.overlap); + va_TraceMsg("\tsyncmarker = %d.\n", + p->sequence_fields.bits.syncmarker); + va_TraceMsg("\trangered = %d.\n", + p->sequence_fields.bits.rangered); + va_TraceMsg("\tmax_b_frames = %d.\n", + p->sequence_fields.bits.max_b_frames); + va_TraceMsg("\tcoded_width = %d.\n", + p->coded_width); + va_TraceMsg("\tcoded_height = %d.\n", + p->coded_height); + va_TraceMsg("\tclosed_entry = %d.\n", + p->entrypoint_fields.bits.closed_entry); + va_TraceMsg("\tbroken_link = %d.\n", + p->entrypoint_fields.bits.broken_link); + va_TraceMsg("\tclosed_entry = %d.\n", + p->entrypoint_fields.bits.closed_entry); + va_TraceMsg("\tpanscan_flag = %d.\n", + p->entrypoint_fields.bits.panscan_flag); + va_TraceMsg("\tloopfilter = %d.\n", + p->entrypoint_fields.bits.loopfilter); + va_TraceMsg("\tconditional_overlap_flag = %d.\n", + p->conditional_overlap_flag); + va_TraceMsg("\tfast_uvmc_flag = %d.\n", + p->fast_uvmc_flag); + va_TraceMsg("\trange_mapping_luma_flag = %d.\n", + p->range_mapping_fields.bits.luma_flag); + va_TraceMsg("\trange_mapping_luma = %d.\n", + p->range_mapping_fields.bits.luma); + va_TraceMsg("\trange_mapping_chroma_flag = %d.\n", + p->range_mapping_fields.bits.chroma_flag); + va_TraceMsg("\trange_mapping_chroma = %d.\n", + p->range_mapping_fields.bits.chroma); + va_TraceMsg("\tb_picture_fraction = %d.\n", + p->b_picture_fraction); + va_TraceMsg("\tcbp_table = %d.\n", + p->cbp_table); + va_TraceMsg("\tmb_mode_table = %d.\n", + p->mb_mode_table); + va_TraceMsg("\trange_reduction_frame = %d.\n", + p->range_reduction_frame); + va_TraceMsg("\trounding_control = %d.\n", + p->rounding_control); + va_TraceMsg("\tpost_processing = %d.\n", + p->post_processing); + va_TraceMsg("\tpicture_resolution_index = %d.\n", + p->picture_resolution_index); + va_TraceMsg("\tluma_scale = %d.\n", + p->luma_scale); + va_TraceMsg("\tluma_shift = %d.\n", + p->luma_shift); + va_TraceMsg("\tpicture_type = %d.\n", + p->picture_fields.bits.picture_type); + va_TraceMsg("\tframe_coding_mode = %d.\n", + p->picture_fields.bits.frame_coding_mode); + va_TraceMsg("\ttop_field_first = %d.\n", + p->picture_fields.bits.top_field_first); + va_TraceMsg("\tis_first_field = %d.\n", + p->picture_fields.bits.is_first_field); + va_TraceMsg("\tintensity_compensation = %d.\n", + p->picture_fields.bits.intensity_compensation); + va_TraceMsg(" ---------------------------------\n"); + va_TraceMsg("\tmv_type_mb = %d.\n", + p->raw_coding.flags.mv_type_mb); + va_TraceMsg("\tdirect_mb = %d.\n", + p->raw_coding.flags.direct_mb); + va_TraceMsg("\tskip_mb = %d.\n", + p->raw_coding.flags.skip_mb); + va_TraceMsg("\tfield_tx = %d.\n", + p->raw_coding.flags.field_tx); + va_TraceMsg("\tforward_mb = %d.\n", + p->raw_coding.flags.forward_mb); + va_TraceMsg("\tac_pred = %d.\n", + p->raw_coding.flags.ac_pred); + va_TraceMsg("\toverflags = %d.\n", + p->raw_coding.flags.overflags); + va_TraceMsg(" ---------------------------------\n"); + va_TraceMsg("\tbp_mv_type_mb = %d.\n", + p->bitplane_present.flags.bp_mv_type_mb); + va_TraceMsg("\tbp_direct_mb = %d.\n", + p->bitplane_present.flags.bp_direct_mb); + va_TraceMsg("\tbp_skip_mb = %d.\n", + p->bitplane_present.flags.bp_skip_mb); + va_TraceMsg("\tbp_field_tx = %d.\n", + p->bitplane_present.flags.bp_field_tx); + va_TraceMsg("\tbp_forward_mb = %d.\n", + p->bitplane_present.flags.bp_forward_mb); + va_TraceMsg("\tbp_ac_pred = %d.\n", + p->bitplane_present.flags.bp_ac_pred); + va_TraceMsg("\tbp_overflags = %d.\n", + p->bitplane_present.flags.bp_overflags); + va_TraceMsg(" ---------------------------------\n"); + va_TraceMsg("\treference_distance_flag = %d.\n", + p->reference_fields.bits.reference_distance_flag); + va_TraceMsg("\treference_distance = %d.\n", + p->reference_fields.bits.reference_distance); + va_TraceMsg("\tnum_reference_pictures = %d.\n", + p->reference_fields.bits.num_reference_pictures); + va_TraceMsg("\treference_field_pic_indicator = %d.\n", + p->reference_fields.bits.reference_field_pic_indicator); + va_TraceMsg("\tmv_mode = %d.\n", + p->mv_fields.bits.mv_mode); + va_TraceMsg("\tmv_mode2 = %d.\n", + p->mv_fields.bits.mv_mode2); + va_TraceMsg("\tmv_table = %d.\n", + p->mv_fields.bits.mv_table); + va_TraceMsg("\ttwo_mv_block_pattern_table = %d.\n", + p->mv_fields.bits.two_mv_block_pattern_table); + va_TraceMsg("\tfour_mv_switch = %d.\n", + p->mv_fields.bits.four_mv_switch); + va_TraceMsg("\tfour_mv_block_pattern_table = %d.\n", + p->mv_fields.bits.four_mv_block_pattern_table); + va_TraceMsg("\textended_mv_flag = %d.\n", + p->mv_fields.bits.extended_mv_flag); + va_TraceMsg("\textended_mv_range = %d.\n", + p->mv_fields.bits.extended_mv_range); + va_TraceMsg("\textended_dmv_flag = %d.\n", + p->mv_fields.bits.extended_dmv_flag); + va_TraceMsg("\textended_dmv_range = %d.\n", + p->mv_fields.bits.extended_dmv_range); + va_TraceMsg("\tdquant = %d.\n", + p->pic_quantizer_fields.bits.dquant); + va_TraceMsg("\tquantizer = %d.\n", + p->pic_quantizer_fields.bits.quantizer); + va_TraceMsg("\thalf_qp = %d.\n", + p->pic_quantizer_fields.bits.half_qp); + va_TraceMsg("\tpic_quantizer_scale = %d.\n", + p->pic_quantizer_fields.bits.pic_quantizer_scale); + va_TraceMsg("\tpic_quantizer_type = %d.\n", + p->pic_quantizer_fields.bits.pic_quantizer_type); + va_TraceMsg("\tdq_frame = %d.\n", + p->pic_quantizer_fields.bits.dq_frame); + va_TraceMsg("\tdq_profile = %d.\n", + p->pic_quantizer_fields.bits.dq_profile); + va_TraceMsg("\tdq_sb_edge = %d.\n", + p->pic_quantizer_fields.bits.dq_sb_edge); + va_TraceMsg("\tdq_db_edge = %d.\n", + p->pic_quantizer_fields.bits.dq_db_edge); + va_TraceMsg("\tdq_binary_level = %d.\n", + p->pic_quantizer_fields.bits.dq_binary_level); + va_TraceMsg("\talt_pic_quantizer = %d.\n", + p->pic_quantizer_fields.bits.alt_pic_quantizer); + va_TraceMsg("\tvariable_sized_transform_flag = %d.\n", + p->transform_fields.bits.variable_sized_transform_flag); + va_TraceMsg("\tmb_level_transform_type_flag = %d.\n", + p->transform_fields.bits.mb_level_transform_type_flag); + va_TraceMsg("\tframe_level_transform_type = %d.\n", + p->transform_fields.bits.frame_level_transform_type); + va_TraceMsg("\ttransform_ac_codingset_idx1 = %d.\n", + p->transform_fields.bits.transform_ac_codingset_idx1); + va_TraceMsg("\ttransform_ac_codingset_idx2 = %d.\n", + p->transform_fields.bits.transform_ac_codingset_idx2); + va_TraceMsg("\tintra_transform_dc_table = %d.\n", + p->transform_fields.bits.intra_transform_dc_table); +} + +static void va_TraceVASliceParameterBufferVC1( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void* data +) +{ + VASliceParameterBufferVC1 *p = (VASliceParameterBufferVC1*)data; + + va_TraceMsg ("========== SLICE NUMBER ==========\n"); + va_TraceMsg (" slice_data_size = %d\n", p->slice_data_size); + va_TraceMsg (" slice_data_offset = %d\n", p->slice_data_offset); + va_TraceMsg (" slice_data_flag = %d\n", p->slice_data_flag); + va_TraceMsg (" macroblock_offset = %d\n", p->macroblock_offset); + va_TraceMsg (" slice_vertical_position = %d\n", p->slice_vertical_position); +} + +int va_TraceBeginPicture( + VADisplay dpy, + VAContextID context, + VASurfaceID render_target +) +{ + int i; + + va_TraceMsg("\tcontext = 0x%08x\n", context); + va_TraceMsg("\t\trender_targets = 0x%08x\n", render_target); + + trace_rendertarget = render_target; /* for surface data dump after vaEndPicture */ + + trace_frame++; + trace_slice = 0; +} + +VAStatus vaBufferInfo ( + VADisplay dpy, + VAContextID context, /* in */ + VABufferID buf_id, /* in */ + VABufferType *type, /* out */ + unsigned int *size, /* out */ + unsigned int *num_elements /* out */ +); + +static int va_TraceMPEG2Buf( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *pbuf +) +{ + switch (type) { + case VAPictureParameterBufferType: + va_TraceVAPictureParameterBufferMPEG2(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAIQMatrixBufferType: + va_TraceVAIQMatrixBufferMPEG2(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VABitPlaneBufferType: + break; + case VASliceGroupMapBufferType: + break; + case VASliceParameterBufferType: + trace_slice++; + va_TraceVASliceParameterBufferMPEG2(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VASliceDataBufferType: + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAMacroblockParameterBufferType: + break; + case VAResidualDataBufferType: + break; + case VADeblockingParameterBufferType: + break; + case VAImageBufferType: + break; + case VAProtectedSliceDataBufferType: + break; + case VAEncCodedBufferType: + break; + case VAEncSequenceParameterBufferType: + break; + case VAEncPictureParameterBufferType: + break; + case VAEncSliceParameterBufferType: + break; + case VAEncH264VUIBufferType: + break; + case VAEncH264SEIBufferType: + break; + } + + return 0; +} + + +static int va_TraceMPEG4Buf( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *pbuf +) +{ + switch (type) { + case VAPictureParameterBufferType: + va_TraceVAPictureParameterBufferMPEG4(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAIQMatrixBufferType: + va_TraceVAIQMatrixBufferMPEG4(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VABitPlaneBufferType: + break; + case VASliceGroupMapBufferType: + break; + case VASliceParameterBufferType: + va_TraceVASliceParameterBufferMPEG4(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VASliceDataBufferType: + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAMacroblockParameterBufferType: + break; + case VAResidualDataBufferType: + break; + case VADeblockingParameterBufferType: + break; + case VAImageBufferType: + break; + case VAProtectedSliceDataBufferType: + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAEncCodedBufferType: + break; + case VAEncSequenceParameterBufferType: + break; + case VAEncPictureParameterBufferType: + break; + case VAEncSliceParameterBufferType: + break; + case VAEncH264VUIBufferType: + break; + case VAEncH264SEIBufferType: + break; + default: + break; + } + + + return 0; +} + + +static int va_TraceH264Buf( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *pbuf +) +{ + switch (type) { + case VAPictureParameterBufferType: + va_TraceVAPictureParameterBufferMPEG2(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAIQMatrixBufferType: + va_TraceVAIQMatrixBufferH264(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VABitPlaneBufferType: + break; + case VASliceGroupMapBufferType: + break; + case VASliceParameterBufferType: + va_TraceVASliceParameterBufferH264(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VASliceDataBufferType: + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAMacroblockParameterBufferType: + break; + case VAResidualDataBufferType: + break; + case VADeblockingParameterBufferType: + break; + case VAImageBufferType: + break; + case VAProtectedSliceDataBufferType: + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAEncCodedBufferType: + break; + case VAEncSequenceParameterBufferType: + break; + case VAEncPictureParameterBufferType: + break; + case VAEncSliceParameterBufferType: + break; + case VAEncH264VUIBufferType: + break; + case VAEncH264SEIBufferType: + break; + default: + break; + } + + + return 0; +} + + +static int va_TraceVC1Buf( + VADisplay dpy, + VAContextID context, + VABufferID buffer, + VABufferType type, + unsigned int size, + unsigned int num_elements, + void *pbuf +) +{ + switch (type) { + case VAPictureParameterBufferType: + va_TraceVAPictureParameterBufferVC1(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAIQMatrixBufferType: + break; + case VABitPlaneBufferType: + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VASliceGroupMapBufferType: + break; + case VASliceParameterBufferType: + va_TraceVASliceParameterBufferVC1(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VASliceDataBufferType: + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAMacroblockParameterBufferType: + break; + case VAResidualDataBufferType: + break; + case VADeblockingParameterBufferType: + break; + case VAImageBufferType: + break; + case VAProtectedSliceDataBufferType: + va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf); + break; + case VAEncCodedBufferType: + break; + case VAEncSequenceParameterBufferType: + break; + case VAEncPictureParameterBufferType: + break; + case VAEncSliceParameterBufferType: + break; + case VAEncH264VUIBufferType: + break; + case VAEncH264SEIBufferType: + break; + default: + break; + } + + return 0; +} + +int va_TraceRenderPicture( + VADisplay dpy, + VAContextID context, + VABufferID *buffers, + int num_buffers +) +{ + VABufferType type; + unsigned int size; + unsigned int num_elements; + int i; + + va_TraceMsg("\tcontext = 0x%08x\n", context); + va_TraceMsg("\tnum_buffers = %d\n", num_buffers); + for (i = 0; i < num_buffers; i++) { + void *pbuf; + + /* get buffer type information */ + vaBufferInfo(dpy, context, buffers[i], &type, &size, &num_elements); + + va_TraceMsg("\t\tbuffers[%d] = 0x%08x\n", i, buffers[i]); + va_TraceMsg("\t\t\ttype = %s\n", buffer_type_to_string(type)); + va_TraceMsg("\t\t\tsize = %d\n", size); + va_TraceMsg("\t\t\tnum_elements = %d\n", num_elements); + + + vaMapBuffer(dpy, buffers[i], &pbuf); + + switch (trace_profile) { + case VAProfileMPEG2Simple: + case VAProfileMPEG2Main: + va_TraceMPEG2Buf(dpy, context, buffers[i], type, size, num_elements, pbuf); + break; + case VAProfileMPEG4Simple: + case VAProfileMPEG4AdvancedSimple: + case VAProfileMPEG4Main: + va_TraceMPEG4Buf(dpy, context, buffers[i], type, size, num_elements, pbuf); + break; + case VAProfileH264Baseline: + case VAProfileH264Main: + case VAProfileH264High: + va_TraceH264Buf(dpy, context, buffers[i], type, size, num_elements, pbuf); + break; + case VAProfileVC1Simple: + case VAProfileVC1Main: + case VAProfileVC1Advanced: + va_TraceVC1Buf(dpy, context, buffers[i], type, size, num_elements, pbuf); + break; + case VAProfileH263Baseline: + break; + } + + vaUnmapBuffer(dpy, buffers[i]); + } +} + + +int va_TraceEndPicture( + VADisplay dpy, + VAContextID context +) +{ + int i, j; + unsigned int fourcc; /* following are output argument */ + unsigned int luma_stride; + unsigned int chroma_u_stride; + unsigned int chroma_v_stride; + unsigned int luma_offset; + unsigned int chroma_u_offset; + unsigned int chroma_v_offset; + unsigned int buffer_name; + void *buffer; + char *Y_data, *UV_data, *tmp; + + VAStatus va_status; + + va_TraceMsg("\tcontext = 0x%08x\n", context); + va_TraceMsg("\t\trender_targets = 0x%08x\n", trace_rendertarget); + + /* force the pipleline finish rendering */ + vaSyncSurface(dpy, trace_rendertarget); + + va_TraceMsg("***dump surface data***\n", trace_rendertarget); + + va_status = vaLockSurface(dpy, trace_rendertarget, &fourcc, &luma_stride, &chroma_u_stride, &chroma_v_stride, + &luma_offset, &chroma_u_offset, &chroma_v_offset, &buffer_name, &buffer); + + if (va_status != VA_STATUS_SUCCESS) + return va_status; + + va_TraceMsg("\tfourcc=0x%08x\n", fourcc); + va_TraceMsg("\twidth=%d\n", trace_width); + va_TraceMsg("\theight=%d\n", trace_height); + va_TraceMsg("\tluma_stride=%d\n", luma_stride); + va_TraceMsg("\tchroma_u_stride=%d\n", chroma_u_stride); + va_TraceMsg("\tchroma_v_stride=%d\n", chroma_v_stride); + va_TraceMsg("\tluma_offset=%d\n", luma_offset); + va_TraceMsg("\tchroma_u_offset=%d\n", chroma_u_offset); + va_TraceMsg("\tchroma_v_offset=%d\n", chroma_v_offset); + + if (!buffer) + return; + + Y_data = buffer; + UV_data = buffer + luma_offset; + + tmp = Y_data; + va_TraceMsg("**Y data**\n"); + for (i=0; i<trace_height; i++) { + for (j=0; j<trace_width; j++) { + if ((j%16) == 0) + va_TraceMsg("\n0x%08x:", j + i*trace_width); + va_TraceMsg(" %02x", tmp[j]); + } + + va_TraceMsg("\n"); + tmp = Y_data + i * luma_stride; + } + + tmp = UV_data; + if (fourcc == VA_FOURCC_NV12) { + va_TraceMsg("**UV data**\n"); + + for (i=0; i<trace_height/2; i++) { + for (j=0; j<trace_width; j++) { + if ((j%16) == 0) + va_TraceMsg("\n0x%08x:", j + i*trace_width); + va_TraceMsg(" %02x", tmp[j]); + } + + va_TraceMsg("\n"); + tmp = UV_data + i * chroma_u_stride; + } + } +} diff --git a/va/x11/dri1_util.c b/va/x11/dri1_util.c index 3e67e2a..d9afca6 100644 --- a/va/x11/dri1_util.c +++ b/va/x11/dri1_util.c @@ -62,12 +62,12 @@ dri1Close(VADriverContextP ctx) struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; free_drawable_hashtable(ctx); - VA_DRIDestroyContext(ctx->x11_dpy, ctx->x11_screen, dri_state->hwContextID); + VA_DRIDestroyContext((Display *)ctx->native_dpy, ctx->x11_screen, dri_state->hwContextID); assert(dri_state->pSAREA != MAP_FAILED); drmUnmap(dri_state->pSAREA, SAREA_MAX); assert(dri_state->fd >= 0); drmCloseOnce(dri_state->fd); - VA_DRICloseConnection(ctx->x11_dpy, ctx->x11_screen); + VA_DRICloseConnection((Display *)ctx->native_dpy, ctx->x11_screen); } Bool @@ -87,7 +87,7 @@ isDRI1Connected(VADriverContextP ctx, char **driver_name) dri_state->pSAREA = MAP_FAILED; dri_state->driConnectedFlag = VA_NONE; - if (!VA_DRIQueryDirectRenderingCapable(ctx->x11_dpy, + if (!VA_DRIQueryDirectRenderingCapable((Display *)ctx->native_dpy, ctx->x11_screen, &direct_capable)) goto err_out0; @@ -95,12 +95,12 @@ isDRI1Connected(VADriverContextP ctx, char **driver_name) if (!direct_capable) goto err_out0; - if (!VA_DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, + if (!VA_DRIGetClientDriverName((Display *)ctx->native_dpy, ctx->x11_screen, &driver_major, &driver_minor, &driver_patch, driver_name)) goto err_out0; - if (!VA_DRIOpenConnection(ctx->x11_dpy, ctx->x11_screen, + if (!VA_DRIOpenConnection((Display *)ctx->native_dpy, ctx->x11_screen, &dri_state->hSAREA, &BusID)) goto err_out0; @@ -115,14 +115,14 @@ isDRI1Connected(VADriverContextP ctx, char **driver_name) if (drmGetMagic(dri_state->fd, &magic)) goto err_out1; - if (newlyopened && !VA_DRIAuthConnection(ctx->x11_dpy, ctx->x11_screen, magic)) + if (newlyopened && !VA_DRIAuthConnection((Display *)ctx->native_dpy, ctx->x11_screen, magic)) goto err_out1; if (drmMap(dri_state->fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA)) goto err_out1; - if (!VA_DRICreateContext(ctx->x11_dpy, ctx->x11_screen, - DefaultVisual(ctx->x11_dpy, ctx->x11_screen), + if (!VA_DRICreateContext((Display *)ctx->native_dpy, ctx->x11_screen, + DefaultVisual((Display *)ctx->native_dpy, ctx->x11_screen), &dri_state->hwContextID, &dri_state->hwContext)) goto err_out1; @@ -142,7 +142,7 @@ err_out1: if (dri_state->fd >= 0) drmCloseOnce(dri_state->fd); - VA_DRICloseConnection(ctx->x11_dpy, ctx->x11_screen); + VA_DRICloseConnection((Display *)ctx->native_dpy, ctx->x11_screen); err_out0: if (*driver_name) diff --git a/va/x11/dri2_util.c b/va/x11/dri2_util.c index ff73623..63db330 100644 --- a/va/x11/dri2_util.c +++ b/va/x11/dri2_util.c @@ -50,7 +50,7 @@ dri2CreateDrawable(VADriverContextP ctx, XID x_drawable) dri2_drawable->base.x_drawable = x_drawable; dri2_drawable->base.x = 0; dri2_drawable->base.y = 0; - VA_DRI2CreateDrawable(ctx->x11_dpy, x_drawable); + VA_DRI2CreateDrawable((Display *)ctx->native_dpy, x_drawable); return &dri2_drawable->base; } @@ -58,7 +58,7 @@ dri2CreateDrawable(VADriverContextP ctx, XID x_drawable) static void dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable) { - VA_DRI2DestroyDrawable(ctx->x11_dpy, dri_drawable->x_drawable); + VA_DRI2DestroyDrawable((Display *)ctx->native_dpy, dri_drawable->x_drawable); free(dri_drawable); } @@ -72,7 +72,7 @@ dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) if (dri2_drawable->has_backbuffer) { if (gsDRI2SwapAvailable) { CARD64 ret; - VA_DRI2SwapBuffers(ctx->x11_dpy, dri_drawable->x_drawable, 0, 0, + VA_DRI2SwapBuffers(ctx->native_dpy, dri_drawable->x_drawable, 0, 0, 0, &ret); } else { xrect.x = 0; @@ -80,10 +80,10 @@ dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) xrect.width = dri2_drawable->width; xrect.height = dri2_drawable->height; - region = XFixesCreateRegion(ctx->x11_dpy, &xrect, 1); - VA_DRI2CopyRegion(ctx->x11_dpy, dri_drawable->x_drawable, region, + region = XFixesCreateRegion(ctx->native_dpy, &xrect, 1); + VA_DRI2CopyRegion(ctx->native_dpy, dri_drawable->x_drawable, region, DRI2BufferFrontLeft, DRI2BufferBackLeft); - XFixesDestroyRegion(ctx->x11_dpy, region); + XFixesDestroyRegion(ctx->native_dpy, region); } } } @@ -99,7 +99,7 @@ dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) i = 0; attachments[i++] = __DRI_BUFFER_BACK_LEFT; - buffers = VA_DRI2GetBuffers(ctx->x11_dpy, dri_drawable->x_drawable, + buffers = VA_DRI2GetBuffers(ctx->native_dpy, dri_drawable->x_drawable, &dri2_drawable->width, &dri2_drawable->height, attachments, i, &count); assert(buffers); @@ -156,14 +156,14 @@ isDRI2Connected(VADriverContextP ctx, char **driver_name) *driver_name = NULL; dri_state->fd = -1; dri_state->driConnectedFlag = VA_NONE; - if (!VA_DRI2QueryExtension(ctx->x11_dpy, &event_base, &error_base)) + if (!VA_DRI2QueryExtension((Display *)ctx->native_dpy, &event_base, &error_base)) goto err_out; - if (!VA_DRI2QueryVersion(ctx->x11_dpy, &major, &minor)) + if (!VA_DRI2QueryVersion((Display *)ctx->native_dpy, &major, &minor)) goto err_out; - if (!VA_DRI2Connect(ctx->x11_dpy, RootWindow(ctx->x11_dpy, ctx->x11_screen), + if (!VA_DRI2Connect((Display *)ctx->native_dpy, RootWindow((Display *)ctx->native_dpy, ctx->x11_screen), driver_name, &device_name)) goto err_out; @@ -176,7 +176,7 @@ isDRI2Connected(VADriverContextP ctx, char **driver_name) if (drmGetMagic(dri_state->fd, &magic)) goto err_out; - if (!VA_DRI2Authenticate(ctx->x11_dpy, RootWindow(ctx->x11_dpy, ctx->x11_screen), + if (!VA_DRI2Authenticate((Display *)ctx->native_dpy, RootWindow((Display *)ctx->native_dpy, ctx->x11_screen), magic)) goto err_out; diff --git a/va/x11/va_dricommon.h b/va/x11/va_dricommon.h index b762bd0..ae364e7 100644 --- a/va/x11/va_dricommon.h +++ b/va/x11/va_dricommon.h @@ -1,19 +1,26 @@ #ifndef _VA_DRICOMMON_H_ #define _VA_DRICOMMON_H_ +#ifndef ANDROID #include <X11/Xlib.h> - #include <xf86drm.h> #include <drm.h> #include <drm_sarea.h> +#endif #include <va/va_backend.h> +#ifdef ANDROID +#define XID unsigned int +#define Bool int +#endif + enum { VA_NONE = 0, VA_DRI1 = 1, - VA_DRI2 = 2 + VA_DRI2 = 2, + VA_DUMMY = 3 }; union dri_buffer @@ -45,6 +52,7 @@ struct dri_state { int fd; int driConnectedFlag; /* 0: disconnected, 1: DRI, 2: DRI2 */ +#ifndef ANDROID drm_handle_t hSAREA; drm_context_t hwContext; drmAddress pSAREA; @@ -56,6 +64,7 @@ struct dri_state void (*swapBuffer)(VADriverContextP ctx, struct dri_drawable *dri_drawable); union dri_buffer *(*getRenderingBuffer)(VADriverContextP ctx, struct dri_drawable *dri_drawable); void (*close)(VADriverContextP ctx); +#endif }; Bool isDRI2Connected(VADriverContextP ctx, char **driver_name); diff --git a/va/x11/va_x11.c b/va/x11/va_x11.c index 29e81c8..7f8fbd6 100644 --- a/va/x11/va_x11.c +++ b/va/x11/va_x11.c @@ -116,12 +116,12 @@ static VAStatus va_NVCTRL_GetDriverName ( int direct_capable, driver_major, driver_minor, driver_patch; Bool result; - result = VA_NVCTRLQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen, + result = VA_NVCTRLQueryDirectRenderingCapable((Display *)ctx->native_dpy, ctx->x11_screen, &direct_capable); if (!result || !direct_capable) return VA_STATUS_ERROR_UNKNOWN; - result = VA_NVCTRLGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, + result = VA_NVCTRLGetClientDriverName((Display *)ctx->native_dpy, ctx->x11_screen, &driver_major, &driver_minor, &driver_patch, driver_name); if (!result) @@ -136,19 +136,10 @@ static VAStatus va_DisplayContextGetDriverName ( ) { VAStatus vaStatus; - char *driver_name_env; if (driver_name) *driver_name = NULL; - if ((driver_name_env = getenv("LIBVA_DRIVER_NAME")) != NULL - && geteuid() == getuid()) - { - /* don't allow setuid apps to use LIBVA_DRIVER_NAME */ - *driver_name = strdup(driver_name_env); - return VA_STATUS_SUCCESS; - } - vaStatus = va_DRI2GetDriverName(pDisplayContext, driver_name); if (vaStatus != VA_STATUS_SUCCESS) vaStatus = va_DRIGetDriverName(pDisplayContext, driver_name); @@ -172,7 +163,7 @@ VADisplay vaGetDisplay ( while (pDisplayContext) { if (pDisplayContext->pDriverContext && - pDisplayContext->pDriverContext->x11_dpy == native_dpy) + pDisplayContext->pDriverContext->native_dpy == (void *)native_dpy) { dpy = (VADisplay)pDisplayContext; break; @@ -192,12 +183,13 @@ VADisplay vaGetDisplay ( { pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC; - pDriverContext->x11_dpy = native_dpy; + pDriverContext->native_dpy = (void *)native_dpy; pDisplayContext->pNext = pDisplayContexts; pDisplayContext->pDriverContext = pDriverContext; pDisplayContext->vaIsValid = va_DisplayContextIsValid; pDisplayContext->vaDestroy = va_DisplayContextDestroy; pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName; + pDisplayContext->opaque = NULL; pDisplayContexts = pDisplayContext; pDriverContext->dri_state = dri_state; dpy = (VADisplay)pDisplayContext; @@ -215,3 +207,33 @@ VADisplay vaGetDisplay ( return dpy; } + +#define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext) +#define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; } + +VAStatus vaPutSurface ( + VADisplay dpy, + VASurfaceID surface, + Drawable draw, /* X Drawable */ + short srcx, + short srcy, + unsigned short srcw, + unsigned short srch, + short destx, + short desty, + unsigned short destw, + unsigned short desth, + VARectangle *cliprects, /* client supplied clip list */ + unsigned int number_cliprects, /* number of clip rects in the clip list */ + unsigned int flags /* de-interlacing flags */ +) +{ + VADriverContextP ctx; + + CHECK_DISPLAY(dpy); + ctx = CTX(dpy); + + return ctx->vtable.vaPutSurface( ctx, surface, (void *)draw, srcx, srcy, srcw, srch, + destx, desty, destw, desth, + cliprects, number_cliprects, flags ); +} |