From 4d74a235f18cf13166adefc3bbb02638bc36424a Mon Sep 17 00:00:00 2001 From: Waldo Bastian Date: Thu, 13 Sep 2007 10:18:11 -0700 Subject: [PATCH 1/1] libva 0.23 --- COPYING | 19 + Makefile.am | 29 + autogen.sh | 3 + configure.ac | 42 ++ dummy_drv_video/Makefile.am | 30 + dummy_drv_video/dummy_drv_video.c | 1162 +++++++++++++++++++++++++++++ dummy_drv_video/dummy_drv_video.h | 76 ++ dummy_drv_video/object_heap.c | 192 +++++ dummy_drv_video/object_heap.h | 89 +++ libva.pc.in | 10 + src/Makefile.am | 33 + src/va.c | 1072 ++++++++++++++++++++++++++ src/va.h | 1487 +++++++++++++++++++++++++++++++++++++ src/va_backend.h | 346 +++++++++ src/va_dri.c | 624 ++++++++++++++++ src/va_dri.h | 120 +++ src/va_dristr.h | 344 +++++++++ src/va_x11.h | 104 +++ test/Makefile.am | 33 + test/test.c | 152 ++++ 20 files changed, 5967 insertions(+) create mode 100644 COPYING create mode 100644 Makefile.am create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 dummy_drv_video/Makefile.am create mode 100644 dummy_drv_video/dummy_drv_video.c create mode 100644 dummy_drv_video/dummy_drv_video.h create mode 100644 dummy_drv_video/object_heap.c create mode 100644 dummy_drv_video/object_heap.h create mode 100644 libva.pc.in create mode 100644 src/Makefile.am create mode 100644 src/va.c create mode 100755 src/va.h create mode 100755 src/va_backend.h create mode 100644 src/va_dri.c create mode 100644 src/va_dri.h create mode 100644 src/va_dristr.h create mode 100755 src/va_x11.h create mode 100644 test/Makefile.am create mode 100644 test/test.c diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..765e825 --- /dev/null +++ b/COPYING @@ -0,0 +1,19 @@ + 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. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..5470b69 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,29 @@ +# 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. + +AUTOMAKE_OPTIONS = foreign +SUBDIRS = src dummy_drv_video test + +pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libva.pc + +EXTRA_DIST = libva.pc.in diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..9c2f4f6 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,3 @@ +#! /bin/sh +autoreconf -v --install +./configure "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..82088ff --- /dev/null +++ b/configure.ac @@ -0,0 +1,42 @@ +# 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. + +AC_PREREQ(2.57) +AC_INIT([libva], 0.22, [waldo.bastian@intel.com], libva) +AC_CONFIG_SRCDIR([Makefile.am]) +AM_INIT_AUTOMAKE([dist-bzip2]) + +AM_CONFIG_HEADER([src/config.h]) + +AC_DISABLE_STATIC +AC_PROG_LIBTOOL +AC_PROG_CC + +AC_HEADER_STDC +AC_SYS_LARGEFILE + +PKG_CHECK_MODULES([libva_la], [libdrm]) + +pkgconfigdir=${libdir}/pkgconfig +AC_SUBST(pkgconfigdir) + +AC_OUTPUT([Makefile src/Makefile dummy_drv_video/Makefile test/Makefile libva.pc]) diff --git a/dummy_drv_video/Makefile.am b/dummy_drv_video/Makefile.am new file mode 100644 index 0000000..feb2f8b --- /dev/null +++ b/dummy_drv_video/Makefile.am @@ -0,0 +1,30 @@ +# 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. + +dummy_drv_video_la_LTLIBRARIES = dummy_drv_video.la +dummy_drv_video_ladir = /usr/X11R6/lib/modules/dri +dummy_drv_video_la_LDFLAGS = -no-undefined -module -Wl,--no-undefined +dummy_drv_video_la_LIBADD = -lva + +AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/../../include/external/ -I$(top_srcdir)/../../include/kmd +dummy_drv_video_la_SOURCES = dummy_drv_video.c object_heap.c + diff --git a/dummy_drv_video/dummy_drv_video.c b/dummy_drv_video/dummy_drv_video.c new file mode 100644 index 0000000..ce600aa --- /dev/null +++ b/dummy_drv_video/dummy_drv_video.c @@ -0,0 +1,1162 @@ +/* + * 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. + */ + +#include "va_backend.h" + +#include "dummy_drv_video.h" + +#include "assert.h" +#include +#include +#include + +#define ASSERT assert + +#define INIT_DRIVER_DATA struct dummy_driver_data *driver_data = (struct dummy_driver_data *) ctx->pDriverData; + +#define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id )) +#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) +#define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) +#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) + +#define CONFIG_ID_OFFSET 0x01000000 +#define CONTEXT_ID_OFFSET 0x02000000 +#define SURFACE_ID_OFFSET 0x04000000 +#define BUFFER_ID_OFFSET 0x08000000 + +static void dummy__error_message(const char *msg, ...) +{ + va_list args; + + fprintf(stderr, "dummy_drv_video error: "); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +} + +static void dummy__information_message(const char *msg, ...) +{ + va_list args; + + fprintf(stderr, "dummy_drv_video: "); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +} + +VAStatus dummy_QueryConfigProfiles( + VADriverContextP ctx, + VAProfile *profile_list, /* out */ + int *num_profiles /* out */ + ) +{ + INIT_DRIVER_DATA + int i = 0; + + profile_list[i++] = VAProfileMPEG2Simple; + profile_list[i++] = VAProfileMPEG2Main; + profile_list[i++] = VAProfileMPEG4Simple; + profile_list[i++] = VAProfileMPEG4AdvancedSimple; + profile_list[i++] = VAProfileMPEG4Main; + profile_list[i++] = VAProfileH264Baseline; + profile_list[i++] = VAProfileH264Main; + profile_list[i++] = VAProfileH264High; + profile_list[i++] = VAProfileVC1Simple; + profile_list[i++] = VAProfileVC1Main; + profile_list[i++] = VAProfileVC1Advanced; + + /* If the assert fails then DUMMY_MAX_PROFILES needs to be bigger */ + ASSERT(i <= DUMMY_MAX_PROFILES); + *num_profiles = i; + + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_QueryConfigEntrypoints( + VADriverContextP ctx, + VAProfile profile, + VAEntrypoint *entrypoint_list, /* out */ + int *num_entrypoints /* out */ + ) +{ + INIT_DRIVER_DATA + + switch (profile) { + case VAProfileMPEG2Simple: + case VAProfileMPEG2Main: + *num_entrypoints = 2; + entrypoint_list[0] = VAEntrypointVLD; + entrypoint_list[1] = VAEntrypointMoComp; + break; + + case VAProfileMPEG4Simple: + case VAProfileMPEG4AdvancedSimple: + case VAProfileMPEG4Main: + *num_entrypoints = 1; + entrypoint_list[0] = VAEntrypointVLD; + break; + + case VAProfileH264Baseline: + case VAProfileH264Main: + case VAProfileH264High: + *num_entrypoints = 1; + entrypoint_list[0] = VAEntrypointVLD; + break; + + case VAProfileVC1Simple: + case VAProfileVC1Main: + case VAProfileVC1Advanced: + *num_entrypoints = 1; + entrypoint_list[0] = VAEntrypointVLD; + break; + + default: + *num_entrypoints = 0; + break; + } + + /* If the assert fails then DUMMY_MAX_ENTRYPOINTS needs to be bigger */ + ASSERT(*num_entrypoints <= DUMMY_MAX_ENTRYPOINTS); + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_QueryConfigAttributes( + VADriverContextP ctx, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, /* in/out */ + int num_attribs + ) +{ + INIT_DRIVER_DATA + + int i; + + /* Other attributes don't seem to be defined */ + /* What to do if we don't know the attribute? */ + for (i = 0; i < num_attribs; i++) + { + switch (attrib_list[i].type) + { + case VAConfigAttribRTFormat: + attrib_list[i].value = VA_RT_FORMAT_YUV420; + break; + + default: + /* Do nothing */ + attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; + break; + } + } + + return VA_STATUS_SUCCESS; +} + +static VAStatus dummy__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib) +{ + int i; + /* Check existing attrbiutes */ + for(i = 0; obj_config->attrib_count < i; i++) + { + if (obj_config->attrib_list[i].type == attrib->type) + { + /* Update existing attribute */ + obj_config->attrib_list[i].value = attrib->value; + return VA_STATUS_SUCCESS; + } + } + if (obj_config->attrib_count < DUMMY_MAX_CONFIG_ATTRIBUTES) + { + i = obj_config->attrib_count; + obj_config->attrib_list[i].type = attrib->type; + obj_config->attrib_list[i].value = attrib->value; + obj_config->attrib_count++; + return VA_STATUS_SUCCESS; + } + return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; +} + +VAStatus dummy_CreateConfig( + VADriverContextP ctx, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, + int num_attribs, + VAConfigID *config_id /* out */ + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus; + int configID; + object_config_p obj_config; + int i; + + /* Validate profile & entrypoint */ + switch (profile) { + case VAProfileMPEG2Simple: + case VAProfileMPEG2Main: + if ((VAEntrypointVLD == entrypoint) || + (VAEntrypointMoComp == entrypoint)) + { + vaStatus = VA_STATUS_SUCCESS; + } + else + { + vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; + } + break; + + case VAProfileMPEG4Simple: + case VAProfileMPEG4AdvancedSimple: + case VAProfileMPEG4Main: + if (VAEntrypointVLD == entrypoint) + { + vaStatus = VA_STATUS_SUCCESS; + } + else + { + vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; + } + break; + + case VAProfileH264Baseline: + case VAProfileH264Main: + case VAProfileH264High: + if (VAEntrypointVLD == entrypoint) + { + vaStatus = VA_STATUS_SUCCESS; + } + else + { + vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; + } + break; + + case VAProfileVC1Simple: + case VAProfileVC1Main: + case VAProfileVC1Advanced: + if (VAEntrypointVLD == entrypoint) + { + vaStatus = VA_STATUS_SUCCESS; + } + else + { + vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; + } + break; + + default: + vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + break; + } + + if (VA_STATUS_SUCCESS != vaStatus) + { + return vaStatus; + } + + configID = object_heap_allocate( &driver_data->config_heap ); + obj_config = CONFIG(configID); + if (NULL == obj_config) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + return vaStatus; + } + + obj_config->profile = profile; + obj_config->entrypoint = entrypoint; + obj_config->attrib_list[0].type = VAConfigAttribRTFormat; + obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420; + obj_config->attrib_count = 1; + + for(i = 0; i < num_attribs; i++) + { + vaStatus = dummy__update_attribute(obj_config, &(attrib_list[i])); + if (VA_STATUS_SUCCESS != vaStatus) + { + break; + } + } + + /* Error recovery */ + if (VA_STATUS_SUCCESS != vaStatus) + { + object_heap_free( &driver_data->config_heap, (object_base_p) obj_config); + } + else + { + *config_id = configID; + } + + return vaStatus; +} + +VAStatus dummy_GetConfigAttributes( + VADriverContextP ctx, + VAConfigID config_id, + VAProfile *profile, /* out */ + VAEntrypoint *entrypoint, /* out */ + VAConfigAttrib *attrib_list, /* out */ + int *num_attribs /* out */ + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + object_config_p obj_config; + int i; + + obj_config = CONFIG(config_id); + ASSERT(obj_config); + + *profile = obj_config->profile; + *entrypoint = obj_config->entrypoint; + *num_attribs = obj_config->attrib_count; + for(i = 0; i < obj_config->attrib_count; i++) + { + attrib_list[i] = obj_config->attrib_list[i]; + } + + return vaStatus; +} + +VAStatus dummy_CreateSurfaces( + VADriverContextP ctx, + int width, + int height, + int format, + int num_surfaces, + VASurface *surfaces /* out */ + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + int i; + + /* We only support one format */ + if (VA_RT_FORMAT_YUV420 != format) + { + return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; + } + + for (i = 0; i < num_surfaces; i++) + { + int surfaceID = object_heap_allocate( &driver_data->surface_heap ); + object_surface_p obj_surface = SURFACE(surfaceID); + if (NULL == obj_surface) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + break; + } + obj_surface->surface = &(surfaces[i]); + obj_surface->surface->surface_id = surfaceID; + obj_surface->surface->context_id = -1; + obj_surface->surface->width = width; + obj_surface->surface->height = height; + obj_surface->surface->format = format; + obj_surface->surface->privData = NULL; + } + + /* Error recovery */ + if (VA_STATUS_SUCCESS != vaStatus) + { + /* surfaces[i-1] was the last successful allocation */ + for(; i--; ) + { + object_surface_p obj_surface = SURFACE(surfaces[i].surface_id); + surfaces[i].surface_id = -1; + ASSERT(obj_surface); + object_heap_free( &driver_data->surface_heap, (object_base_p) obj_surface); + } + } + + return vaStatus; +} + +VAStatus dummy_DestroySurface( + VADriverContextP ctx, + VASurface *surface_list, + int num_surfaces + ) +{ + INIT_DRIVER_DATA + int i; + for(i = num_surfaces; i--; ) + { + object_surface_p obj_surface = SURFACE(surface_list[i].surface_id); + ASSERT(obj_surface); + object_heap_free( &driver_data->surface_heap, (object_base_p) obj_surface); + } + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_QueryImageFormats( + VADriverContextP ctx, + VAImageFormat *format_list, /* out */ + int *num_formats /* out */ +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_CreateImage( + VADriverContextP ctx, + VAImageFormat *format, + int width, + int height, + VAImage *image /* out */ +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_DestroyImage( + VADriverContextP ctx, + VAImage *image +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_GetImage( + VADriverContextP ctx, + VASurface *surface, + int x, /* coordinates of the upper left source pixel */ + int y, + unsigned int width, /* width and height of the region */ + unsigned int height, + VAImage *image +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_PutImage( + VADriverContextP ctx, + VASurface *surface, + VAImage *image, + int src_x, + int src_y, + unsigned int width, + unsigned int height, + int dest_x, + int dest_y +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_QuerySubpictureFormats( + VADriverContextP ctx, + VAImageFormat *format_list, /* out */ + unsigned int *flags, /* out */ + unsigned int *num_formats /* out */ +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_CreateSubpicture( + VADriverContextP ctx, + VAImage *image, + VASubpicture *subpicture /* out */ +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_DestroySubpicture( + VADriverContextP ctx, + VASubpicture *subpicture +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_SetSubpictureImage( + VADriverContextP ctx, + VASubpicture *subpicture, + VAImage *image +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_SetSubpicturePalette( + VADriverContextP ctx, + VASubpicture *subpicture, + /* + * pointer to an array holding the palette data. The size of the array is + * num_palette_entries * entry_bytes in size. The order of the components + * in the palette is described by the component_order in VASubpicture struct + */ + unsigned char *palette +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_SetSubpictureChromakey( + VADriverContextP ctx, + VASubpicture *subpicture, + unsigned int chromakey_min, + unsigned int chromakey_max +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_SetSubpictureGlobalAlpha( + VADriverContextP ctx, + VASubpicture *subpicture, + float global_alpha +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_AssociateSubpicture( + VADriverContextP ctx, + VASurface *target_surface, + VASubpicture *subpicture, + short src_x, /* upper left offset in subpicture */ + short src_y, + short dest_x, /* upper left offset in surface */ + short dest_y, + unsigned short width, + unsigned short height, + /* + * whether to enable chroma-keying or global-alpha + * see VA_SUBPICTURE_XXX values + */ + unsigned int flags +) +{ + INIT_DRIVER_DATA + + /* TODO */ + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_CreateContext( + VADriverContextP ctx, + VAConfigID config_id, + int picture_width, + int picture_height, + int flag, + VASurface *render_targets, + int num_render_targets, + VAContext *context /* out */ + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + object_config_p obj_config; + int i; + + obj_config = CONFIG(config_id); + if (NULL == obj_config) + { + vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; + return vaStatus; + } + + /* Validate flag */ + /* Validate picture dimensions */ + + int contextID = object_heap_allocate( &driver_data->context_heap ); + object_context_p obj_context = CONTEXT(contextID); + if (NULL == obj_context) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + return vaStatus; + } + + obj_context->context = context; + obj_context->current_render_target = -1; + + obj_context->context->context_id = contextID; + obj_context->context->config_id = config_id; + obj_context->context->picture_width = picture_width; + obj_context->context->picture_height = picture_height; + obj_context->context->num_render_targets = num_render_targets; + obj_context->context->render_targets = (VASurfaceID *) malloc(num_render_targets * sizeof(VASurfaceID)); + for(i = 0; i < num_render_targets; i++) + { + if (NULL == SURFACE(render_targets[i].surface_id)) + { + vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; + break; + } + obj_context->context->render_targets[i] = render_targets[i].surface_id; + } + obj_context->context->flags = flag; + obj_context->context->privData = NULL; + + /* Error recovery */ + if (VA_STATUS_SUCCESS != vaStatus) + { + free(obj_context->context->render_targets); + obj_context->context->render_targets = NULL; + obj_context->context->context_id = -1; + obj_context->context->config_id = -1; + obj_context->context->picture_width = 0; + obj_context->context->picture_height = 0; + free(obj_context->context->render_targets); + obj_context->context->render_targets = NULL; + obj_context->context->num_render_targets = 0; + obj_context->context->flags = 0; + obj_context->context->privData = NULL; + object_heap_free( &driver_data->context_heap, (object_base_p) obj_context); + } + + return vaStatus; +} + + +VAStatus dummy_DestroyContext( + VADriverContextP ctx, + VAContext *context + ) +{ + INIT_DRIVER_DATA + object_context_p obj_context = CONTEXT(context->context_id); + ASSERT(obj_context); + + obj_context->context->context_id = -1; + obj_context->context->config_id = -1; + obj_context->context->picture_width = 0; + obj_context->context->picture_height = 0; + if (obj_context->context->render_targets) + { + free(obj_context->context->render_targets); + } + obj_context->context->render_targets = NULL; + obj_context->context->num_render_targets = 0; + obj_context->context->flags = 0; + obj_context->context->privData = NULL; + + obj_context->context = NULL; + obj_context->current_render_target = -1; + + object_heap_free( &driver_data->context_heap, (object_base_p) obj_context); + + return VA_STATUS_SUCCESS; +} + + +VAStatus dummy_CreateBuffer( + VADriverContextP ctx, + VABufferType type, /* in */ + VABufferID *buf_desc /* out */ + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + int bufferID; + object_buffer_p obj_buffer; + + /* Validate type */ + switch (type) + { + case VAPictureParameterBufferType: + case VAIQMatrixBufferType: + case VASliceParameterBufferType: + case VASliceDataBufferType: + case VAMacroblockParameterBufferType: + case VAResidualDataBufferType: + case VADeblockingParameterBufferType: + /* Ok */ + break; + default: + vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE; + return vaStatus; + } + + bufferID = object_heap_allocate( &driver_data->buffer_heap ); + obj_buffer = BUFFER(bufferID); + if (NULL == obj_buffer) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + return vaStatus; + } + + obj_buffer->buffer_data = NULL; + + *buf_desc = bufferID; + + return vaStatus; +} + +static VAStatus dummy__allocate_buffer(object_buffer_p obj_buffer, int size) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + + obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size); + if (NULL == obj_buffer->buffer_data) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + } + return vaStatus; +} + +VAStatus dummy_BufferData( + VADriverContextP ctx, + VABufferID buf_id, /* in */ + unsigned int size, /* in */ + unsigned int num_elements, /* in */ + void *data /* in */ + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + object_buffer_p obj_buffer = BUFFER(buf_id); + ASSERT(obj_buffer); + + vaStatus = dummy__allocate_buffer(obj_buffer, size * num_elements); + if (VA_STATUS_SUCCESS == vaStatus) + { + obj_buffer->max_num_elements = num_elements; + obj_buffer->num_elements = num_elements; + if (data) + { + memcpy(obj_buffer->buffer_data, data, size * num_elements); + } + } + + return vaStatus; +} + +VAStatus dummy_BufferSetNumElements( + VADriverContextP ctx, + VABufferID buf_id, /* in */ + unsigned int num_elements /* in */ + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + object_buffer_p obj_buffer = BUFFER(buf_id); + ASSERT(obj_buffer); + + if ((num_elements < 0) || (num_elements > obj_buffer->max_num_elements)) + { + vaStatus = VA_STATUS_ERROR_UNKNOWN; + } + if (VA_STATUS_SUCCESS == vaStatus) + { + obj_buffer->num_elements = num_elements; + } + + return vaStatus; +} + +VAStatus dummy_MapBuffer( + VADriverContextP ctx, + VABufferID buf_id, /* in */ + void **pbuf /* out */ + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN; + object_buffer_p obj_buffer = BUFFER(buf_id); + ASSERT(obj_buffer); + if (NULL == obj_buffer) + { + vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; + return vaStatus; + } + + if (NULL != obj_buffer->buffer_data) + { + *pbuf = obj_buffer->buffer_data; + vaStatus = VA_STATUS_SUCCESS; + } + return vaStatus; +} + +VAStatus dummy_UnmapBuffer( + VADriverContextP ctx, + VABufferID buf_id /* in */ + ) +{ + /* Do nothing */ + return VA_STATUS_SUCCESS; +} + +static void dummy__destroy_buffer(struct dummy_driver_data *driver_data, object_buffer_p obj_buffer) +{ + if (NULL != obj_buffer->buffer_data) + { + free(obj_buffer->buffer_data); + obj_buffer->buffer_data = NULL; + } + + object_heap_free( &driver_data->buffer_heap, (object_base_p) obj_buffer); +} + +VAStatus dummy_DestroyBuffer( + VADriverContextP ctx, + VABufferID buffer_id + ) +{ + INIT_DRIVER_DATA + object_buffer_p obj_buffer = BUFFER(buffer_id); + ASSERT(obj_buffer); + + dummy__destroy_buffer(driver_data, obj_buffer); + return VA_STATUS_SUCCESS; +} + +VAStatus dummy_BeginPicture( + VADriverContextP ctx, + VAContext *context, + VASurface *render_target + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + object_context_p obj_context; + object_surface_p obj_surface; + + obj_context = CONTEXT(context->context_id); + ASSERT(obj_context); + + obj_surface = SURFACE(render_target->surface_id); + ASSERT(obj_surface); + + obj_context->current_render_target = obj_surface->base.id; + + return vaStatus; +} + +VAStatus dummy_RenderPicture( + VADriverContextP ctx, + VAContext *context, + VABufferID *buffers, + int num_buffers + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + object_context_p obj_context; + object_surface_p obj_surface; + int i; + + obj_context = CONTEXT(context->context_id); + ASSERT(obj_context); + + obj_surface = SURFACE(obj_context->current_render_target); + ASSERT(obj_surface); + + /* verify that we got valid buffer references */ + for(i = 0; i < num_buffers; i++) + { + object_buffer_p obj_buffer = BUFFER(buffers[i]); + ASSERT(obj_buffer); + if (NULL == obj_buffer) + { + vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; + break; + } + } + + return vaStatus; +} + +VAStatus dummy_EndPicture( + VADriverContextP ctx, + VAContext *context + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + object_context_p obj_context; + object_surface_p obj_surface; + + obj_context = CONTEXT(context->context_id); + ASSERT(obj_context); + + obj_surface = SURFACE(obj_context->current_render_target); + ASSERT(obj_surface); + + // For now, assume that we are done with rendering right away + obj_context->current_render_target = -1; + + return vaStatus; +} + + +VAStatus dummy_SyncSurface( + VADriverContextP ctx, + VAContext *context, + VASurface *render_target + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + object_context_p obj_context; + object_surface_p obj_surface; + + obj_context = CONTEXT(context->context_id); + ASSERT(obj_context); + + obj_surface = SURFACE(render_target->surface_id); + ASSERT(obj_surface); + + /* Assume that this shouldn't be called before vaEndPicture() */ + ASSERT( obj_context->current_render_target != obj_surface->base.id ); + + return vaStatus; +} + +VAStatus dummy_QuerySurfaceStatus( + VADriverContextP ctx, + VAContext *context, + VASurface *render_target, + VASurfaceStatus *status /* out */ + ) +{ + INIT_DRIVER_DATA + VAStatus vaStatus = VA_STATUS_SUCCESS; + object_context_p obj_context; + object_surface_p obj_surface; + + obj_context = CONTEXT(context->context_id); + ASSERT(obj_context); + + obj_surface = SURFACE(render_target->surface_id); + ASSERT(obj_surface); + + /* Assume that we are busy until vaEndPicture() is called */ + if ( obj_context->current_render_target == obj_surface->base.id ) + { + *status = VASurfaceRendering; + } + else + { + *status = VASurfaceReady; + } + + return vaStatus; +} + +VAStatus dummy_PutSurface( + VADriverContextP ctx, + VASurface *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 */ + int flags /* de-interlacing flags */ + ) +{ + /* TODO */ + return VA_STATUS_ERROR_UNKNOWN; +} + + +VAStatus dummy_CopySurfaceToGLXPbuffer ( + VADriverContextP ctx, + VASurface *surface, + XID pbuffer_id, + short srcx, + short srcy, + unsigned short width, + unsigned short height, + short destx, + short desty, + unsigned int draw_buffer, + unsigned int flags /* de-interlacing flags */ +) +{ + /* TODO */ + return VA_STATUS_ERROR_UNKNOWN; +} + +VAStatus dummy_DbgCopySurfaceToBuffer( + VADriverContextP ctx, + VASurface *surface, + void **buffer, /* out */ + unsigned int *stride /* out */ + ) +{ + /* TODO */ + return VA_STATUS_ERROR_UNKNOWN; +} + +VAStatus dummy_Terminate( VADriverContextP ctx ) +{ + INIT_DRIVER_DATA + object_buffer_p obj_buffer; + object_surface_p obj_surface; + object_context_p obj_context; + object_config_p obj_config; + object_heap_iterator iter; + + /* Clean up left over buffers */ + obj_buffer = (object_buffer_p) object_heap_first( &driver_data->buffer_heap, &iter); + while (obj_buffer) + { + dummy__information_message("vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id); + dummy__destroy_buffer(driver_data, obj_buffer); + obj_buffer = (object_buffer_p) object_heap_next( &driver_data->buffer_heap, &iter); + } + object_heap_destroy( &driver_data->buffer_heap ); + + /* TODO cleanup */ + object_heap_destroy( &driver_data->surface_heap ); + + /* TODO cleanup */ + object_heap_destroy( &driver_data->context_heap ); + + /* Clean up configIDs */ + obj_config = (object_config_p) object_heap_first( &driver_data->config_heap, &iter); + while (obj_config) + { + object_heap_free( &driver_data->config_heap, (object_base_p) obj_config); + obj_config = (object_config_p) object_heap_next( &driver_data->config_heap, &iter); + } + object_heap_destroy( &driver_data->config_heap ); + + free(ctx->pDriverData); + ctx->pDriverData = NULL; + + return VA_STATUS_SUCCESS; +} + +VAStatus __vaDriverInit_0_23( VADriverContextP ctx ) +{ + object_base_p obj; + int result; + struct dummy_driver_data *driver_data; + int i; + + ctx->version_major = 0; + ctx->version_minor = 22; + ctx->max_profiles = DUMMY_MAX_PROFILES; + ctx->max_entrypoints = DUMMY_MAX_ENTRYPOINTS; + ctx->max_attributes = DUMMY_MAX_CONFIG_ATTRIBUTES; + ctx->max_image_formats = DUMMY_MAX_IMAGE_FORMATS; + ctx->max_subpic_formats = DUMMY_MAX_SUBPIC_FORMATS; + + ctx->vtable.vaTerminate = dummy_Terminate; + ctx->vtable.vaQueryConfigEntrypoints = dummy_QueryConfigEntrypoints; + ctx->vtable.vaQueryConfigProfiles = dummy_QueryConfigProfiles; + ctx->vtable.vaQueryConfigEntrypoints = dummy_QueryConfigEntrypoints; + ctx->vtable.vaQueryConfigAttributes = dummy_QueryConfigAttributes; + ctx->vtable.vaCreateConfig = dummy_CreateConfig; + ctx->vtable.vaGetConfigAttributes = dummy_GetConfigAttributes; + ctx->vtable.vaCreateSurfaces = dummy_CreateSurfaces; + ctx->vtable.vaDestroySurface = dummy_DestroySurface; + ctx->vtable.vaCreateContext = dummy_CreateContext; + ctx->vtable.vaDestroyContext = dummy_DestroyContext; + ctx->vtable.vaCreateBuffer = dummy_CreateBuffer; + ctx->vtable.vaBufferData = dummy_BufferData; + ctx->vtable.vaBufferSetNumElements = dummy_BufferSetNumElements; + ctx->vtable.vaMapBuffer = dummy_MapBuffer; + ctx->vtable.vaUnmapBuffer = dummy_UnmapBuffer; + ctx->vtable.vaDestroyBuffer = dummy_DestroyBuffer; + ctx->vtable.vaBeginPicture = dummy_BeginPicture; + ctx->vtable.vaRenderPicture = dummy_RenderPicture; + ctx->vtable.vaEndPicture = dummy_EndPicture; + ctx->vtable.vaSyncSurface = dummy_SyncSurface; + ctx->vtable.vaQuerySurfaceStatus = dummy_QuerySurfaceStatus; + ctx->vtable.vaPutSurface = dummy_PutSurface; + ctx->vtable.vaCopySurfaceToGLXPbuffer = dummy_CopySurfaceToGLXPbuffer; + ctx->vtable.vaQueryImageFormats = dummy_QueryImageFormats; + ctx->vtable.vaCreateImage = dummy_CreateImage; + ctx->vtable.vaDestroyImage = dummy_DestroyImage; + ctx->vtable.vaGetImage = dummy_GetImage; + ctx->vtable.vaPutImage = dummy_PutImage; + ctx->vtable.vaQuerySubpictureFormats = dummy_QuerySubpictureFormats; + ctx->vtable.vaCreateSubpicture = dummy_CreateSubpicture; + ctx->vtable.vaDestroySubpicture = dummy_DestroySubpicture; + ctx->vtable.vaSetSubpictureImage = dummy_SetSubpictureImage; + ctx->vtable.vaSetSubpicturePalette = dummy_SetSubpicturePalette; + ctx->vtable.vaSetSubpictureChromakey = dummy_SetSubpictureChromakey; + ctx->vtable.vaSetSubpictureGlobalAlpha = dummy_SetSubpictureGlobalAlpha; + ctx->vtable.vaAssociateSubpicture = dummy_AssociateSubpicture; + ctx->vtable.vaDbgCopySurfaceToBuffer = dummy_DbgCopySurfaceToBuffer; + + driver_data = (struct dummy_driver_data *) malloc( sizeof(*driver_data) ); + ctx->pDriverData = (void *) driver_data; + + result = object_heap_init( &driver_data->config_heap, sizeof(struct object_config), CONFIG_ID_OFFSET ); + ASSERT( result == 0 ); + + result = object_heap_init( &driver_data->context_heap, sizeof(struct object_context), CONTEXT_ID_OFFSET ); + ASSERT( result == 0 ); + + result = object_heap_init( &driver_data->surface_heap, sizeof(struct object_surface), SURFACE_ID_OFFSET ); + ASSERT( result == 0 ); + + result = object_heap_init( &driver_data->buffer_heap, sizeof(struct object_buffer), BUFFER_ID_OFFSET ); + ASSERT( result == 0 ); + + + return VA_STATUS_SUCCESS; +} + diff --git a/dummy_drv_video/dummy_drv_video.h b/dummy_drv_video/dummy_drv_video.h new file mode 100644 index 0000000..05f3c9d --- /dev/null +++ b/dummy_drv_video/dummy_drv_video.h @@ -0,0 +1,76 @@ +/* + * 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. + */ + +#ifndef _DUMMY_DRV_VIDEO_H_ +#define _DUMMY_DRV_VIDEO_H_ + +#include "va.h" +#include "object_heap.h" + +#define DUMMY_MAX_PROFILES 11 +#define DUMMY_MAX_ENTRYPOINTS 5 +#define DUMMY_MAX_CONFIG_ATTRIBUTES 10 +#define DUMMY_MAX_IMAGE_FORMATS 10 +#define DUMMY_MAX_SUBPIC_FORMATS 4 + +struct dummy_driver_data { + struct object_heap config_heap; + struct object_heap context_heap; + struct object_heap surface_heap; + struct object_heap buffer_heap; +}; + +struct object_config { + struct object_base base; + VAProfile profile; + VAEntrypoint entrypoint; + VAConfigAttrib attrib_list[DUMMY_MAX_CONFIG_ATTRIBUTES]; + int attrib_count; +}; + +struct object_context { + struct object_base base; + VAContext *context; + VAConfigID config; + VASurfaceID current_render_target; +}; + +struct object_surface { + struct object_base base; + VASurface *surface; +}; + +struct object_buffer { + struct object_base base; + void *buffer_data; + int max_num_elements; + int num_elements; +}; + +typedef struct object_config *object_config_p; +typedef struct object_context *object_context_p; +typedef struct object_surface *object_surface_p; +typedef struct object_buffer *object_buffer_p; + +#endif /* _DUMMY_DRV_VIDEO_H_ */ diff --git a/dummy_drv_video/object_heap.c b/dummy_drv_video/object_heap.c new file mode 100644 index 0000000..5e85064 --- /dev/null +++ b/dummy_drv_video/object_heap.c @@ -0,0 +1,192 @@ +/* + * 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. + */ + +#include "object_heap.h" + +#include "assert.h" +#include +#include + +#define ASSERT assert + +#define LAST_FREE -1 +#define ALLOCATED -2 + +/* + * Expands the heap + * Return 0 on success, -1 on error + */ +static int object_heap_expand( object_heap_p heap ) +{ + int i; + void *new_heap_index; + int next_free; + int new_heap_size = heap->heap_size + heap->heap_increment; + + new_heap_index = (void *) realloc( heap->heap_index, new_heap_size * heap->object_size ); + if ( NULL == new_heap_index ) + { + return -1; /* Out of memory */ + } + heap->heap_index = new_heap_index; + next_free = heap->next_free; + for(i = new_heap_size; i-- > heap->heap_size; ) + { + object_base_p obj = (object_base_p) (heap->heap_index + i * heap->object_size); + obj->id = i + heap->id_offset; + obj->next_free = next_free; + next_free = i; + } + heap->next_free = next_free; + heap->heap_size = new_heap_size; + return 0; /* Success */ +} + +/* + * Return 0 on success, -1 on error + */ +int object_heap_init( object_heap_p heap, int object_size, int id_offset) +{ + heap->object_size = object_size; + heap->id_offset = id_offset & OBJECT_HEAP_OFFSET_MASK; + heap->heap_size = 0; + heap->heap_increment = 16; + heap->heap_index = NULL; + heap->next_free = LAST_FREE; + return object_heap_expand(heap); +} + +/* + * Allocates an object + * Returns the object ID on success, returns -1 on error + */ +int object_heap_allocate( object_heap_p heap ) +{ + object_base_p obj; + if ( LAST_FREE == heap->next_free ) + { + if( -1 == object_heap_expand( heap ) ) + { + return -1; /* Out of memory */ + } + } + ASSERT( heap->next_free >= 0 ); + + obj = (object_base_p) (heap->heap_index + heap->next_free * heap->object_size); + heap->next_free = obj->next_free; + obj->next_free = ALLOCATED; + return obj->id; +} + +/* + * Lookup an object by object ID + * Returns a pointer to the object on success, returns NULL on error + */ +object_base_p object_heap_lookup( object_heap_p heap, int id ) +{ + object_base_p obj; + if ( (id < heap->id_offset) || (id > (heap->heap_size+heap->id_offset)) ) + { + return NULL; + } + id &= OBJECT_HEAP_ID_MASK; + obj = (object_base_p) (heap->heap_index + id * heap->object_size); + + /* Check if the object has in fact been allocated */ + if ( obj->next_free != ALLOCATED ) + { + return NULL; + } + return obj; +} + +/* + * Iterate over all objects in the heap. + * Returns a pointer to the first object on the heap, returns NULL if heap is empty. + */ +object_base_p object_heap_first( object_heap_p heap, object_heap_iterator *iter ) +{ + *iter = -1; + return object_heap_next( heap, iter ); +} + +/* + * Iterate over all objects in the heap. + * Returns a pointer to the next object on the heap, returns NULL if heap is empty. + */ +object_base_p object_heap_next( object_heap_p heap, object_heap_iterator *iter ) +{ + object_base_p obj; + int i = *iter + 1; + while ( i < heap->heap_size) + { + obj = (object_base_p) (heap->heap_index + i * heap->object_size); + if (obj->next_free == ALLOCATED) + { + *iter = i; + return obj; + } + i++; + } + *iter = i; + return NULL; +} + + + +/* + * Frees an object + */ +void object_heap_free( object_heap_p heap, object_base_p obj ) +{ + /* Don't complain about NULL pointers */ + if (NULL != obj) + { + /* Check if the object has in fact been allocated */ + ASSERT( obj->next_free == ALLOCATED ); + + obj->next_free = heap->next_free; + heap->next_free = obj->id & OBJECT_HEAP_ID_MASK; + } +} + +/* + * Destroys a heap, the heap must be empty. + */ +void object_heap_destroy( object_heap_p heap ) +{ + object_base_p obj; + int i; + /* Check if heap is empty */ + for (i = 0; i < heap->heap_size; i++) + { + /* Check if object is not still allocated */ + obj = (object_base_p) (heap->heap_index + i * heap->object_size); + ASSERT( obj->next_free != ALLOCATED ); + } + free(heap->heap_index); + heap->heap_size = 0; + heap->heap_index = NULL; + heap->next_free = LAST_FREE; +} diff --git a/dummy_drv_video/object_heap.h b/dummy_drv_video/object_heap.h new file mode 100644 index 0000000..154fddb --- /dev/null +++ b/dummy_drv_video/object_heap.h @@ -0,0 +1,89 @@ +/* + * 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. + */ + +#ifndef _OBJECT_HEAP_H_ +#define _OBJECT_HEAP_H_ + +#define OBJECT_HEAP_OFFSET_MASK 0x7F000000 +#define OBJECT_HEAP_ID_MASK 0x00FFFFFF + +typedef struct object_base *object_base_p; +typedef struct object_heap *object_heap_p; + +struct object_base { + int id; + int next_free; +}; + +struct object_heap { + int object_size; + int id_offset; + void *heap_index; + int next_free; + int heap_size; + int heap_increment; +}; + +typedef int object_heap_iterator; + +/* + * Return 0 on success, -1 on error + */ +int object_heap_init( object_heap_p heap, int object_size, int id_offset); + +/* + * Allocates an object + * Returns the object ID on success, returns -1 on error + */ +int object_heap_allocate( object_heap_p heap ); + +/* + * Lookup an allocated object by object ID + * Returns a pointer to the object on success, returns NULL on error + */ +object_base_p object_heap_lookup( object_heap_p heap, int id ); + +/* + * Iterate over all objects in the heap. + * Returns a pointer to the first object on the heap, returns NULL if heap is empty. + */ +object_base_p object_heap_first( object_heap_p heap, object_heap_iterator *iter ); + +/* + * Iterate over all objects in the heap. + * Returns a pointer to the next object on the heap, returns NULL if heap is empty. + */ +object_base_p object_heap_next( object_heap_p heap, object_heap_iterator *iter ); + +/* + * Frees an object + */ +void object_heap_free( object_heap_p heap, object_base_p obj ); + +/* + * Destroys a heap, the heap must be empty. + */ +void object_heap_destroy( object_heap_p heap ); + +#endif /* _OBJECT_HEAP_H_ */ diff --git a/libva.pc.in b/libva.pc.in new file mode 100644 index 0000000..d46f53c --- /dev/null +++ b/libva.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libva +Description: Userspace Video Acceleration (VA) interface +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lva +Cflags: -I${includedir} diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..74a6711 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,33 @@ +# 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. + +libva_la_LTLIBRARIES = libva.la +libva_ladir = $(libdir) +libva_la_LDFLAGS = -version-number 0:22:0 -no-undefined +libva_la_LIBADD = -ldl -lX11 -lXext + +libva_la_SOURCES = va_dri.c va.c va_dristr.h + +libvaincludedir = ${includedir} +libvainclude_HEADERS = va.h va_x11.h va_dri.h va_backend.h + +EXTRA_DIST = ChangeLog TODO diff --git a/src/va.c b/src/va.c new file mode 100644 index 0000000..9a3aca5 --- /dev/null +++ b/src/va.c @@ -0,0 +1,1072 @@ +/* + * 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. + */ + +#include "X11/Xlib.h" +#include "va.h" +#include "va_backend.h" + +#include "assert.h" +#include +#include +#include +#include +#include +#include "va_dri.h" + +#define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri" +#define DRIVER_EXTENSION "_drv_video.so" +#define DRIVER_INIT_FUNC "__vaDriverInit_0_23" + +#define CTX(dpy) ((VADriverContextP) dpy ); +#define ASSERT_CONTEXT(dpy) assert( vaDbgContextIsValid(dpy) ) +#define ASSERT assert +#define CHECK_VTABLE(s, ctx, func) if (!va_checkVtable(ctx->vtable.va##func, #func)) s = VA_STATUS_ERROR_UNKNOWN; +#define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN; + +#define TRACE(func) if (va_debug_trace) va_infoMessage("[TR] %s\n", #func); + +static VADriverContextP pDriverContexts = NULL; +static int va_debug_trace = 0; + +static Bool vaDbgContextIsValid(VADriverContextP arg_ctx) +{ + VADriverContextP ctx = pDriverContexts; + + while (ctx) + { + if (ctx == arg_ctx) + { + return True; + } + ctx = ctx->pNext; + } + return False; +} + +VADisplay vaGetDisplay ( + NativeDisplay native_dpy /* implementation specific */ +) +{ + VADisplay dpy = NULL; + VADriverContextP ctx = pDriverContexts; + + while (ctx) + { + if (ctx->x11_dpy == (Display *)native_dpy) + { + dpy = (VADisplay) ctx; + break; + } + ctx = ctx->pNext; + } + + if (!dpy) + { + /* create new entry */ + ctx = (VADriverContextP) calloc(1, sizeof(struct VADriverContext)); + ctx->pNext = pDriverContexts; + ctx->x11_dpy = (Display *) native_dpy; + pDriverContexts = ctx; + dpy = (VADisplay) ctx; + } + + return dpy; +} + +static void va_errorMessage(const char *msg, ...) +{ + va_list args; + + fprintf(stderr, "libva error: "); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +} + +static void va_infoMessage(const char *msg, ...) +{ + va_list args; + + fprintf(stderr, "libva: "); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +} + +static Bool va_checkVtable(void *ptr, char *function) +{ + if (!ptr) + { + va_errorMessage("No valid vtable entry for va%s\n", function); + return False; + } + return True; +} + +static Bool va_checkMaximum(int value, char *variable) +{ + if (!value) + { + va_errorMessage("Failed to define max_%s in init\n", variable); + return False; + } + return True; +} + +static VAStatus va_getDriverName(VADriverContextP ctx, char **driver_name) +{ + VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN; + int direct_capable; + int driver_major; + int driver_minor; + int driver_patch; + Bool result = True; + + *driver_name = NULL; + if (geteuid() == getuid()) + { + /* don't allow setuid apps to use LIBVA_DRIVER_NAME */ + if (getenv("LIBVA_DRIVER_NAME")) + { + /* For easier debugging */ + *driver_name = strdup(getenv("LIBVA_DRIVER_NAME")); + return VA_STATUS_SUCCESS; + } + } + if (result) + { + result = VA_DRIQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen, &direct_capable); + if (!result) + { + va_errorMessage("VA_DRIQueryDirectRenderingCapable failed\n"); + } + } + if (result) + { + result = direct_capable; + if (!result) + { + va_errorMessage("VA_DRIQueryDirectRenderingCapable returned false\n"); + } + } + if (result) + { + result = VA_DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, &driver_major, &driver_minor, + &driver_patch, driver_name); + if (!result) + { + va_errorMessage("VA_DRIGetClientDriverName returned false\n"); + } + } + if (result) + { + vaStatus = VA_STATUS_SUCCESS; + va_infoMessage("VA_DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", + driver_major, driver_minor, driver_patch, *driver_name, ctx->x11_screen); + } + + return vaStatus; +} + +static VAStatus va_openDriver(VADriverContextP ctx, char *driver_name) +{ + VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN; + char *search_path; + char *saveptr; + char *driver_dir; + + if (geteuid() == getuid()) + { + /* 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) + { + search_path = DEFAULT_DRIVER_DIR; + } + + search_path = strdup(search_path); + driver_dir = strtok_r(search_path, ":", &saveptr); + while(driver_dir) + { + void *handle = NULL; + char *driver_path = (char *) malloc( strlen(driver_dir) + + strlen(driver_name) + + strlen(DRIVER_EXTENSION) + 2 ); + strcpy( driver_path, driver_dir ); + strcat( driver_path, "/" ); + strcat( driver_path, driver_name ); + strcat( driver_path, DRIVER_EXTENSION ); + + va_infoMessage("Trying to open %s\n", driver_path); + + handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL ); + if (!handle) + { + /* Don't give errors for non-existing files */ + if (0 == access( driver_path, F_OK)) + { + va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror()); + } + } + else + { + VADriverInit init_func; + init_func = (VADriverInit) dlsym(handle, DRIVER_INIT_FUNC); + if (!init_func) + { + va_errorMessage("%s has no function %s\n", driver_path, DRIVER_INIT_FUNC); + dlclose(handle); + } + else + { + vaStatus = (*init_func)(ctx); + + if (VA_STATUS_SUCCESS == vaStatus) + { + CHECK_MAXIMUM(vaStatus, ctx, profiles); + CHECK_MAXIMUM(vaStatus, ctx, entrypoints); + CHECK_MAXIMUM(vaStatus, ctx, attributes); + CHECK_MAXIMUM(vaStatus, ctx, image_formats); + CHECK_MAXIMUM(vaStatus, ctx, subpic_formats); + CHECK_VTABLE(vaStatus, ctx, Terminate); + CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles); + CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints); + CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes); + CHECK_VTABLE(vaStatus, ctx, CreateConfig); + CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes); + CHECK_VTABLE(vaStatus, ctx, CreateSurfaces); + CHECK_VTABLE(vaStatus, ctx, DestroySurface); + CHECK_VTABLE(vaStatus, ctx, CreateContext); + CHECK_VTABLE(vaStatus, ctx, DestroyContext); + CHECK_VTABLE(vaStatus, ctx, CreateBuffer); + CHECK_VTABLE(vaStatus, ctx, BufferData); + CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements); + CHECK_VTABLE(vaStatus, ctx, MapBuffer); + CHECK_VTABLE(vaStatus, ctx, UnmapBuffer); + CHECK_VTABLE(vaStatus, ctx, DestroyBuffer); + CHECK_VTABLE(vaStatus, ctx, BeginPicture); + CHECK_VTABLE(vaStatus, ctx, RenderPicture); + CHECK_VTABLE(vaStatus, ctx, EndPicture); + CHECK_VTABLE(vaStatus, ctx, SyncSurface); + CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus); + CHECK_VTABLE(vaStatus, ctx, PutSurface); + CHECK_VTABLE(vaStatus, ctx, CopySurfaceToGLXPbuffer); + CHECK_VTABLE(vaStatus, ctx, QueryImageFormats); + CHECK_VTABLE(vaStatus, ctx, CreateImage); + CHECK_VTABLE(vaStatus, ctx, DestroyImage); + CHECK_VTABLE(vaStatus, ctx, GetImage); + CHECK_VTABLE(vaStatus, ctx, PutImage); + CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats); + CHECK_VTABLE(vaStatus, ctx, CreateSubpicture); + CHECK_VTABLE(vaStatus, ctx, DestroySubpicture); + CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage); + CHECK_VTABLE(vaStatus, ctx, SetSubpicturePalette); + CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey); + CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha); + CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture); + CHECK_VTABLE(vaStatus, ctx, DbgCopySurfaceToBuffer); + } + if (VA_STATUS_SUCCESS != vaStatus) + { + va_errorMessage("%s init failed\n", driver_path); + dlclose(handle); + } + if (VA_STATUS_SUCCESS == vaStatus) + { + ctx->handle = handle; + } + free(driver_path); + break; + } + } + free(driver_path); + + driver_dir = strtok_r(NULL, ":", &saveptr); + } + + free(search_path); + + return vaStatus; +} + + +/* + * Returns a short english description of error_status + */ +const char *vaErrorStr(VAStatus error_status) +{ + switch(error_status) + { + case VA_STATUS_SUCCESS: + return "success (no error)"; + case VA_STATUS_ERROR_ALLOCATION_FAILED: + return "resource allocation failed"; + case VA_STATUS_ERROR_INVALID_CONFIG: + return "invalid VAConfigID"; + case VA_STATUS_ERROR_INVALID_CONTEXT: + return "invalid VAContextID"; + case VA_STATUS_ERROR_INVALID_SURFACE: + return "invalid VASurfaceID"; + case VA_STATUS_ERROR_INVALID_BUFFER: + return "invalid VABufferID"; + case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED: + return "attribute not supported"; + case VA_STATUS_ERROR_MAX_NUM_EXCEEDED: + return "list argument exceeds maximum number"; + case VA_STATUS_ERROR_UNSUPPORTED_PROFILE: + return "the requested VAProfile is not supported"; + case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT: + return "the requested VAEntryPoint is not supported"; + case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT: + return "the requested RT Format is not supported"; + case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE: + return "the requested VABufferType is not supported"; + case VA_STATUS_ERROR_UNKNOWN: + return "unknown libva error"; + } + return "unknown libva error / description missing"; +} + +VAStatus vaInitialize ( + VADisplay dpy, + int *major_version, /* out */ + int *minor_version /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + char *driver_name = NULL; + VAStatus vaStatus; + + ASSERT_CONTEXT(ctx); + + va_debug_trace = (getenv("LIBVA_DEBUG_TRACE") != NULL); + + vaStatus = va_getDriverName(ctx, &driver_name); + va_infoMessage("va_getDriverName() returns %d\n", vaStatus); + + if (VA_STATUS_SUCCESS == vaStatus) + { + vaStatus = va_openDriver(ctx, driver_name); + va_infoMessage("va_openDriver() returns %d\n", vaStatus); + + *major_version = ctx->version_major; + *minor_version = ctx->version_minor; + } + + if (driver_name) + { + XFree(driver_name); + } + return vaStatus; +} + + +/* + * After this call, all library internal resources will be cleaned up + */ +VAStatus vaTerminate ( + VADisplay dpy +) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VADriverContextP old_ctx = CTX(dpy); + ASSERT_CONTEXT(old_ctx); + + if (old_ctx->handle) + { + vaStatus = old_ctx->vtable.vaTerminate(old_ctx); + dlclose(old_ctx->handle); + old_ctx->handle = NULL; + } + + if (VA_STATUS_SUCCESS == vaStatus) + { + VADriverContextP *ctx = &pDriverContexts; + + /* Throw away old_ctx */ + while (*ctx) + { + if (*ctx == old_ctx) + { + *ctx = old_ctx->pNext; + old_ctx->pNext = NULL; + break; + } + ctx = &((*ctx)->pNext); + } + free(old_ctx); + } + return vaStatus; +} + +/* Get maximum number of profiles supported by the implementation */ +int vaMaxNumProfiles ( + VADisplay dpy +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + return ctx->max_profiles; +} + +/* Get maximum number of entrypoints supported by the implementation */ +int vaMaxNumEntrypoints ( + VADisplay dpy +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + return ctx->max_entrypoints; +} + + +/* Get maximum number of attributs supported by the implementation */ +int vaMaxNumConfigAttributes ( + VADisplay dpy +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + return ctx->max_attributes; +} + +VAStatus vaQueryConfigEntrypoints ( + VADisplay dpy, + VAProfile profile, + VAEntrypoint *entrypoints, /* out */ + int *num_entrypoints /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaQueryConfigEntrypoints); + return ctx->vtable.vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints); +} + +VAStatus vaQueryConfigAttributes ( + VADisplay dpy, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, /* in/out */ + int num_attribs +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaQueryConfigAttributes); + return ctx->vtable.vaQueryConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs ); +} + +VAStatus vaQueryConfigProfiles ( + VADisplay dpy, + VAProfile *profile_list, /* out */ + int *num_profiles /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaQueryConfigProfiles); + return ctx->vtable.vaQueryConfigProfiles ( ctx, profile_list, num_profiles ); +} + +VAStatus vaCreateConfig ( + VADisplay dpy, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, + int num_attribs, + VAConfigID *config_id /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaCreateConfig); + return ctx->vtable.vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id ); +} + +VAStatus vaGetConfigAttributes ( + VADisplay dpy, + VAConfigID config_id, + VAProfile *profile, /* out */ + VAEntrypoint *entrypoint, /* out */ + VAConfigAttrib *attrib_list,/* out */ + int *num_attribs /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaGetConfigAttributes); + return ctx->vtable.vaGetConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs); +} + +VAStatus vaCreateSurfaces ( + VADisplay dpy, + int width, + int height, + int format, + int num_surfaces, + VASurface *surfaces /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaCreateSurfaces); + return ctx->vtable.vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces ); +} + +VAStatus vaDestroySurface ( + VADisplay dpy, + VASurface *surface_list, + int num_surfaces +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaDestroySurface); + return ctx->vtable.vaDestroySurface( ctx, surface_list, num_surfaces ); +} + +VAStatus vaCreateContext ( + VADisplay dpy, + VAConfigID config_id, + int picture_width, + int picture_height, + int flag, + VASurface *render_targets, + int num_render_targets, + VAContext *context /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaCreateContext); + return ctx->vtable.vaCreateContext( ctx, config_id, picture_width, picture_height, + flag, render_targets, num_render_targets, context ); +} + +VAStatus vaDestroyContext ( + VADisplay dpy, + VAContext *context +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaDestroyContext); + return ctx->vtable.vaDestroyContext( ctx, context ); +} + +VAStatus vaCreateBuffer ( + VADisplay dpy, + VABufferType type, /* in */ + VABufferID *buf_id /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaCreateBuffer); + return ctx->vtable.vaCreateBuffer( ctx, type, buf_id); +} + +VAStatus vaBufferData ( + VADisplay dpy, + VABufferID buf_id, /* in */ + unsigned int size, /* in */ + unsigned int num_elements, /* in */ + void *data /* in */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaBufferData); + return ctx->vtable.vaBufferData( ctx, buf_id, size, num_elements, data); +} + +VAStatus vaBufferSetNumElements ( + VADisplay dpy, + VABufferID buf_id, /* in */ + unsigned int num_elements /* in */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaBufferSetNumElements); + return ctx->vtable.vaBufferSetNumElements( ctx, buf_id, num_elements ); +} + + +VAStatus vaMapBuffer ( + VADisplay dpy, + VABufferID buf_id, /* in */ + void **pbuf /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaMapBuffer); + return ctx->vtable.vaMapBuffer( ctx, buf_id, pbuf ); +} + +VAStatus vaUnmapBuffer ( + VADisplay dpy, + VABufferID buf_id /* in */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaUnmapBuffer); + return ctx->vtable.vaUnmapBuffer( ctx, buf_id ); +} + +VAStatus vaDestroyBuffer ( + VADisplay dpy, + VABufferID buffer_id +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaDestroyBuffer); + return ctx->vtable.vaDestroyBuffer( ctx, buffer_id ); +} + +VAStatus vaBeginPicture ( + VADisplay dpy, + VAContext *context, + VASurface *render_target +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaBeginPicture); + return ctx->vtable.vaBeginPicture( ctx, context, render_target ); +} + +VAStatus vaRenderPicture ( + VADisplay dpy, + VAContext *context, + VABufferID *buffers, + int num_buffers +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaRenderPicture); + return ctx->vtable.vaRenderPicture( ctx, context, buffers, num_buffers ); +} + +VAStatus vaEndPicture ( + VADisplay dpy, + VAContext *context +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaEndPicture); + return ctx->vtable.vaEndPicture( ctx, context ); +} + +VAStatus vaSyncSurface ( + VADisplay dpy, + VAContext *context, + VASurface *render_target +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaSyncSurface); + return ctx->vtable.vaSyncSurface( ctx, context, render_target ); +} + +VAStatus vaQuerySurfaceStatus ( + VADisplay dpy, + VAContext *context, + VASurface *render_target, + VASurfaceStatus *status /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaQuerySurfaceStatus); + return ctx->vtable.vaQuerySurfaceStatus( ctx, context, render_target, status ); +} + +VAStatus vaPutSurface ( + VADisplay dpy, + VASurface *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 */ + int flags /* de-interlacing flags */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaPutSurface); + return ctx->vtable.vaPutSurface( ctx, surface, draw, srcx, srcy, srcw, srch, + destx, desty, destw, desth, + cliprects, number_cliprects, flags ); +} + +VAStatus vaCopySurfaceToGLXPbuffer ( + VADisplay dpy, + VASurface *surface, + XID pbuffer_id, + short srcx, + short srcy, + unsigned short width, + unsigned short height, + short destx, + short desty, + unsigned int draw_buffer, + unsigned int flags /* de-interlacing flags */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaCopySurfaceToGLXPbuffer); + return ctx->vtable.vaCopySurfaceToGLXPbuffer( ctx, surface, pbuffer_id, + srcx,srcy,width, height,destx,desty, + draw_buffer, flags ); +} + +/* Get maximum number of image formats supported by the implementation */ +int vaMaxNumImageFormats ( + VADisplay dpy +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + return ctx->max_image_formats; +} + +VAStatus vaQueryImageFormats ( + VADisplay dpy, + VAImageFormat *format_list, /* out */ + int *num_formats /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaQueryImageFormats); + return ctx->vtable.vaQueryImageFormats ( ctx, format_list, num_formats); +} + +/* + * The width and height fields returned in the VAImage structure may get + * enlarged for some YUV formats. The size of the data buffer that needs + * to be allocated will be given in the "data_size" field in VAImage. + * Image data is not allocated by this function. The client should + * allocate the memory and fill in the VAImage structure's data field + * after looking at "data_size" returned from the library. + */ +VAStatus vaCreateImage ( + VADisplay dpy, + VAImageFormat *format, + int width, + int height, + VAImage *image /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaCreateImage); + return ctx->vtable.vaCreateImage ( ctx, format, width, height, image); +} + +/* + * Should call DestroyImage before destroying the surface it is bound to + */ +VAStatus vaDestroyImage ( + VADisplay dpy, + VAImage *image +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaDestroyImage); + return ctx->vtable.vaDestroyImage ( ctx, image); +} + +/* + * Retrieve surface data into a VAImage + * Image must be in a format supported by the implementation + */ +VAStatus vaGetImage ( + VADisplay dpy, + VASurface *surface, + int x, /* coordinates of the upper left source pixel */ + int y, + unsigned int width, /* width and height of the region */ + unsigned int height, + VAImage *image +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaGetImage); + return ctx->vtable.vaGetImage ( ctx, surface, x, y, width, height, image); +} + +/* + * Copy data from a VAImage to a surface + * Image must be in a format supported by the implementation + */ +VAStatus vaPutImage ( + VADisplay dpy, + VASurface *surface, + VAImage *image, + int src_x, + int src_y, + unsigned int width, + unsigned int height, + int dest_x, + int dest_y +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaPutImage); + return ctx->vtable.vaPutImage ( ctx, surface, image, src_x, src_y, width, height, dest_x, dest_y ); +} + +/* Get maximum number of subpicture formats supported by the implementation */ +int vaMaxNumSubpictureFormats ( + VADisplay dpy +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + return ctx->max_subpic_formats; +} + +/* + * Query supported subpicture formats + * The caller must provide a "format_list" array that can hold at + * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag + * for each format to indicate additional capabilities for that format. The actual + * number of formats returned in "format_list" is returned in "num_formats". + */ +VAStatus vaQuerySubpictureFormats ( + VADisplay dpy, + VAImageFormat *format_list, /* out */ + unsigned int *flags, /* out */ + unsigned int *num_formats /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaQuerySubpictureFormats); + return ctx->vtable.vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats); +} + +/* + * Subpictures are created with an image associated. + */ +VAStatus vaCreateSubpicture ( + VADisplay dpy, + VAImage *image, + VASubpicture *subpicture /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaCreateSubpicture); + return ctx->vtable.vaCreateSubpicture ( ctx, image, subpicture ); +} + +/* + * Destroy the subpicture before destroying the image it is assocated to + */ +VAStatus vaDestroySubpicture ( + VADisplay dpy, + VASubpicture *subpicture +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaDestroySubpicture); + return ctx->vtable.vaDestroySubpicture ( ctx, subpicture); +} + +VAStatus vaSetSubpictureImage ( + VADisplay dpy, + VASubpicture *subpicture, + VAImage *image +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaSetSubpictureImage); + return ctx->vtable.vaSetSubpictureImage ( ctx, subpicture, image); +} + + +VAStatus vaSetSubpicturePalette ( + VADisplay dpy, + VASubpicture *subpicture, + /* + * pointer to an array holding the palette data. The size of the array is + * num_palette_entries * entry_bytes in size. The order of the components + * in the palette is described by the component_order in VASubpicture struct + */ + unsigned char *palette +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaSetSubpicturePalette); + return ctx->vtable.vaSetSubpicturePalette ( ctx, subpicture, palette); +} + +/* + * If chromakey is enabled, then the area where the source value falls within + * the chromakey [min, max] range is transparent + */ +VAStatus vaSetSubpictureChromakey ( + VADisplay dpy, + VASubpicture *subpicture, + unsigned int chromakey_min, + unsigned int chromakey_max +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaSetSubpictureChromakey); + return ctx->vtable.vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max ); +} + + +/* + * Global alpha value is between 0 and 1. A value of 1 means fully opaque and + * a value of 0 means fully transparent. If per-pixel alpha is also specified then + * the overall alpha is per-pixel alpha multiplied by the global alpha + */ +VAStatus vaSetSubpictureGlobalAlpha ( + VADisplay dpy, + VASubpicture *subpicture, + float global_alpha +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaSetSubpictureGlobalAlpha); + return ctx->vtable.vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha ); +} + +/* + vaAssociateSubpicture associates the subpicture with the target_surface. + It defines the region mapping between the subpicture and the target + surface through source and destination rectangles (with the same width and height). + Both will be displayed at the next call to vaPutSurface. Additional + associations before the call to vaPutSurface simply overrides the association. +*/ +VAStatus vaAssociateSubpicture ( + VADisplay dpy, + VASurface *target_surface, + VASubpicture *subpicture, + short src_x, /* upper left offset in subpicture */ + short src_y, + short dest_x, /* upper left offset in surface */ + short dest_y, + unsigned short width, + unsigned short height, + /* + * whether to enable chroma-keying or global-alpha + * see VA_SUBPICTURE_XXX values + */ + unsigned int flags +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaAssociateSubpicture); + return ctx->vtable.vaAssociateSubpicture ( ctx, target_surface, subpicture, src_x, src_y, dest_x, dest_y, width, height, flags ); +} + + +VAStatus vaDbgCopySurfaceToBuffer(VADisplay dpy, + VASurface *surface, + void **buffer, /* out */ + unsigned int *stride /* out */ +) +{ + VADriverContextP ctx = CTX(dpy); + ASSERT_CONTEXT(ctx); + + TRACE(vaDbgCopySurfaceToBuffer); + return ctx->vtable.vaDbgCopySurfaceToBuffer( ctx, surface, buffer, stride ); +} + diff --git a/src/va.h b/src/va.h new file mode 100755 index 0000000..2343412 --- /dev/null +++ b/src/va.h @@ -0,0 +1,1487 @@ +/* + * 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 API Specification + * + * Rev. 0.23 + * + * + * Revision History: + * rev 0.10 (12/10/2006 Jonathan Bian) - Initial draft + * rev 0.11 (12/15/2006 Jonathan Bian) - Fixed some errors + * rev 0.12 (02/05/2007 Jonathan Bian) - Added VC-1 data structures for slice level decode + * rev 0.13 (02/28/2007 Jonathan Bian) - Added GetDisplay() + * rev 0.14 (04/13/2007 Jonathan Bian) - Fixed MPEG-2 PictureParameter structure, cleaned up a few funcs. + * rev 0.15 (04/20/2007 Jonathan Bian) - Overhauled buffer management + * rev 0.16 (05/02/2007 Jonathan Bian) - Added error codes and fixed some issues with configuration + * rev 0.17 (05/07/2007 Jonathan Bian) - Added H.264/AVC data structures for slice level decode. + * rev 0.18 (05/14/2007 Jonathan Bian) - Added data structures for MPEG-4 slice level decode + * and MPEG-2 motion compensation. + * rev 0.19 (08/06/2007 Jonathan Bian) - Removed extra type for bitplane data. + * rev 0.20 (08/08/2007 Jonathan Bian) - Added missing fields to VC-1 PictureParameter structure. + * rev 0.21 (08/20/2007 Jonathan Bian) - Added image and subpicture support. + * rev 0.22 (08/27/2007 Jonathan Bian) - Added support for chroma-keying and global alpha. + * rev 0.23 (09/07/2007 Jonathan Bian) - Fixed some issues with images and subpictures. + * + * Acknowledgements: + * Some concepts borrowed from XvMC and XvImage. + * Thanks to Waldo Bastian for many valuable feedbacks. + */ +#ifndef _VA_H_ +#define _VA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +Overview + +This is currently a decode only interface (with some rendering support). + +The basic operation steps are: + +- Negotiate a mutually acceptable configuration with the server to lock + down profile, entrypoints, and other attributes that will not change on + a frame-by-frame basis. +- Create a decode context which represents a "virtualized" hardware decode + device +- Get and fill decode buffers with picture level, slice level and macroblock + level data (depending on entrypoints) +- Pass the decode buffers to the server to decode the current frame + +Initialization & Configuration Management + +- Find out supported profiles +- Find out entrypoints for a given profile +- Find out configuration attributes for a given profile/entrypoint pair +- Create a configuration for use by the decoder + +*/ + +typedef void* VADisplay; /* window system dependent */ + +typedef int VAStatus; /* Return status type from functions */ +/* Values for the return status */ +#define VA_STATUS_SUCCESS 0x00000000 +#define VA_STATUS_ERROR_ALLOCATION_FAILED 0x00000001 +#define VA_STATUS_ERROR_INVALID_CONFIG 0x00000002 +#define VA_STATUS_ERROR_INVALID_CONTEXT 0x00000003 +#define VA_STATUS_ERROR_INVALID_SURFACE 0x00000004 +#define VA_STATUS_ERROR_INVALID_BUFFER 0x00000005 +#define VA_STATUS_ERROR_ATTR_NOT_SUPPORTED 0x00000006 /* Todo: Remove */ +#define VA_STATUS_ERROR_MAX_NUM_EXCEEDED 0x00000007 +#define VA_STATUS_ERROR_UNSUPPORTED_PROFILE 0x00000008 +#define VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT 0x00000009 +#define VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT 0x0000000a +#define VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE 0x0000000b +#define VA_STATUS_ERROR_UNKNOWN 0xFFFFFFFF + +/* + * Returns a short english description of error_status + */ +const char *vaErrorStr(VAStatus error_status); + +/* + * Initialization: + * A display must be obtained by calling vaGetDisplay() before calling + * vaInitialize() and other functions. This connects the API to the + * native window system. + * For X Windows, native_dpy would be from XOpenDisplay() + */ +typedef void* NativeDisplay; /* window system dependent */ + +VADisplay vaGetDisplay ( + NativeDisplay native_dpy /* implementation specific */ +); + +VAStatus vaInitialize ( + VADisplay dpy, + int *major_version, /* out */ + int *minor_version /* out */ +); + +/* + * After this call, all library internal resources will be cleaned up + */ +VAStatus vaTerminate ( + VADisplay dpy +); + +/* Currently defined profiles */ +typedef enum +{ + VAProfileMPEG2Simple = 0, + VAProfileMPEG2Main = 1, + VAProfileMPEG4Simple = 2, + VAProfileMPEG4AdvancedSimple = 3, + VAProfileMPEG4Main = 4, + VAProfileH264Baseline = 5, + VAProfileH264Main = 6, + VAProfileH264High = 7, + VAProfileVC1Simple = 8, + VAProfileVC1Main = 9, + VAProfileVC1Advanced = 10, +} VAProfile; + +/* + * Currently defined entrypoints + */ +typedef enum +{ + VAEntrypointVLD = 1, + VAEntrypointIZZ = 2, + VAEntrypointIDCT = 3, + VAEntrypointMoComp = 4, + VAEntrypointDeblocking = 5, +} VAEntrypoint; + +/* Currently defined configuration attribute types */ +typedef enum +{ + VAConfigAttribRTFormat = 0, + VAConfigAttribSpatialResidual = 1, + VAConfigAttribSpatialClipping = 2, + VAConfigAttribIntraResidual = 3, + VAConfigAttribEncryption = 4, +} VAConfigAttribType; + +/* + * Configuration attributes + * If there is more than one value for an attribute, a default + * value will be assigned to the attribute if the client does not + * specify the attribute when creating a configuration + */ +typedef struct _VAConfigAttrib { + VAConfigAttribType type; + unsigned int value; /* OR'd flags (bits) for this attribute */ +} VAConfigAttrib; + +/* attribute value for VAConfigAttribRTFormat */ +#define VA_RT_FORMAT_YUV420 0x00000001 +#define VA_RT_FORMAT_YUV422 0x00000002 +#define VA_RT_FORMAT_YUV444 0x00000004 + +/* + * if an attribute is not applicable for a given + * profile/entrypoint pair, then set the value to the following + */ +#define VA_ATTRIB_NOT_SUPPORTED 0x80000000 + +/* Get maximum number of profiles supported by the implementation */ +int vaMaxNumProfiles ( + VADisplay dpy +); + +/* Get maximum number of entrypoints supported by the implementation */ +int vaMaxNumEntrypoints ( + VADisplay dpy +); + +/* Get maximum number of attributs supported by the implementation */ +int vaMaxNumConfigAttributes ( + VADisplay dpy +); + +/* + * Query supported profiles + * The caller must provide a "profile_list" array that can hold at + * least vaMaxNumProfile() entries. The actual number of profiles + * returned in "profile_list" is returned in "num_profile". + */ +VAStatus vaQueryConfigProfiles ( + VADisplay dpy, + VAProfile *profile_list, /* out */ + int *num_profiles /* out */ +); + +/* + * Query supported entrypoints for a given profile + * The caller must provide an "entrypoint_list" array that can hold at + * least vaMaxNumEntrypoints() entries. The actual number of entrypoints + * returned in "entrypoint_list" is returned in "num_entrypoints". + */ +VAStatus vaQueryConfigEntrypoints ( + VADisplay dpy, + VAProfile profile, + VAEntrypoint *entrypoint_list, /* out */ + int *num_entrypoints /* out */ +); + +/* + * Query attributes for a given profile/entrypoint pair + * The caller must provide an “attrib_list” with all attributes to be + * queried. Upon return, the attributes in “attrib_list” have been + * updated with their value. Unknown attributes or attributes that are + * not supported for the given profile/entrypoint pair will have their + * value set to VA_ATTRIB_NOT_SUPPORTED + */ +VAStatus vaQueryConfigAttributes ( + VADisplay dpy, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, /* in/out */ + int num_attribs +); + +typedef int VAConfigID; + +/* + * Create a configuration for the decode pipeline + * it passes in the attribute list that specifies the attributes it cares + * about, with the rest taking default values. + */ +VAStatus vaCreateConfig ( + VADisplay dpy, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, + int num_attribs, + VAConfigID *config_id /* out */ +); + +/* + * Get all attributes for a given configuration + * The profile of the configuration is returned in “profile” + * The entrypoint of the configuration is returned in “entrypoint” + * The caller must provide an “attrib_list” array that can hold at least + * vaMaxNumConfigAttributes() entries. The actual number of attributes + * returned in “attrib_list” is returned in “num_attribs” + */ +VAStatus vaGetConfigAttributes ( + VADisplay dpy, + VAConfigID config_id, + VAProfile *profile, /* out */ + VAEntrypoint *entrypoint, /* out */ + VAConfigAttrib *attrib_list,/* out */ + int *num_attribs /* out */ +); + + +/* + * Context + * + * Context represents a "virtual" video decode pipeline + */ + +/* generic context ID type, can be re-typed for specific implementation */ +typedef int VAContextID; + +/* generic surface ID type, can be re-typed for specific implementation */ +typedef int VASurfaceID; + +#define VA_INVALID_SURFACE -1 + +typedef struct _VAContext +{ + VAContextID context_id; /* to identify this context */ + VAConfigID config_id; + unsigned short picture_width; + unsigned short picture_height; + VASurfaceID *render_targets; + int num_render_targets; + int flags; + void *privData; +} VAContext; + +/* + flags - Any combination of the following: + VA_PROGRESSIVE (only progressive frame pictures in the sequence when set) +*/ +#define VA_PROGRESSIVE 0x1 + +/* + +Surface Management + +Surfaces are render targets for a given context. The data in the surfaces +are not accessible to the client and the internal data format of +the surface is implementatin specific. + +Question: Is there a need to know the data format (fourcc) or just +differentiate between 420/422/444 is sufficient? + +*/ + +typedef struct _VASurface +{ + VASurfaceID surface_id; /* uniquely identify this surface */ + VAContextID context_id; /* which context does this surface belong */ + unsigned short width; + unsigned short height; + int format; /* 420/422/444 */ + void *privData; /* private to the library */ +} VASurface; + +/* + * Surfaces will be bound to a context when the context is created. Once + * a surface is bound to a given context, it can not be used to create + * another context. The association is removed when the context is destroyed + */ + +/* Surface Functions */ +VAStatus vaCreateSurfaces ( + VADisplay dpy, + int width, + int height, + int format, + int num_surfaces, + VASurface *surfaces /* out */ +); + +/* + * surfaces can only be destroyed after the context associated has been + * destroyed + */ +VAStatus vaDestroySurface ( + VADisplay dpy, + VASurface *surface_list, + int num_surfaces +); + +VAStatus vaCreateContext ( + VADisplay dpy, + VAConfigID config_id, + int picture_width, + int picture_height, + int flag, + VASurface *render_targets, + int num_render_targets, + VAContext *context /* out */ +); + +VAStatus vaDestroyContext ( + VADisplay dpy, + VAContext *context +); + +/* + * + * Buffers + * Buffers are used to pass various types of data from the + * client to the server. The server maintains a data store + * for each buffer created, and the client idenfies a buffer + * through a unique buffer id assigned by the server. + * + */ + +typedef int VABufferID; + +typedef enum +{ + VAPictureParameterBufferType = 0, + VAIQMatrixBufferType = 1, + VABitPlaneBufferType = 2, + VASliceGroupMapBufferType = 3, + VASliceParameterBufferType = 4, + VASliceDataBufferType = 5, + VAMacroblockParameterBufferType = 6, + VAResidualDataBufferType = 7, + VADeblockingParameterBufferType = 8, + VAImageBufferType = 9 +} VABufferType; + +/**************************** + * MPEG-2 data structures + ****************************/ + +/* MPEG-2 Picture Parameter Buffer */ +/* + * For each frame or field, and before any slice data, a single + * picture parameter buffer must be send. + */ +typedef struct _VAPictureParameterBufferMPEG2 +{ + unsigned short horizontal_size; + unsigned short vertical_size; + VASurfaceID forward_reference_picture; + VASurfaceID backward_reference_picture; + /* meanings of the following fields are the same as in the standard */ + int picture_coding_type; + int f_code; /* pack all four fcode into this */ + union { + struct { + unsigned char intra_dc_precision : 2; + unsigned char picture_structure : 2; + unsigned char top_field_first : 1; + unsigned char frame_pred_frame_dct : 1; + unsigned char concealment_motion_vectors : 1; + unsigned char q_scale_type : 1; + unsigned char intra_vlc_format : 1; + unsigned char alternate_scan : 1; + unsigned char repeat_first_field : 1; + unsigned char progressive_frame : 1; + unsigned char is_first_field : 1; /* indicate whether the current field + * is the first field for field picture + */ + }; + unsigned int picture_coding_extension; + }; +} VAPictureParameterBufferMPEG2; + +/* MPEG-2 Inverse Quantization Matrix Buffer */ +typedef struct _VAIQMatrixBufferMPEG2 +{ + int load_intra_quantiser_matrix; + int load_non_intra_quantiser_matrix; + int load_chroma_intra_quantiser_matrix; + int load_chroma_non_intra_quantiser_matrix; + unsigned char intra_quantiser_matrix[64]; + unsigned char non_intra_quantiser_matrix[64]; + unsigned char chroma_intra_quantiser_matrix[64]; + unsigned char chroma_non_intra_quantiser_matrix[64]; +} VAIQMatrixBufferMPEG2; + +/* + * There will be cases where the bitstream buffer will not have enough room to hold + * the data for the entire slice, and the following flags will be used in the slice + * parameter to signal to the server for the possible cases. + * If a slice parameter buffer and slice data buffer pair is sent to the server with + * the slice data partially in the slice data buffer (BEGIN and MIDDLE cases below), + * then a slice parameter and data buffer needs to be sent again to complete this slice. + */ +#define VA_SLICE_DATA_FLAG_ALL 0x00 /* whole slice is in the buffer */ +#define VA_SLICE_DATA_FLAG_BEGIN 0x01 /* The beginning of the slice is in the buffer but the end if not */ +#define VA_SLICE_DATA_FLAG_MIDDLE 0x02 /* Neither beginning nor end of the slice is in the buffer */ +#define VA_SLICE_DATA_FLAG_END 0x04 /* end of the slice is in the buffer */ + +/* MPEG-2 Slice Parameter Buffer */ +typedef struct _VASliceParameterBufferMPEG2 +{ + unsigned int slice_data_size;/* number of bytes in the slice data buffer for this slice */ + unsigned int slice_data_offset;/* the offset to the first byte of slice data */ + unsigned int slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX defintions */ + unsigned int macroblock_offset;/* the offset to the first bit of MB from the first byte of slice data */ + unsigned int slice_vertical_position; + int quantiser_scale_code; + int intra_slice_flag; +} VASliceParameterBufferMPEG2; + +/* MPEG-2 Macroblock Parameter Buffer */ +typedef struct _VAMacroblockParameterBufferMPEG2 +{ + unsigned short macroblock_address; + /* + * macroblock_address (in raster scan order) + * top-left: 0 + * bottom-right: picture-height-in-mb*picture-width-in-mb - 1 + */ + unsigned char macroblock_type; /* see definition below */ + union { + struct { + unsigned char frame_motion_type : 2; + unsigned char field_motion_type : 2; + unsigned char dct_type : 1; + }; + unsigned char macroblock_modes; + }; + unsigned char motion_vertical_field_select; + /* + * motion_vertical_field_select: + * see section 6.3.17.2 in the spec + * only the lower 4 bits are used + * bit 0: first vector forward + * bit 1: first vector backward + * bit 2: second vector forward + * bit 3: second vector backward + */ + short PMV[2][2][2]; /* see Table 7-7 in the spec */ + unsigned short coded_block_pattern; + /* + * The bitplanes for coded_block_pattern are described + * in Figure 6.10-12 in the spec + */ + + /* Number of skipped macroblocks after this macroblock */ + unsigned short num_skipped_macroblocks; +} VAMacroblockParameterBufferMPEG2; + +/* + * OR'd flags for macroblock_type (section 6.3.17.1 in the spec) + */ +#define VA_MB_TYPE_MOTION_FORWARD 0x02 +#define VA_MB_TYPE_MOTION_BACKWARD 0x04 +#define VA_MB_TYPE_MOTION_PATTERN 0x08 +#define VA_MB_TYPE_MOTION_INTRA 0x10 + +/* + * MPEG-2 Residual Data Buffer + * For each macroblock, there wil be 64 shorts (16-bit) in the + * residual data buffer + */ + +/**************************** + * MPEG-4 Part 2 data structures + ****************************/ + +/* MPEG-4 Picture Parameter Buffer */ +/* + * For each frame or field, and before any slice data, a single + * picture parameter buffer must be send. + */ +typedef struct _VAPictureParameterBufferMPEG4 +{ + unsigned short vop_width; + unsigned short vop_height; + VASurfaceID forward_reference_picture; + VASurfaceID backward_reference_picture; + union { + struct { + unsigned char short_video_header : 1; + unsigned char chroma_format : 2; + unsigned char interlaced : 1; + unsigned char obmc_disable : 1; + unsigned char sprite_enable : 2; + unsigned char sprite_warping_accuracy : 2; + unsigned char quant_type : 1; + unsigned char quarter_sample : 1; + unsigned char data_partitioned : 1; + unsigned char reversible_vlc : 1; + }; + unsigned short vol_fields; + }; + unsigned char no_of_sprite_warping_points; + short sprite_trajectory_du[3]; + short sprite_trajectory_dv[3]; + unsigned char quant_precision; + union { + struct { + unsigned char vop_coding_type : 2; + unsigned char backward_reference_vop_coding_type : 2; + unsigned char vop_rounding_type : 1; + unsigned char intra_dc_vlc_thr : 3; + unsigned char top_field_first : 1; + unsigned char alternate_vertical_scan_flag : 1; + }; + unsigned short vop_fields; + }; + unsigned char vop_fcode_forward; + unsigned char vop_fcode_backward; + /* short header related */ + unsigned char num_gobs_in_vop; + unsigned char num_macroblocks_in_gob; + /* for direct mode prediction */ + short TRB; + short TRD; +} VAPictureParameterBufferMPEG4; + +/* MPEG-4 Inverse Quantization Matrix Buffer */ +typedef struct _VAIQMatrixBufferMPEG4 +{ + int load_intra_quant_mat; + int load_non_intra_quant_mat; + unsigned char intra_quant_mat[64]; + unsigned char non_intra_quant_mat[64]; +} VAIQMatrixBufferMPEG4; + +/* MPEG-4 Slice Parameter Buffer */ +typedef struct _VASliceParameterBufferMPEG4 +{ + unsigned int slice_data_size;/* number of bytes in the slice data buffer for this slice */ + unsigned int slice_data_offset;/* the offset to the first byte of slice data */ + unsigned int slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX defintions */ + unsigned int macroblock_offset;/* the offset to the first bit of MB from the first byte of slice data */ + unsigned int macroblock_number; + int quant_scale; +} VASliceParameterBufferMPEG4; + +/* + VC-1 data structures +*/ + +/* VC-1 Picture Parameter Buffer */ +/* + * For each picture, and before any slice data, a picture parameter + * buffer must be send. Multiple picture parameter buffers may be + * sent for a single picture. In that case picture parameters will + * apply to all slice data that follow it until a new picture + * parameter buffer is sent. + * + * Notes: + * pic_quantizer_type should be set to the applicable quantizer + * type as defined by QUANTIZER (J.1.19) and either + * PQUANTIZER (7.1.1.8) or PQINDEX (7.1.1.6) + */ +typedef struct _VAPictureParameterBufferVC1 +{ + VASurfaceID forward_reference_picture; + VASurfaceID backward_reference_picture; + /* if out-of-loop post-processing is done on the render + target, then we need to keep the in-loop decoded + picture as a reference picture */ + VASurfaceID inloop_decoded_picture; + + /* sequence layer for AP or meta data for SP and MP */ + union { + struct { + unsigned char interlace : 1; /* SEQUENCE_LAYER::INTERLACE */ + unsigned char syncmarker : 1;/* METADATA::SYNCMARKER */ + unsigned char overlap : 1;/* METADATA::OVERLAP */ + }; + unsigned char sequence_fields; + }; + + unsigned short coded_width; /* ENTRY_POINT_LAYER::CODED_WIDTH */ + unsigned short coded_height; /* ENTRY_POINT_LAYER::CODED_HEIGHT */ + unsigned char closed_entry; /* ENTRY_POINT_LAYER::CLOSED_ENTRY */ + unsigned char broken_link; /* ENTRY_POINT_LAYER::BROKEN_LINK */ + unsigned char loopfilter; /* ENTRY_POINT_LAYER::LOOPFILTER */ + unsigned char conditional_overlap_flag; /* ENTRY_POINT_LAYER::CONDOVER */ + unsigned char fast_uvmc_flag; /* ENTRY_POINT_LAYER::FASTUVMC */ + union { + struct { + unsigned char range_mapping_luma_flag: 1; /* ENTRY_POINT_LAYER::RANGE_MAPY_FLAG */ + unsigned char range_mapping_luma: 3; /* ENTRY_POINT_LAYER::RANGE_MAPY */ + unsigned char range_mapping_chroma_flag: 1; /* ENTRY_POINT_LAYER::RANGE_MAPUV_FLAG */ + unsigned char range_mapping_chroma: 3; /* ENTRY_POINT_LAYER::RANGE_MAPUV */ + }; + unsigned char range_mapping_fields; + }; + + unsigned char b_picture_fraction; /* PICTURE_LAYER::BFRACTION */ + unsigned char cbp_table; /* PICTURE_LAYER::CBPTAB/ICBPTAB */ + unsigned char mb_mode_table; /* PICTURE_LAYER::MBMODETAB */ + unsigned char range_reduction_frame;/* PICTURE_LAYER::RANGEREDFRM */ + unsigned char rounding_control; /* PICTURE_LAYER::RNDCTRL */ + unsigned char post_processing; /* PICTURE_LAYER::POSTPROC */ + unsigned char picture_resolution_index; /* PICTURE_LAYER::RESPIC */ + unsigned char luma_scale; /* PICTURE_LAYER::LUMSCALE */ + unsigned char luma_shift; /* PICTURE_LAYER::LUMSHIFT */ + union { + struct { + unsigned char picture_type : 2; /* PICTURE_LAYER::PTYPE */ + unsigned char frame_coding_mode : 3;/* PICTURE_LAYER::FCM */ + unsigned char top_field_first : 1;/* PICTURE_LAYER::TFF */ + unsigned char is_first_field : 1; /* set to 1 if it is the first field */ + unsigned char intensity_compensation: 1;/* PICTURE_LAYER::INTCOMP */ + }; + unsigned char picture_fields; + }; + union { + struct { + unsigned char mv_type_mb : 1; /* PICTURE::MVTYPEMB */ + unsigned char direct_mb : 1; /* PICTURE::DIRECTMB */ + unsigned char skip_mb : 1; /* PICTURE::SKIPMB */ + unsigned char field_tx : 1; /* PICTURE::FIELDTX */ + unsigned char foward_mb : 1; /* PICTURE::FORWARDMB */ + unsigned char ac_pred : 1; /* PICTURE::ACPRED */ + unsigned char overflags : 1; /* PICTURE::OVERFLAGS */ + }; + unsigned char raw_coding_flag; + }; + union { + struct { + unsigned char reference_distance_flag : 1;/* PICTURE_LAYER::REFDIST_FLAG */ + unsigned char reference_distance : 1;/* PICTURE_LAYER::REFDIST */ + unsigned char num_reference_pictures: 1;/* PICTURE_LAYER::NUMREF */ + unsigned char reference_field_pic_indicator : 1;/* PICTURE_LAYER::REFFIELD */ + }; + unsigned short reference_fields; + }; + union { + struct { + unsigned char mv_mode : 2; /* PICTURE_LAYER::MVMODE */ + unsigned char mv_mode2 : 2; /* PICTURE_LAYER::MVMODE2 */ + unsigned char mv_table : 3;/* PICTURE_LAYER::MVTAB/IMVTAB */ + unsigned char two_mv_block_pattern_table: 2;/* PICTURE_LAYER::2MVBPTAB */ + unsigned char four_mv_switch: 1; /* PICTURE_LAYER::4MVSWITCH */ + unsigned char four_mv_block_pattern_table : 2;/* PICTURE_LAYER::4MVBPTAB */ + unsigned char extended_mv_flag: 1;/* ENTRY_POINT_LAYER::EXTENDED_MV */ + unsigned char extended_mv_range : 2;/* PICTURE_LAYER::MVRANGE */ + unsigned char extended_dmv_flag : 1;/* ENTRY_POINT_LAYER::EXTENDED_DMV */ + unsigned char extended_dmv_range : 2;/* PICTURE_LAYER::DMVRANGE */ + }; + unsigned int mv_fields; + }; + union { + struct { + unsigned char dquant : 2; /* ENTRY_POINT_LAYER::DQUANT */ + unsigned char half_qp : 1; /* PICTURE_LAYER::HALFQP */ + unsigned char pic_quantizer_scale : 1;/* PICTURE_LAYER::PQUANT */ + unsigned char pic_quantizer_type : 1;/* PICTURE_LAYER::PQUANTIZER */ + unsigned char dq_frame : 1; /* VOPDQUANT::DQUANTFRM */ + unsigned char dq_profile : 2; /* VOPDQUANT::DQPROFILE */ + unsigned char dq_sb_edge : 2; /* VOPDQUANT::DQSBEDGE */ + unsigned char dq_db_edge : 2; /* VOPDQUANT::DQDBEDGE */ + unsigned char dq_binary_level : 1; /* VOPDQUANT::DQBILEVEL */ + unsigned char alt_pic_quantizer : 5;/* VOPDQUANT::ALTPQUANT */ + }; + unsigned long pic_quantizer_fields; + }; + union { + struct { + unsigned char variable_sized_transform_flag : 1;/* ENTRY_POINT_LAYER::VSTRANSFORM */ + unsigned char mb_level_transform_type_flag : 1;/* PICTURE_LAYER::TTMBF */ + unsigned char frame_level_transform_type : 2;/* PICTURE_LAYER::TTFRM */ + unsigned char transform_ac_codingset_idx1 : 2;/* PICTURE_LAYER::TRANSACFRM */ + unsigned char transform_ac_codingset_idx2 : 2;/* PICTURE_LAYER::TRANSACFRM2 */ + unsigned char intra_transform_dc_table : 1;/* PICTURE_LAYER::TRANSDCTAB */ + }; + unsigned short transform_fields; + }; +} VAPictureParameterBufferVC1; + +/* VC-1 Bitplane Buffer +There will be at most three bitplanes coded in any picture header. To send +the bitplane data more efficiently, each byte is divided in two nibbles, with +each nibble carrying three bitplanes for one macroblock. The following table +shows the bitplane data arrangement within each nibble based on the picture +type. + +Picture Type Bit3 Bit2 Bit1 Bit0 +I or BI OVERFLAGS ACPRED FIELDTX +P MYTYPEMB SKIPMB DIRECTMB +B FORWARDMB SKIPMB DIRECTMB + +Within each byte, the lower nibble is for the first MB and the upper nibble is +for the second MB. E.g. the lower nibble of the first byte in the bitplane +buffer is for Macroblock #1 and the upper nibble of the first byte is for +Macroblock #2 in the first row. +*/ + +/* VC-1 Slice Parameter Buffer */ +typedef struct _VASliceParameterBufferVC1 +{ + unsigned int slice_data_size;/* number of bytes in the slice data buffer for this slice */ + unsigned int slice_data_offset;/* the offset to the first byte of slice data */ + unsigned int slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX defintions */ + unsigned int macroblock_offset;/* the offset to the first bit of MB from the first byte of slice data */ + unsigned int slice_vertical_position; +} VASliceParameterBufferVC1; + +/* VC-1 Slice Data Buffer */ +/* +This is simplely a buffer containing raw bit-stream bytes +*/ + +/**************************** + * H.264/AVC data structures + ****************************/ + +typedef struct _VAPictureH264 +{ + VASurfaceID picture_id; + unsigned int flags; + unsigned int TopFieldOrderCnt; + unsigned int BottomFieldOrderCnt; +} VAPictureH264; +/* flags in VAPictureH264 could be OR of the following */ +#define VA_PICTURE_H264_INVALID 0x00000001 +#define VA_PICTURE_H264_TOP_FIELD 0x00000002 +#define VA_PICTURE_H264_BOTTOM_FIELD 0x00000004 +#define VA_PICTURE_H264_SHORT_TERM_REFERENCE 0x00000008 +#define VA_PICTURE_H264_LONG_TERM_REFERENCE 0x00000010 + +/* H.264 Picture Parameter Buffer */ +/* + * For each picture, and before any slice data, a single + * picture parameter buffer must be send. + */ +typedef struct _VAPictureParameterBufferH264 +{ + VAPictureH264 CurrPic; + VAPictureH264 ReferenceFrames[16]; /* in DPB */ + unsigned short picture_width_in_mbs_minus1; + unsigned short picture_height_in_mbs_minus1; + unsigned char bit_depth_luma_minus8; + unsigned char bit_depth_chroma_minus8; + unsigned char num_ref_frames; + union { + struct { + unsigned char chroma_format_idc : 2; + unsigned char residual_colour_transform_flag : 1; + unsigned char frame_mbs_only_flag : 1; + unsigned char mb_adaptive_frame_field_flag : 1; + unsigned char direct_8x8_inference_flag : 1; + unsigned char MinLumaBiPredSize8x8 : 1; /* see A.3.3.2 */ + }; + unsigned char seq_fields; + }; + unsigned char num_slice_groups_minus1; + unsigned char slice_group_map_type; + unsigned char pic_init_qp_minus26; + unsigned char chroma_qp_index_offset; + unsigned char second_chroma_qp_index_offset; + union { + struct { + unsigned char entropy_coding_mode_flag : 1; + unsigned char weighted_pred_flag : 1; + unsigned char weighted_bipred_idc : 1; + unsigned char transform_8x8_mode_flag : 1; + unsigned char field_pic_flag : 1; + unsigned char constrained_intra_pred_flag : 1; + }; + unsigned char pic_fields; + }; + unsigned short frame_num; +} VAPictureParameterBufferH264; + +/* H.264 Inverse Quantization Matrix Buffer */ +typedef struct _VAIQMatrixBufferH264 +{ + unsigned char ScalingList4x4[6][16]; + unsigned char ScalingList8x8[2][64]; +} VAIQMatrixBufferH264; + +/* + * H.264 Slice Group Map Buffer + * When VAPictureParameterBufferH264::num_slice_group_minus1 is not equal to 0, + * A slice group map buffer should be sent for each picture if required. The buffer + * is sent only when there is a change in the mapping values. + * The slice group map buffer map "map units" to slice groups as specified in + * section 8.2.2 of the H.264 spec. The buffer will contain one byte for each macroblock + * in raster scan order + */ + +/* H.264 Slice Parameter Buffer */ +typedef struct _VASliceParameterBufferH264 +{ + unsigned int slice_data_size;/* number of bytes in the slice data buffer for this slice */ + unsigned int slice_data_offset;/* the offset to first byte of slice data */ + unsigned int slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX defintions */ + unsigned short slice_data_bit_offset; /* bit offset in the first byte of valid data */ + unsigned short first_mb_in_slice; + unsigned char slice_type; + unsigned char direct_spatial_mv_pred_flag; + unsigned char num_ref_idx_l0_active_minus1; + unsigned char num_ref_idx_l1_active_minus1; + unsigned char cabac_init_idc; + char slice_qp_delta; + unsigned char disable_deblocking_filter_idc; + char slice_alpha_c0_offset_div2; + char slice_beta_offset_div2; + VAPictureH264 RefPicList0[32]; /* See 8.2.4.2 */ + VAPictureH264 RefPicList1[32]; /* See 8.2.4.2 */ + unsigned char luma_log2_weight_denom; + unsigned char chroma_log2_weight_denom; + unsigned char luma_weight_l0_flag; + short luma_weight_l0[32]; + short luma_offset_l0[32]; + unsigned char chroma_weight_l0_flag; + short chroma_weight_l0[32][2]; + short chroma_offset_l0[32][2]; + unsigned char luma_weight_l1_flag; + short luma_weight_l1[32]; + short luma_offset_l1[32]; + unsigned char chroma_weight_l1_flag; + short chroma_weight_l1[32][2]; + short chroma_offset_l1[32][2]; +} VASliceParameterBufferH264; + +/* Buffer functions */ + +/* + * Creates a buffer for storing a certain type of data, no data store allocated + */ +VAStatus vaCreateBuffer ( + VADisplay dpy, + VABufferType type, /* in */ + VABufferID *buf_id /* out */ +); + +/* + * Create data store for the buffer and initalize with "data". + * if "data" is null, then the contents of the buffer data store + * are undefined. + * Basically there are two ways to get buffer data to the server side. One is + * to call vaBufferData() with a non-null "data", which results the data being + * copied to the data store on the server side. A different method that + * eliminates this copy is to pass null as "data" when calling vaBufferData(), + * and then use vaMapBuffer() to map the data store from the server side to the + * client address space for access. + */ +VAStatus vaBufferData ( + VADisplay dpy, + VABufferID buf_id, /* in */ + unsigned int size, /* in */ + unsigned int num_elements, /* in */ + void *data /* in */ +); + +/* + * Convey to the server how many valid elements are in the buffer. + * e.g. if multiple slice parameters are being held in a single buffer, + * this will communicate to the server the number of slice parameters + * that are valid in the buffer. + */ +VAStatus vaBufferSetNumElements ( + VADisplay dpy, + VABufferID buf_id, /* in */ + unsigned int num_elements /* in */ +); + +/* + * Map data store of the buffer into the client's address space + * vaBufferData() needs to be called with "data" set to NULL before + * calling vaMapBuffer() + */ +VAStatus vaMapBuffer ( + VADisplay dpy, + VABufferID buf_id, /* in */ + void **pbuf /* out */ +); + +/* + * After client making changes to a mapped data store, it needs to + * "Unmap" it to let the server know that the data is ready to be + * consumed by the server + */ +VAStatus vaUnmapBuffer ( + VADisplay dpy, + VABufferID buf_id /* in */ +); + +/* + * After this call, the buffer is deleted and this buffer_id is no longer valid + */ +VAStatus vaDestroyBuffer ( + VADisplay dpy, + VABufferID buffer_id +); + +/* +Render (Decode) Pictures + +A picture represents either a frame or a field. + +The Begin/Render/End sequence sends the decode buffers to the server +*/ + +/* + * Get ready to decode a picture to a target surface + */ +VAStatus vaBeginPicture ( + VADisplay dpy, + VAContext *context, + VASurface *render_target +); + +/* + * Send decode buffers to the server. + */ +VAStatus vaRenderPicture ( + VADisplay dpy, + VAContext *context, + VABufferID *buffers, + int num_buffers +); + +/* + * Make the end of rendering for a picture. + * The server should start processing all pending operations for this + * surface. This call is non-blocking. The client can start another + * Begin/Render/End sequence on a different render target. + */ +VAStatus vaEndPicture ( + VADisplay dpy, + VAContext *context +); + +/* + +Synchronization + +*/ + +/* + * This function blocks until all pending operations on the render target + * have been completed. Upon return it is safe to use the render target for a + * different picture. + */ +VAStatus vaSyncSurface ( + VADisplay dpy, + VAContext *context, + VASurface *render_target +); + +typedef enum +{ + VASurfaceRendering = 0, /* Rendering in progress */ + VASurfaceDisplaying = 1, /* Displaying in progress (not safe to render into it) */ + /* this status is useful if surface is used as the source */ + /* of an overlay */ + VASurfaceReady = 2 /* not being rendered or displayed */ +} VASurfaceStatus; + +/* + * Find out any pending ops on the render target + */ +VAStatus vaQuerySurfaceStatus ( + VADisplay dpy, + VAContext *context, + VASurface *render_target, + VASurfaceStatus *status /* out */ +); + + +/* + * Copies the surface to a buffer + * The stride of the surface will be stored in *stride + * Caller should free the returned buffer with free() when done. + */ +VAStatus vaDbgCopySurfaceToBuffer(VADisplay dpy, + VASurface *surface, + void **buffer, /* out */ + unsigned int *stride /* out */ +); + +/* + * Images and Subpictures + * VAImage is used to either get the surface data to client memory, or + * to copy image data in client memory to a surface. + * Both images, subpictures and surfaces follow the same 2D coordinate system where origin + * is at the upper left corner with positive X to the right and positive Y down + */ +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((unsigned long)(unsigned char) (ch0) | ((unsigned long)(unsigned char) (ch1) << 8) | \ + ((unsigned long)(unsigned char) (ch2) << 16) | ((unsigned long)(unsigned char) (ch3) << 24 )) + +/* a few common FourCCs */ +#define VA_FOURCC_NV12 0x3231564E +#define VA_FOURCC_AI44 0x34344149 +#define VA_FOURCC_RGBA 0x41424752 + +typedef struct _VAImageFormat +{ + unsigned int fourcc; + unsigned int byte_order; /* VA_LSB_FIRST, VA_MSB_FIRST */ + unsigned int bits_per_pixel; + /* for RGB formats */ + unsigned int depth; /* significant bits per pixel */ + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; + unsigned int alpha_mask; +} VAImageFormat; + +typedef int VAImageID; + +typedef struct _VAImage +{ + VAImageID image_id; /* uniquely identify this image */ + VAImageFormat format; + VABufferID buf; /* image data buffer */ + /* + * Image data will be stored in a buffer of type VAImageBufferType to facilitate + * data store on the server side for optimal performance. + * It is expected that the client will first call vaCreateImage which returns a VAImage + * structure with the following fields filled by the library. It will then + * create the "buf" with vaBufferCreate. For PutImage, then client will call + * vaBufferData() with the image data before calling PutImage, and for GetImage + * the client will call vaBufferData() with a NULL data pointer, and then call GetImage. + * After that the client can use the Map/Unmap buffer functions to access the image data. + */ + unsigned short width; + unsigned short height; + unsigned int data_size; + unsigned int num_planes; + /* + * An array of size num_planes indicating the scanline pitch in bytes. + * Each plane may have a different pitch. + */ + unsigned int *pitches; + /* + * An array of size num_planes indicating the byte offset from + * the beginning of the image data to the start of each plane. + */ + unsigned int *offsets; +} VAImage; + +/* Get maximum number of image formats supported by the implementation */ +int vaMaxNumImageFormats ( + VADisplay dpy +); + +/* + * Query supported image formats + * The caller must provide a "format_list" array that can hold at + * least vaMaxNumImageFormats() entries. The actual number of formats + * returned in "format_list" is returned in "num_formats". + */ +VAStatus vaQueryImageFormats ( + VADisplay dpy, + VAImageFormat *format_list, /* out */ + int *num_formats /* out */ +); + +/* + * Create a VAImage structure + * The width and height fields returned in the VAImage structure may get + * enlarged for some YUV formats. The size of the data buffer that needs + * to be allocated will be given in the "data_size" field in VAImage. + * Image data is not allocated by this function. The client should + * allocate the memory required for the data and fill in the data field after + * looking at "data_size" returned from this call. + */ +VAStatus vaCreateImage ( + VADisplay dpy, + VAImageFormat *format, + int width, + int height, + VAImage *image /* out */ +); + +/* + * Should call DestroyImage before destroying the surface it is bound to + */ +VAStatus vaDestroyImage ( + VADisplay dpy, + VAImage *image +); + +/* + * Retrive surface data into a VAImage + * Image must be in a format supported by the implementation + */ +VAStatus vaGetImage ( + VADisplay dpy, + VASurface *surface, + int x, /* coordinates of the upper left source pixel */ + int y, + unsigned int width, /* width and height of the region */ + unsigned int height, + VAImage *image +); + +/* + * Copy data from a VAImage to a surface + * Image must be in a format supported by the implementation + */ +VAStatus vaPutImage ( + VADisplay dpy, + VASurface *surface, + VAImage *image, + int src_x, + int src_y, + unsigned int width, + unsigned int height, + int dest_x, + int dest_y +); + +/* + * Subpictures + * Subpicture is a special type of image that can be blended + * with a surface during vaPutSurface(). Subpicture can be used to render + * DVD sub-titles or closed captioning text etc. + */ + +typedef int VASubpictureID; + +typedef struct _VASubpicture +{ + VASubpictureID subpicture_id; /* uniquely identify this subpicture */ + VASurfaceID surface_id; /* which surface does this subpicture associate with */ + VAImageID image_id; + /* The following fields are set by the library */ + int num_palette_entries; /* paletted formats only. set to zero for image without palettes */ + /* + * Each component is one byte and entry_bytes indicates the number of components in + * each entry (eg. 3 for YUV palette entries). set to zero for image without palettes + */ + int entry_bytes; + /* + * An array of ascii characters describing teh order of the components within the bytes. + * Only entry_bytes characters of the string are used. + */ + char component_order[4]; + + /* chromakey range */ + unsigned int chromakey_min; + unsigned int chromakey_max; + + /* global alpha */ + unsigned int global_alpha; + + /* flags */ + unsigned int flags; /* see below */ +} VASubpicture; + +/* flags for subpictures */ +#define VA_SUBPICTURE_CHROMA_KEYING 0x0001 +#define VA_SUBPICTURE_GLOBAL_ALPHA 0x0002 + +/* Get maximum number of subpicture formats supported by the implementation */ +int vaMaxNumSubpictureFormats ( + VADisplay dpy +); + +/* + * Query supported subpicture formats + * The caller must provide a "format_list" array that can hold at + * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag + * for each format to indicate additional capabilities for that format. The actual + * number of formats returned in "format_list" is returned in "num_formats". + */ +VAStatus vaQuerySubpictureFormats ( + VADisplay dpy, + VAImageFormat *format_list, /* out */ + unsigned int *flags, /* out */ + unsigned int *num_formats /* out */ +); + +/* + * Subpictures are created with an image associated. + */ +VAStatus vaCreateSubpicture ( + VADisplay dpy, + VAImage *image, + VASubpicture *subpicture /* out */ +); + +/* + * Destroy the subpicture before destroying the image it is assocated to + */ +VAStatus vaDestroySubpicture ( + VADisplay dpy, + VASubpicture *subpicture +); + +/* + * Bind an image to the subpicture. This image will now be associated with + * the subpicture instead of the one at creation. + */ +VAStatus vaSetSubpictureImage ( + VADisplay dpy, + VASubpicture *subpicture, + VAImage *image +); + +VAStatus vaSetSubpicturePalette ( + VADisplay dpy, + VASubpicture *subpicture, + /* + * pointer to an array holding the palette data. The size of the array is + * num_palette_entries * entry_bytes in size. The order of the components + * in the palette is described by the component_order in VASubpicture struct + */ + unsigned char *palette +); + +/* + * If chromakey is enabled, then the area where the source value falls within + * the chromakey [min, max] range is transparent + */ +VAStatus vaSetSubpictureChromakey ( + VADisplay dpy, + VASubpicture *subpicture, + unsigned int chromakey_min, + unsigned int chromakey_max +); + +/* + * Global alpha value is between 0 and 1. A value of 1 means fully opaque and + * a value of 0 means fully transparent. If per-pixel alpha is also specified then + * the overall alpha is per-pixel alpha multiplied by the global alpha + */ +VAStatus vaSetSubpictureGlobalAlpha ( + VADisplay dpy, + VASubpicture *subpicture, + float global_alpha +); + +/* + vaAssociateSubpicture associates the subpicture with the target_surface. + It defines the region mapping between the subpicture and the target + surface through source and destination rectangles (with the same width and height). + Both will be displayed at the next call to vaPutSurface. Additional + associations before the call to vaPutSurface simply overrides the association. +*/ +VAStatus vaAssociateSubpicture ( + VADisplay dpy, + VASurface *target_surface, + VASubpicture *subpicture, + short src_x, /* upper left offset in subpicture */ + short src_y, + short dest_x, /* upper left offset in surface */ + short dest_y, + unsigned short width, + unsigned short height, + /* + * whether to enable chroma-keying or global-alpha + * see VA_SUBPICTURE_XXX values + */ + unsigned int flags +); + +typedef struct _VARectangle +{ + short x; + short y; + unsigned short width; + unsigned short height; +} VARectangle; + +#ifdef __cplusplus +} +#endif + +#endif /* _VA_H_ */ + +#if 0 +/*****************************************************************************/ + +Sample Program (w/ pseudo code) + +Mostly to demonstrate program flow with no error handling ... + +/*****************************************************************************/ + + /* MPEG-2 VLD decode for a 720x480 frame */ + + int major_ver, minor_ver; + vaInitialize(dpy, &major_ver, &minor_ver); + + int max_num_profiles, max_num_entrypoints, max_num_attribs; + max_num_profiles = vaMaxNumProfiles(dpy); + max_num_entrypoints = vaMaxNumProfiles(dpy); + max_num_attribs = vaMaxNumProfiles(dpy); + + /* find out whether MPEG2 MP is supported */ + VAProfile *profiles = malloc(sizeof(VAProfile)*max_num_profiles); + int num_profiles; + vaQueryConfigProfiles(dpy, profiles, &profiles); + /* + * traverse "profiles" to locate the one that matches VAProfileMPEG2Main + */ + + /* now get the available entrypoints for MPEG2 MP */ + VAEntrypoint *entrypoints = malloc(sizeof(VAEntrypoint)*max_num_entrypoints); + int num_entrypoints; + vaQueryConfigEntrypoints(dpy, VAProfileMPEG2Main, entrypoints, &num_entrypoints); + + /* traverse "entrypoints" to see whether VLD is there */ + + /* Assuming finding VLD, find out the format for the render target */ + VAConfigAttrib attrib; + attrib.type = VAConfigAttribRTFormat; + vaQueryConfigAttributes(dpy, VAProfileMPEG2Main, VAEntrypointVLD, + &attrib, 1); + + if (attrib.value & VA_RT_FORMAT_YUV420) + /* Found desired RT format, keep going */ + + VAConfigID config_id; + vaCreateConfig(dpy, VAProfileMPEG2Main, VAEntrypointVLD, &attrib, 1, + &config_id); + + /* + * create surfaces for the current target as well as reference frames + * we can get by with 4 surfaces for MPEG-2 + */ + VASurface surfaces[4]; + vaCreateSurfaces(dpy, 720, 480, VA_RT_FORMAT_YUV420, 4, surfaces); + + /* + * Create a context for this decode pipe + */ + VAContext context; + vaCreateContext(dpy, config_id, 720, 480, VA_PROGRESSIVE, surfaces, + 4, &context); + + /* Create a picture parameter buffer for this frame */ + VABufferID picture_buf; + VAPictureParameterBufferMPEG2 *picture_param; + vaCreateBuffer(dpy, VAPictureParameterBufferType, &picture_buf); + vaBufferData(dpy, picture_buf, sizeof(VAPictureParameterBufferMPEG2), NULL); + vaMapBuffer(dpy, picture_buf, &picture_param); + picture_param->horizontal_size = 720; + picture_param->vertical_size = 480; + picture_param->picture_coding_type = 1; /* I-frame */ + /* fill in picture_coding_extension fields here */ + vaUnmapBuffer(dpy, picture_buf); + + + /* Create an IQ matrix buffer for this frame */ + VABufferID iq_buf; + VAIQMatrixBufferMPEG2 *iq_matrix; + vaCreateBuffer(dpy, VAIQMatrixBufferType, &iq_buf); + vaBufferData(dpy, iq_buf, sizeof(VAIQMatrixBufferMPEG2), NULL); + vaMapBuffer(dpy, iq_buf, &iq_matrix); + /* fill values for IQ_matrix here */ + vaUnmapBuffer(dpy, iq_buf); + + /* send the picture and IQ matrix buffers to the server */ + vaBeginPicture(dpy, context, &surfaces[0]); + + vaRenderPicture(dpy, context, &picture_buf, 1); + vaRenderPicture(dpy, context, &iq_buf, 1); + + /* + * Send slices in this frame to the server. + * For MPEG-2, each slice is one row of macroblocks, and + * we have 30 slices for a 720x480 frame + */ + for (int i = 1; i <= 30; i++) { + + /* Create a slice parameter buffer */ + VABufferID slice_param_buf; + VASliceParameterBufferMPEG2 *slice_param; + vaCreateBuffer(dpy, VASliceParameterBufferType, &slice_param_buf); + vaBufferData(dpy, slice_param_buf, sizeof(VASliceParameterBufferMPEG2), NULL); + vaMapBuffer(dpy, slice_param_buf, &slice_param); + slice_param->slice_data_offset = 0; + /* Let's say all slices in this bit-stream has 64-bit header */ + slice_param->macroblock_offset = 64; + slice_param->vertical_position = i; + /* set up the rest based on what is in the slice header ... */ + vaUnmapBuffer(dpy, slice_param_buf); + + /* send the slice parameter buffer */ + vaRenderPicture(dpy, context, &slice_param_buf, 1); + + /* Create a slice data buffer */ + unsigned char *slice_data; + VABufferID slice_data_buf; + vaCreateBuffer(dpy, VASliceDataBufferType, slice_data_buf); + vaBufferData(dpy, slice_data_buf, x /* decoder figure out how big */, NULL); + vaMapBuffer(dpy, slice_data_buf, &slice_data); + /* decoder fill in slice_data */ + vaUnmapBuffer(dpy, slice_data_buf); + + /* send the slice data buffer */ + vaRenderPicture(dpy, context, &slice_data_buf, 1); + } + + /* all slices have been sent, mark the end for this frame */ + vaEndPicture(dpy, context); + + /* The following code demonstrates rendering a sub-title with the target surface */ + /* Find out supported Subpicture formats */ + VAImageFormat sub_formats[4]; + int num_formats; + vaQuerySubpictureFormats(dpy, sub_formats, &num_formats); + /* Assume that we find AI44 as a subpicture format in sub_formats[0] */ + VAImage sub_image; + VASubpicture subpicture; + unsigned char sub_data[128][16]; + /* fill sub_data with subtitle in AI44 */ + vaCreateImage(dpy, sub_formats, 128, 16,&sub_image); + vaCreateSubpicture(dpy, &sub_image, &subpicture); + unsigned char palette[3][16]; + /* fill the palette data */ + vaSetSubpicturePalette(dpy, &subpicture, palette); + vaAssociateSubpicture(dpy, surfaces, &subpicture, 0, 0, 296, 400, 128, 16); + vaPutSurface(dpy, surfaces, win, 0, 0, 720, 480, 100, 100, 640, 480, NULL, 0, 0); +#endif diff --git a/src/va_backend.h b/src/va_backend.h new file mode 100755 index 0000000..c474925 --- /dev/null +++ b/src/va_backend.h @@ -0,0 +1,346 @@ +/* + * 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_H_ +#define _VA_BACKEND_H_ + +#include "va.h" +#include "va_x11.h" + +#include + +typedef struct VADriverContext *VADriverContextP; + +struct VADriverContext +{ + VADriverContextP pNext; + Display *x11_dpy; + int x11_screen; + int version_major; + int version_minor; + int max_profiles; + int max_entrypoints; + int max_attributes; + int max_image_formats; + int max_subpic_formats; + void *handle; /* dlopen handle */ + void *pDriverData; + struct + { + VAStatus (*vaTerminate) ( VADriverContextP ctx ); + + VAStatus (*vaQueryConfigProfiles) ( + VADriverContextP ctx, + VAProfile *profile_list, /* out */ + int *num_profiles /* out */ + ); + + VAStatus (*vaQueryConfigEntrypoints) ( + VADriverContextP ctx, + VAProfile profile, + VAEntrypoint *entrypoint_list, /* out */ + int *num_entrypoints /* out */ + ); + + VAStatus (*vaQueryConfigAttributes) ( + VADriverContextP ctx, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, /* in/out */ + int num_attribs + ); + + VAStatus (*vaCreateConfig) ( + VADriverContextP ctx, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, + int num_attribs, + VAConfigID *config_id /* out */ + ); + + VAStatus (*vaGetConfigAttributes) ( + VADriverContextP ctx, + VAConfigID config_id, + VAProfile *profile, /* out */ + VAEntrypoint *entrypoint, /* out */ + VAConfigAttrib *attrib_list, /* out */ + int *num_attribs /* out */ + ); + + VAStatus (*vaCreateSurfaces) ( + VADriverContextP ctx, + int width, + int height, + int format, + int num_surfaces, + VASurface *surfaces /* out */ + ); + + VAStatus (*vaDestroySurface) ( + VADriverContextP ctx, + VASurface *surface_list, + int num_surfaces + ); + + VAStatus (*vaCreateContext) ( + VADriverContextP ctx, + VAConfigID config_id, + int picture_width, + int picture_height, + int flag, + VASurface *render_targets, + int num_render_targets, + VAContext *context /* out */ + ); + + VAStatus (*vaDestroyContext) ( + VADriverContextP ctx, + VAContext *context + ); + + VAStatus (*vaCreateBuffer) ( + VADriverContextP ctx, + VABufferType type, /* in */ + VABufferID *buf_desc /* out */ + ); + + VAStatus (*vaBufferData) ( + VADriverContextP ctx, + VABufferID buf_id, /* in */ + unsigned int size, /* in */ + unsigned int num_elements, /* in */ + void *data /* in */ + ); + + VAStatus (*vaBufferSetNumElements) ( + VADriverContextP ctx, + VABufferID buf_id, /* in */ + unsigned int num_elements /* in */ + ); + + VAStatus (*vaMapBuffer) ( + VADriverContextP ctx, + VABufferID buf_id, /* in */ + void **pbuf /* out */ + ); + + VAStatus (*vaUnmapBuffer) ( + VADriverContextP ctx, + VABufferID buf_id /* in */ + ); + + VAStatus (*vaDestroyBuffer) ( + VADriverContextP ctx, + VABufferID buffer_id + ); + + VAStatus (*vaBeginPicture) ( + VADriverContextP ctx, + VAContext *context, + VASurface *render_target + ); + + VAStatus (*vaRenderPicture) ( + VADriverContextP ctx, + VAContext *context, + VABufferID *buffers, + int num_buffers + ); + + VAStatus (*vaEndPicture) ( + VADriverContextP ctx, + VAContext *context + ); + + VAStatus (*vaSyncSurface) ( + VADriverContextP ctx, + VAContext *context, + VASurface *render_target + ); + + VAStatus (*vaQuerySurfaceStatus) ( + VADriverContextP ctx, + VAContext *context, + VASurface *render_target, + VASurfaceStatus *status /* out */ + ); + + VAStatus (*vaPutSurface) ( + VADriverContextP ctx, + VASurface *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 */ + int flags /* de-interlacing flags */ + ); + + VAStatus (*vaCopySurfaceToGLXPbuffer) ( + VADriverContextP ctx, + VASurface *surface, + XID pbuffer_id, + short srcx, + short srcy, + unsigned short width, + unsigned short height, + short destx, + short desty, + unsigned int draw_buffer, + unsigned int flags /* de-interlacing flags */ + ); + + VAStatus (*vaQueryImageFormats) ( + VADriverContextP ctx, + VAImageFormat *format_list, /* out */ + int *num_formats /* out */ + ); + + VAStatus (*vaCreateImage) ( + VADriverContextP ctx, + VAImageFormat *format, + int width, + int height, + VAImage *image /* out */ + ); + + VAStatus (*vaDestroyImage) ( + VADriverContextP ctx, + VAImage *image + ); + + VAStatus (*vaGetImage) ( + VADriverContextP ctx, + VASurface *surface, + int x, /* coordinates of the upper left source pixel */ + int y, + unsigned int width, /* width and height of the region */ + unsigned int height, + VAImage *image + ); + + VAStatus (*vaPutImage) ( + VADriverContextP ctx, + VASurface *surface, + VAImage *image, + int src_x, + int src_y, + unsigned int width, + unsigned int height, + int dest_x, + int dest_y + ); + + VAStatus (*vaQuerySubpictureFormats) ( + VADriverContextP ctx, + VAImageFormat *format_list, /* out */ + unsigned int *flags, /* out */ + unsigned int *num_formats /* out */ + ); + + VAStatus (*vaCreateSubpicture) ( + VADriverContextP ctx, + VAImage *image, + VASubpicture *subpicture /* out */ + ); + + VAStatus (*vaDestroySubpicture) ( + VADriverContextP ctx, + VASubpicture *subpicture + ); + + VAStatus (*vaSetSubpictureImage) ( + VADriverContextP ctx, + VASubpicture *subpicture, + VAImage *image + ); + + VAStatus (*vaSetSubpicturePalette) ( + VADriverContextP ctx, + VASubpicture *subpicture, + /* + * pointer to an array holding the palette data. The size of the array is + * num_palette_entries * entry_bytes in size. The order of the components + * in the palette is described by the component_order in VASubpicture struct + */ + unsigned char *palette + ); + + VAStatus (*vaSetSubpictureChromakey) ( + VADriverContextP ctx, + VASubpicture *subpicture, + unsigned int chromakey_min, + unsigned int chromakey_max + ); + + VAStatus (*vaSetSubpictureGlobalAlpha) ( + VADriverContextP ctx, + VASubpicture *subpicture, + float global_alpha + ); + + VAStatus (*vaAssociateSubpicture) ( + VADriverContextP ctx, + VASurface *target_surface, + VASubpicture *subpicture, + short src_x, /* upper left offset in subpicture */ + short src_y, + short dest_x, /* upper left offset in surface */ + short dest_y, + unsigned short width, + unsigned short height, + /* + * whether to enable chroma-keying or global-alpha + * see VA_SUBPICTURE_XXX values + */ + unsigned int flags + ); + + VAStatus (*vaDbgCopySurfaceToBuffer) ( + VADriverContextP ctx, + VASurface *surface, + void **buffer, /* out */ + unsigned int *stride /* out */ + ); + + } vtable; +}; + +typedef VAStatus (*VADriverInit) ( + VADriverContextP driver_context +); + + +#endif /* _VA_BACKEND_H_ */ diff --git a/src/va_dri.c b/src/va_dri.c new file mode 100644 index 0000000..ce3b7cd --- /dev/null +++ b/src/va_dri.c @@ -0,0 +1,624 @@ +/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +Copyright 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Jens Owen + * Rickard E. (Rik) Faith + * + */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#define NEED_REPLIES +#include +#include +#include +#include "va_dristr.h" + +#define PUBLIC + +static XExtensionInfo _va_dri_info_data; +static XExtensionInfo *va_dri_info = &_va_dri_info_data; +static char va_dri_extension_name[] = VA_DRINAME; + +#define VA_DRICheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, va_dri_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int close_display(Display *dpy, XExtCodes *extCodes); +static /* const */ XExtensionHooks va_dri_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, va_dri_info, + va_dri_extension_name, + &va_dri_extension_hooks, + 0, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, va_dri_info) + + +/***************************************************************************** + * * + * public XFree86-DRI Extension routines * + * * + *****************************************************************************/ + +#if 0 +#include +#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg); +#else +#define TRACE(msg) +#endif + + +PUBLIC Bool VA_DRIQueryExtension (dpy, event_basep, error_basep) + Display *dpy; + int *event_basep, *error_basep; +{ + XExtDisplayInfo *info = find_display (dpy); + + TRACE("QueryExtension..."); + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + TRACE("QueryExtension... return True"); + return True; + } else { + TRACE("QueryExtension... return False"); + return False; + } +} + +PUBLIC Bool VA_DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion) + Display* dpy; + int* majorVersion; + int* minorVersion; + int* patchVersion; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIQueryVersionReply rep; + xVA_DRIQueryVersionReq *req; + + TRACE("QueryVersion..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIQueryVersion; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return False"); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + *patchVersion = rep.patchVersion; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return True"); + return True; +} + +PUBLIC Bool VA_DRIQueryDirectRenderingCapable(dpy, screen, isCapable) + Display* dpy; + int screen; + Bool* isCapable; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIQueryDirectRenderingCapableReply rep; + xVA_DRIQueryDirectRenderingCapableReq *req; + + TRACE("QueryDirectRenderingCapable..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIQueryDirectRenderingCapable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIQueryDirectRenderingCapable; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return False"); + return False; + } + *isCapable = rep.isCapable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return True"); + return True; +} + +PUBLIC Bool VA_DRIOpenConnection(dpy, screen, hSAREA, busIdString) + Display* dpy; + int screen; + drm_handle_t * hSAREA; + char **busIdString; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIOpenConnectionReply rep; + xVA_DRIOpenConnectionReq *req; + + TRACE("OpenConnection..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIOpenConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIOpenConnection; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + + *hSAREA = rep.hSAREALow; + if (sizeof(drm_handle_t) == 8) { + int shift = 32; /* var to prevent warning on next line */ + *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift; + } + + if (rep.length) { + if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) { + _XEatData(dpy, ((rep.busIdStringLength+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + _XReadPad(dpy, *busIdString, rep.busIdStringLength); + } else { + *busIdString = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return True"); + return True; +} + +PUBLIC Bool VA_DRIAuthConnection(dpy, screen, magic) + Display* dpy; + int screen; + drm_magic_t magic; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIAuthConnectionReq *req; + xVA_DRIAuthConnectionReply rep; + + TRACE("AuthConnection..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIAuthConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIAuthConnection; + req->screen = screen; + req->magic = magic; + rep.authenticated = 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return False"); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return True"); + return True; +} + +PUBLIC Bool VA_DRICloseConnection(dpy, screen) + Display* dpy; + int screen; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRICloseConnectionReq *req; + + TRACE("CloseConnection..."); + + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRICloseConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRICloseConnection; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CloseConnection... return True"); + return True; +} + +PUBLIC Bool VA_DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, + ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName) + Display* dpy; + int screen; + int* ddxDriverMajorVersion; + int* ddxDriverMinorVersion; + int* ddxDriverPatchVersion; + char** clientDriverName; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIGetClientDriverNameReply rep; + xVA_DRIGetClientDriverNameReq *req; + + TRACE("GetClientDriverName..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIGetClientDriverName, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIGetClientDriverName; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + + *ddxDriverMajorVersion = rep.ddxDriverMajorVersion; + *ddxDriverMinorVersion = rep.ddxDriverMinorVersion; + *ddxDriverPatchVersion = rep.ddxDriverPatchVersion; + + if (rep.length) { + if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) { + _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength); + } else { + *clientDriverName = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return True"); + return True; +} + +PUBLIC Bool VA_DRICreateContextWithConfig(dpy, screen, configID, context, + hHWContext) + Display* dpy; + int screen; + int configID; + XID* context; + drm_context_t * hHWContext; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRICreateContextReply rep; + xVA_DRICreateContextReq *req; + + TRACE("CreateContext..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRICreateContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRICreateContext; + req->visual = configID; + req->screen = screen; + *context = XAllocID(dpy); + req->context = *context; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return False"); + return False; + } + *hHWContext = rep.hHWContext; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return True"); + return True; +} + +PUBLIC Bool VA_DRICreateContext(dpy, screen, visual, context, hHWContext) + Display* dpy; + int screen; + Visual* visual; + XID* context; + drm_context_t * hHWContext; +{ + return VA_DRICreateContextWithConfig( dpy, screen, visual->visualid, + context, hHWContext ); +} + +PUBLIC Bool VA_DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, + __DRIid context ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIDestroyContextReq *req; + + TRACE("DestroyContext..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIDestroyContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIDestroyContext; + req->screen = screen; + req->context = context; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyContext... return True"); + return True; +} + +PUBLIC Bool VA_DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, + __DRIid drawable, drm_drawable_t * hHWDrawable ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xVA_DRICreateDrawableReply rep; + xVA_DRICreateDrawableReq *req; + + TRACE("CreateDrawable..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRICreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRICreateDrawable; + req->screen = screen; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return False"); + return False; + } + *hHWDrawable = rep.hHWDrawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return True"); + return True; +} + +PUBLIC Bool VA_DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, + __DRIid drawable ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIDestroyDrawableReq *req; + + TRACE("DestroyDrawable..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIDestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIDestroyDrawable; + req->screen = screen; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyDrawable... return True"); + return True; +} + +PUBLIC Bool VA_DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable, + unsigned int* index, unsigned int* stamp, + int* X, int* Y, int* W, int* H, + int* numClipRects, drm_clip_rect_t ** pClipRects, + int* backX, int* backY, + int* numBackClipRects, drm_clip_rect_t ** pBackClipRects ) +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIGetDrawableInfoReply rep; + xVA_DRIGetDrawableInfoReq *req; + int total_rects; + + TRACE("GetDrawableInfo..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIGetDrawableInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIGetDrawableInfo; + req->screen = screen; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *)&rep, 1, xFalse)) + { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } + *index = rep.drawableTableIndex; + *stamp = rep.drawableTableStamp; + *X = (int)rep.drawableX; + *Y = (int)rep.drawableY; + *W = (int)rep.drawableWidth; + *H = (int)rep.drawableHeight; + *numClipRects = rep.numClipRects; + total_rects = *numClipRects; + + *backX = rep.backX; + *backY = rep.backY; + *numBackClipRects = rep.numBackClipRects; + total_rects += *numBackClipRects; + +#if 0 + /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks + * backwards compatibility (Because of the >> 2 shift) but the fix + * enables multi-threaded apps to work. + */ + if (rep.length != ((((SIZEOF(xVA_DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply) + + total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) { + _XEatData(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } +#endif + + if (*numClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numClipRects); + + *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); + if (*pClipRects) + _XRead(dpy, (char*)*pClipRects, len); + } else { + *pClipRects = NULL; + } + + if (*numBackClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numBackClipRects); + + *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); + if (*pBackClipRects) + _XRead(dpy, (char*)*pBackClipRects, len); + } else { + *pBackClipRects = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return True"); + return True; +} + +PUBLIC Bool VA_DRIGetDeviceInfo(dpy, screen, hFrameBuffer, + fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate) + Display* dpy; + int screen; + drm_handle_t * hFrameBuffer; + int* fbOrigin; + int* fbSize; + int* fbStride; + int* devPrivateSize; + void** pDevPrivate; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIGetDeviceInfoReply rep; + xVA_DRIGetDeviceInfoReq *req; + + TRACE("GetDeviceInfo..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIGetDeviceInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIGetDeviceInfo; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + + *hFrameBuffer = rep.hFrameBufferLow; + if (sizeof(drm_handle_t) == 8) { + int shift = 32; /* var to prevent warning on next line */ + *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift; + } + + *fbOrigin = rep.framebufferOrigin; + *fbSize = rep.framebufferSize; + *fbStride = rep.framebufferStride; + *devPrivateSize = rep.devPrivateSize; + + if (rep.length) { + if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) { + _XEatData(dpy, ((rep.devPrivateSize+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize); + } else { + *pDevPrivate = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return True"); + return True; +} + +PUBLIC Bool VA_DRIOpenFullScreen(dpy, screen, drawable) + Display* dpy; + int screen; + Drawable drawable; +{ + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; + return False; +} + +PUBLIC Bool VA_DRICloseFullScreen(dpy, screen, drawable) + Display* dpy; + int screen; + Drawable drawable; +{ + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; + return True; +} + +#undef TRACE + diff --git a/src/va_dri.h b/src/va_dri.h new file mode 100644 index 0000000..91f87a2 --- /dev/null +++ b/src/va_dri.h @@ -0,0 +1,120 @@ +/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +Copyright 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. + +**************************************************************************/ + +/** + * \file xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin + * \author Jens Owen + * \author Rickard E. (Rik) Faith + */ + +#ifndef _VA_DRI_H_ +#define _VA_DRI_H_ + +#include +#include + +#define X_VA_DRIQueryVersion 0 +#define X_VA_DRIQueryDirectRenderingCapable 1 +#define X_VA_DRIOpenConnection 2 +#define X_VA_DRICloseConnection 3 +#define X_VA_DRIGetClientDriverName 4 +#define X_VA_DRICreateContext 5 +#define X_VA_DRIDestroyContext 6 +#define X_VA_DRICreateDrawable 7 +#define X_VA_DRIDestroyDrawable 8 +#define X_VA_DRIGetDrawableInfo 9 +#define X_VA_DRIGetDeviceInfo 10 +#define X_VA_DRIAuthConnection 11 +#define X_VA_DRIOpenFullScreen 12 /* Deprecated */ +#define X_VA_DRICloseFullScreen 13 /* Deprecated */ + +#define VA_DRINumberEvents 0 + +#define VA_DRIClientNotLocal 0 +#define VA_DRIOperationNotSupported 1 +#define VA_DRINumberErrors (VA_DRIOperationNotSupported + 1) + +typedef unsigned long __DRIid; +typedef void __DRInativeDisplay; + +_XFUNCPROTOBEGIN + +Bool VA_DRIQueryExtension( Display *dpy, int *event_base, int *error_base ); + +Bool VA_DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion, + int *patchVersion ); + +Bool VA_DRIQueryDirectRenderingCapable( Display *dpy, int screen, + Bool *isCapable ); + +Bool VA_DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA, + char **busIDString ); + +Bool VA_DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic ); + +Bool VA_DRICloseConnection( Display *dpy, int screen ); + +Bool VA_DRIGetClientDriverName( Display *dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName ); + +Bool VA_DRICreateContext( Display *dpy, int screen, Visual *visual, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool VA_DRICreateContextWithConfig( Display *dpy, int screen, int configID, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool VA_DRIDestroyContext( __DRInativeDisplay *dpy, int screen, + __DRIid context_id ); + +Bool VA_DRICreateDrawable( __DRInativeDisplay *dpy, int screen, + __DRIid drawable, drm_drawable_t *hHWDrawable ); + +Bool VA_DRIDestroyDrawable( __DRInativeDisplay *dpy, int screen, + __DRIid drawable); + +Bool VA_DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t **pBackClipRects ); + +Bool VA_DRIGetDeviceInfo( Display *dpy, int screen, + drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize, + int *fbStride, int *devPrivateSize, void **pDevPrivate ); + +_XFUNCPROTOEND + +#endif /* _VA_DRI_H_ */ + diff --git a/src/va_dristr.h b/src/va_dristr.h new file mode 100644 index 0000000..3e391de --- /dev/null +++ b/src/va_dristr.h @@ -0,0 +1,344 @@ +/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.10 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +Copyright 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Jens Owen + * Rickard E. (Rik) Fiath + * + */ + +#ifndef _VA_DRISTR_H_ +#define _VA_DRISTR_H_ + +#include "va_dri.h" + +#define VA_DRINAME "XFree86-DRI" + +/* The DRI version number. This was originally set to be the same of the + * XFree86 version number. However, this version is really indepedent of + * the XFree86 version. + * + * Version History: + * 4.0.0: Original + * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 + * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + */ +#define VA_DRI_MAJOR_VERSION 4 +#define VA_DRI_MINOR_VERSION 1 +#define VA_DRI_PATCH_VERSION 0 + +typedef struct _VA_DRIQueryVersion { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIQueryVersion */ + CARD16 length B16; +} xVA_DRIQueryVersionReq; +#define sz_xVA_DRIQueryVersionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DRI protocol */ + CARD16 minorVersion B16; /* minor version of DRI protocol */ + CARD32 patchVersion B32; /* patch version of DRI protocol */ + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRIQueryVersionReply; +#define sz_xVA_DRIQueryVersionReply 32 + +typedef struct _VA_DRIQueryDirectRenderingCapable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRIQueryDirectRenderingCapableReq; +#define sz_xVA_DRIQueryDirectRenderingCapableReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL isCapable; + BOOL pad2; + BOOL pad3; + BOOL pad4; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; + CARD32 pad9 B32; +} xVA_DRIQueryDirectRenderingCapableReply; +#define sz_xVA_DRIQueryDirectRenderingCapableReply 32 + +typedef struct _VA_DRIOpenConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenConnection */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRIOpenConnectionReq; +#define sz_xVA_DRIOpenConnectionReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hSAREALow B32; + CARD32 hSAREAHigh B32; + CARD32 busIdStringLength B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xVA_DRIOpenConnectionReply; +#define sz_xVA_DRIOpenConnectionReply 32 + +typedef struct _VA_DRIAuthConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; + CARD32 magic B32; +} xVA_DRIAuthConnectionReq; +#define sz_xVA_DRIAuthConnectionReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 authenticated B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRIAuthConnectionReply; +#define zx_xVA_DRIAuthConnectionReply 32 + +typedef struct _VA_DRICloseConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRICloseConnectionReq; +#define sz_xVA_DRICloseConnectionReq 8 + +typedef struct _VA_DRIGetClientDriverName { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetClientDriverName */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRIGetClientDriverNameReq; +#define sz_xVA_DRIGetClientDriverNameReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ddxDriverMajorVersion B32; + CARD32 ddxDriverMinorVersion B32; + CARD32 ddxDriverPatchVersion B32; + CARD32 clientDriverNameLength B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRIGetClientDriverNameReply; +#define sz_xVA_DRIGetClientDriverNameReply 32 + +typedef struct _VA_DRICreateContext { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 visual B32; + CARD32 context B32; +} xVA_DRICreateContextReq; +#define sz_xVA_DRICreateContextReq 16 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWContext B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRICreateContextReply; +#define sz_xVA_DRICreateContextReply 32 + +typedef struct _VA_DRIDestroyContext { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 context B32; +} xVA_DRIDestroyContextReq; +#define sz_xVA_DRIDestroyContextReq 12 + +typedef struct _VA_DRICreateDrawable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRICreateDrawableReq; +#define sz_xVA_DRICreateDrawableReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWDrawable B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRICreateDrawableReply; +#define sz_xVA_DRICreateDrawableReply 32 + +typedef struct _VA_DRIDestroyDrawable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRIDestroyDrawableReq; +#define sz_xVA_DRIDestroyDrawableReq 12 + +typedef struct _VA_DRIGetDrawableInfo { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDrawableInfo */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRIGetDrawableInfoReq; +#define sz_xVA_DRIGetDrawableInfoReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 drawableTableIndex B32; + CARD32 drawableTableStamp B32; + INT16 drawableX B16; + INT16 drawableY B16; + INT16 drawableWidth B16; + INT16 drawableHeight B16; + CARD32 numClipRects B32; + INT16 backX B16; + INT16 backY B16; + CARD32 numBackClipRects B32; +} xVA_DRIGetDrawableInfoReply; + +#define sz_xVA_DRIGetDrawableInfoReply 36 + + +typedef struct _VA_DRIGetDeviceInfo { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDeviceInfo */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRIGetDeviceInfoReq; +#define sz_xVA_DRIGetDeviceInfoReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hFrameBufferLow B32; + CARD32 hFrameBufferHigh B32; + CARD32 framebufferOrigin B32; + CARD32 framebufferSize B32; + CARD32 framebufferStride B32; + CARD32 devPrivateSize B32; +} xVA_DRIGetDeviceInfoReply; +#define sz_xVA_DRIGetDeviceInfoReply 32 + +typedef struct _VA_DRIOpenFullScreen { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRIOpenFullScreenReq; +#define sz_xVA_DRIOpenFullScreenReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isFullScreen B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRIOpenFullScreenReply; +#define sz_xVA_DRIOpenFullScreenReply 32 + +typedef struct _VA_DRICloseFullScreen { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRICloseFullScreenReq; +#define sz_xVA_DRICloseFullScreenReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xVA_DRICloseFullScreenReply; +#define sz_xVA_DRICloseFullScreenReply 32 + + +#endif /* _VA_DRISTR_H_ */ diff --git a/src/va_x11.h b/src/va_x11.h new file mode 100755 index 0000000..e49c6c5 --- /dev/null +++ b/src/va_x11.h @@ -0,0 +1,104 @@ +/* + * Video Decode Acceleration API, X11 specific functions + * + * Rev. 0.15 + * + * + * Revision History: + * rev 0.1 (12/10/06 Jonathan Bian) - Initial draft + * rev 0.11 (12/15/06 Jonathan Bian) - Fixed some errors + * rev 0.12 (02/05/07 Jonathan Bian) - Added VC-1 data structures + * rev 0.13 (02/28/07 Jonathan Bian) - Added GetDisplay() + * rev 0.14 (04/13/07 Jonathan Bian) - Fixed MPEG-2 PictureParameter struct, cleaned up a few funcs. + * rev 0.15 (04/20/07 Jonathan Bian) - Overhauled buffer management + * + */ + +#ifndef _VA_X11_H_ +#define _VA_X11_H_ + +#include "va.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Output rendering + * Following is the rendering interface for X windows, + * to get the decode output surface to a X drawable + * It basically performs a de-interlacing (if needed), + * color space conversion and scaling to the destination + * rectangle + */ + +/* de-interlace flags for vaPutSurface */ +#define VA_TOP_FIELD 0x00000001 +#define VA_BOTTOM_FIELD 0x00000002 +#define VA_FRAME_PICTURE 0x00000004 /* weave */ +VAStatus vaPutSurface ( + VADisplay dpy, + VASurface *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 */ + int flags /* de-interlacing flags */ +); + +/* + This function copies a rectangle of dimension "width" by "height" + from the VASurface indicated by "surface" to the GLXPbuffer + identified by its XID "pbuffer_id". The locations of source and + destination rectangles are specified differently for the VASurface + source and the GLXPbuffer destination as follows. On the VASurface, + the rectangle location is specified in the usual X-Window fashion + with srcx and srcy indicating the location of the upper left hand + corner of the rectangle relative to the VASurface origin (the upper + left hand corner of the XvMCSurface with positive Y axis going in the + down direction). On the GLXPbuffer the rectangle location is + specified in the usual OpenGL fashion with the dstx and dsty + indicating the location of the lower left hand corner of the + rectangle relative to the GLXPbuffer origin (the lower left hand + corner of the GLXPbuffer with the positive Y axis going in the + up direction). + + The "draw_buffer" takes the same OpenGL enums that glDrawBuffer() + takes (ie. GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK_LEFT, GL_BACK_RIGHT, + GL_FRONT, GL_BACK, GL_LEFT, GL_RIGHT or GL_FRONT_AND_BACK). This + indicates which buffer of the GLXPbuffer is to be used for the + destination of the copy. Buffers specified in the "draw_buffer" + that do not exist in the GLXPbuffer are ignored. + + "flags" may be VA_TOP_FIELD, VA_BOTTOM_FIELD or VA_FRAME_PICTURE. + If flags is not VA_FRAME_PICTURE, the srcy and height are in field + coordinates, not frame. That is, the total copyable height is half + the height of the VASurface. +*/ +VAStatus vaCopySurfaceToGLXPbuffer ( + VADisplay dpy, + VASurface *surface, + XID pbuffer_id, + short srcx, + short srcy, + unsigned short width, + unsigned short height, + short destx, + short desty, + unsigned int draw_buffer, + unsigned int flags /* de-interlacing flags */ +); + + +#ifdef __cplusplus +} +#endif + +#endif /* _VA_X11_H_ */ diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..a42608d --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,33 @@ +# 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. + +check_PROGRAMS = test +testdir = $(bindir) + +# This gives better backtraces when running valgrind: +# test_LDADD = ../src/libva.la ../../psb-video/src/psb_drv_video.la +test_LDADD = ../src/libva.la + +AM_CFLAGS = -I$(top_srcdir)/../../include/external/ -I$(top_srcdir)/src +test_SOURCES = test.c + +TESTS = $(check_PROGRAMS) diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..70f3125 --- /dev/null +++ b/test/test.c @@ -0,0 +1,152 @@ +/* + * 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. + */ + +#include "va.h" +#include "X11/Xlib.h" + +#include "assert.h" +#include +#include +#include +#include + +#define ASSERT assert + +int main(int argc, const char* argv[]) +{ + Display *dpy; + VADisplay va_dpy; + VAStatus va_status; + int major_version, minor_version; + + dpy = XOpenDisplay(NULL); + ASSERT( dpy ); + printf("XOpenDisplay: dpy = %08x\n", dpy); + + va_dpy = vaGetDisplay(dpy); + ASSERT( va_dpy ); + printf("vaGetDisplay: va_dpy = %08x\n", va_dpy); + + va_status = vaInitialize(va_dpy, &major_version, &minor_version); + ASSERT( VA_STATUS_SUCCESS == va_status ); + printf("vaInitialize: major = %d minor = %d\n", major_version, minor_version); + + { + VASurface surfaces[21]; + int i; + + surfaces[20].surface_id = -1; + va_status = vaCreateSurfaces(va_dpy, 720, 480, VA_RT_FORMAT_YUV420, 20, surfaces); + ASSERT( VA_STATUS_SUCCESS == va_status ); + ASSERT( -1 == surfaces[20].surface_id ); /* bounds check */ + for(i = 0; i < 20; i++) + { + printf("Surface %d surface_id = %08x\n", i, surfaces[i].surface_id); + } + Window win = XCreateSimpleWindow(dpy, RootWindow(dpy, 0), 0, 0, 720, 480, 0, 0, WhitePixel(dpy, 0)); + printf("Window = %08x\n", win); + XMapWindow(dpy, win); + XSync(dpy, False); + + vaPutSurface(va_dpy, &(surfaces[0]), win, 0, 0, 720, 480, 0, 0, 720, 480, 0); + + sleep(10); + va_status = vaDestroySurface(va_dpy, surfaces, 20); + ASSERT( VA_STATUS_SUCCESS == va_status ); + } + + { + int num_profiles; + int i; + VAProfile *profiles = malloc(vaMaxNumProfiles(va_dpy) * sizeof(VAProfile)); + ASSERT(profiles); + printf("vaMaxNumProfiles = %d\n", vaMaxNumProfiles(va_dpy)); + + va_status = vaQueryConfigProfiles(va_dpy, profiles, &num_profiles); + ASSERT( VA_STATUS_SUCCESS == va_status ); + + printf("vaQueryConfigProfiles reports %d profiles\n", num_profiles); + for(i = 0; i < num_profiles; i++) + { + printf("Profile %d\n", profiles[i]); + } + } + + { + VASurface surfaces[20]; + VAContext context; + VAConfigAttrib attrib; + VAConfigID config_id; + int i; + + attrib.type = VAConfigAttribRTFormat; + va_status = vaQueryConfigAttributes(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD, + &attrib, 1); + ASSERT( VA_STATUS_SUCCESS == va_status ); + + ASSERT(attrib.value & VA_RT_FORMAT_YUV420); + /* Found desired RT format, keep going */ + + va_status = vaCreateConfig(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD, &attrib, 1, + &config_id); + ASSERT( VA_STATUS_SUCCESS == va_status ); + + va_status = vaCreateSurfaces(va_dpy, 720, 480, VA_RT_FORMAT_YUV420, 20, surfaces); + ASSERT( VA_STATUS_SUCCESS == va_status ); + + va_status = vaCreateContext(va_dpy, config_id, 720, 480, 0 /* flag */, surfaces, 20, &context); + ASSERT( VA_STATUS_SUCCESS == va_status ); + + va_status = vaDestroyContext(va_dpy, &context); + ASSERT( VA_STATUS_SUCCESS == va_status ); + + va_status = vaDestroySurface(va_dpy, surfaces, 20); + ASSERT( VA_STATUS_SUCCESS == va_status ); + } + + { + VABufferID picture_buf[3]; + va_status = vaCreateBuffer(va_dpy, VAPictureParameterBufferType, &picture_buf[0]); + ASSERT( VA_STATUS_SUCCESS == va_status ); + va_status = vaCreateBuffer(va_dpy, VAPictureParameterBufferType, &picture_buf[1]); + ASSERT( VA_STATUS_SUCCESS == va_status ); + va_status = vaCreateBuffer(va_dpy, VAPictureParameterBufferType, &picture_buf[2]); + ASSERT( VA_STATUS_SUCCESS == va_status ); + + va_status = vaDestroyBuffer(va_dpy, picture_buf[0]); + ASSERT( VA_STATUS_SUCCESS == va_status ); + va_status = vaDestroyBuffer(va_dpy, picture_buf[2]); + ASSERT( VA_STATUS_SUCCESS == va_status ); + va_status = vaDestroyBuffer(va_dpy, picture_buf[1]); + ASSERT( VA_STATUS_SUCCESS == va_status ); + } + + va_status = vaTerminate(va_dpy); + ASSERT( VA_STATUS_SUCCESS == va_status ); + printf("vaTerminate\n"); + + XCloseDisplay(dpy); + + return 0; +} -- 2.7.4