summaryrefslogtreecommitdiff
path: root/va
diff options
context:
space:
mode:
Diffstat (limited to 'va')
-rw-r--r--va/Android.mk91
-rw-r--r--va/Makefile.am50
-rw-r--r--va/android/Makefile.am30
-rw-r--r--va/android/drmtest.c139
-rw-r--r--va/android/drmtest.h40
-rw-r--r--va/android/va_android.cpp300
l---------va/android/va_dummy.c1
l---------va/dummy1
-rw-r--r--va/glx/Makefile.am41
-rw-r--r--va/glx/va_backend_glx.h54
-rw-r--r--va/glx/va_glx.c165
-rw-r--r--va/glx/va_glx.h109
-rw-r--r--va/glx/va_glx_impl.c1078
-rw-r--r--va/glx/va_glx_impl.h37
-rw-r--r--va/glx/va_glx_private.h76
-rw-r--r--va/va.c262
-rw-r--r--va/va.h103
-rw-r--r--va/va_android.h54
-rw-r--r--va/va_backend.h54
-rw-r--r--va/va_backend_tpi.h74
l---------va/va_dummy.h1
-rw-r--r--va/va_tpi.c130
-rw-r--r--va/va_tpi.h73
-rw-r--r--va/va_trace.c1115
-rw-r--r--va/x11/dri1_util.c18
-rw-r--r--va/x11/dri2_util.c22
-rw-r--r--va/x11/va_dricommon.h13
-rw-r--r--va/x11/va_x11.c48
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 */
diff --git a/va/va.c b/va/va.c
index c8e036e..00a96cf 100644
--- a/va/va.c
+++ b/va/va.c
@@ -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 );
}
diff --git a/va/va.h b/va/va.h
index 08294a8..a4a9cf6 100644
--- a/va/va.h
+++ b/va/va.h
@@ -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 );
+}