commit fe05bcd5dab7a3847b203575493a025d07f985ac
Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
Date:   Wed Jun 24 11:40:56 2009 +0000

    Add compatibility layer with original VA-API 0.29 to 0.31.

diff --git a/va/Makefile.am b/va/Makefile.am
index 3ec4d82..d590966 100644
diff --git a/va/va.c b/va/va.c
index 2f9a586..6918910 100644
diff --git a/va/va_backend.h b/va/va_backend.h
index 62ac970..dc06873 100644
diff --git a/va/va_compat.c b/va/va_compat.c
new file mode 100644
index 0000000..eedb8d6
--- /dev/null
+++ b/va/va_compat.c
@@ -0,0 +1,1292 @@
+/*
+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+#include "va.h"
+#include "va_compat.h"
+#include "va_backend.h"
+#include <stdlib.h>
+#include <string.h>
+#include <alloca.h>
+#include <assert.h>
+
+#define CTX(dpy)        (((VADisplayContextP)dpy)->pDriverContext)
+#define COMPAT_CTX(ctx) ((VACompatContextP)(ctx)->compat)
+#define ASSERT		assert
+
+/* Invoke the normal VA API entry-point. This one can be replaced with
+   one of the va_compat_*() functions */
+#define VA_INVOKE(FUNC, CTX, ...) \
+    (CTX)->vtable.FUNC(CTX, __VA_ARGS__)
+
+/* Invoke the real VA API entry-point. That is, the driver's function */
+#define VA_INVOKE_COMPAT_ARGS(CTX, ...) \
+    (COMPAT_CTX(CTX)->compat_ctx, __VA_ARGS__)
+#define VA_INVOKE_COMPAT(FUNC, CTX, ...) \
+    COMPAT_CTX(CTX)->vtable.FUNC VA_INVOKE_COMPAT_ARGS(CTX, __VA_ARGS__)
+
+typedef struct VACompatContext *VACompatContextP;
+
+typedef VAStatus (*VABufferTranslateFunc)(VACompatContextP ctx, void *dest, const void *src);
+
+typedef enum {
+    VA_DRIVER_ID_UNKNOWN,
+    VA_DRIVER_ID_POULSBO,
+    VA_DRIVER_ID_IEGD
+} VADriverID;
+
+typedef struct {
+    VABufferID                  id;
+    VABufferType                type;
+    unsigned int                size;
+    unsigned int                num_elements;
+    unsigned char              *data;
+    VABufferTranslateFunc       translate;
+    VABufferID                  compat_id;
+    unsigned int                compat_size;
+    unsigned char              *compat_data;
+    unsigned int                map_count;
+} VABufferCompat;
+
+typedef struct VAContextMap *VAContextMapP;
+typedef struct VAContextMap {
+    VASurfaceID                 surface;
+    VAContextID                 context;
+    VAContextMapP               next;
+} VAContextMap;
+
+typedef struct {
+    VAStatus (*vaTerminate)(void *);
+    VAStatus (*vaQueryConfigProfiles)(void *, VAProfile *, int *);
+    VAStatus (*vaQueryConfigEntrypoints)(void *, VAProfile, VAEntrypoint *, int *);
+    VAStatus (*vaGetConfigAttributes)(void *, VAProfile, VAEntrypoint, VAConfigAttrib *, int);
+    VAStatus (*vaCreateConfig)(void *, VAProfile, VAEntrypoint, VAConfigAttrib *, int, VAConfigID *);
+    VAStatus (*vaDestroyConfig)(void *, VAConfigID);
+    VAStatus (*vaQueryConfigAttributes)(void *, VAConfigID, VAProfile *, VAEntrypoint *, VAConfigAttrib *, int *);
+    VAStatus (*vaCreateSurfaces)(void *, int, int, int, int, VASurfaceID *);
+    VAStatus (*vaDestroySurfaces)(void *, VASurfaceID *, int);
+    VAStatus (*vaCreateContext)(void *, VAConfigID, int, int, int, VASurfaceID *, int, VAContextID *);
+    VAStatus (*vaDestroyContext)(void *, VAContextID);
+    VAStatus (*vaCreateBuffer)(void *, VAContextID, VABufferType, unsigned int, unsigned int, void *, VABufferID *);
+    VAStatus (*vaBufferSetNumElements)(void *, VABufferID, unsigned int);
+    VAStatus (*vaMapBuffer)(void *, VABufferID, void **);
+    VAStatus (*vaUnmapBuffer)(void *, VABufferID);
+    VAStatus (*vaDestroyBuffer)(void *, VABufferID);
+    VAStatus (*vaBeginPicture)(void *, VAContextID, VASurfaceID);
+    VAStatus (*vaRenderPicture)(void *, VAContextID, VABufferID *, int);
+    VAStatus (*vaEndPicture)(void *, VAContextID);
+    VAStatus (*vaSyncSurface_pre31)(void *, VAContextID, VASurfaceID);
+    VAStatus (*vaQuerySurfaceStatus)(void *, VASurfaceID, VASurfaceStatus *);
+    VAStatus (*vaPutSurface)(void *, VASurfaceID, unsigned long, short, short, unsigned short, unsigned short, short, short, unsigned short, unsigned short, VARectangle *, unsigned int, unsigned int);
+    VAStatus (*vaQueryImageFormats)(void *, VAImageFormat *, int *);
+    VAStatus (*vaCreateImage)(void *, VAImageFormat *, int, int, VAImage *);
+    VAStatus (*vaDeriveImage)(void *, VASurfaceID, VAImage *);
+    VAStatus (*vaDestroyImage)(void *, VAImageID);
+    VAStatus (*vaSetImagePalette)(void *, VAImageID, unsigned char *);
+    VAStatus (*vaGetImage)(void *, VASurfaceID, int, int, unsigned int, unsigned int, VAImageID);
+    VAStatus (*vaPutImage_pre31)(void *, VASurfaceID, VAImageID, int, int, unsigned int, unsigned int, int, int);
+    VAStatus (*vaPutImage2_pre31)(void *, VASurfaceID, VAImageID, int, int, unsigned int, unsigned int, int, int, unsigned int, unsigned int);
+    VAStatus (*vaQuerySubpictureFormats)(void *, VAImageFormat *, unsigned int *, unsigned int *);
+    VAStatus (*vaCreateSubpicture)(void *, VAImageID, VASubpictureID *);
+    VAStatus (*vaDestroySubpicture)(void *, VASubpictureID);
+    VAStatus (*vaSetSubpictureImage)(void *, VASubpictureID, VAImageID);
+    VAStatus (*vaSetSubpictureChromakey)(void *, VASubpictureID, unsigned int, unsigned int, unsigned int);
+    VAStatus (*vaSetSubpictureGlobalAlpha)(void *, VASubpictureID, float);
+    VAStatus (*vaAssociateSubpicture_pre31)(void *, VASubpictureID, VASurfaceID *, int, short, short, short, short, unsigned short, unsigned short, unsigned int);
+    VAStatus (*vaAssociateSubpicture2_pre31)(void *, VASubpictureID, VASurfaceID *, int, short, short, unsigned short, unsigned short, short, short, unsigned short, unsigned short, unsigned int);
+    VAStatus (*vaDeassociateSubpicture)(void *, VASubpictureID, VASurfaceID *, int);
+    VAStatus (*vaQueryDisplayAttributes)(void *, VADisplayAttribute *, int *);
+    VAStatus (*vaGetDisplayAttributes)(void *, VADisplayAttribute *, int);
+    VAStatus (*vaSetDisplayAttributes)(void *, VADisplayAttribute *, int);
+
+    /* 0.29 hooks */
+    VAStatus (*vaSetSubpicturePalette)(void *, VASubpictureID, unsigned char *);
+    VAStatus (*vaDbgCopySurfaceToBuffer)(void *, VASurfaceID, void **, unsigned int *);
+
+    /* 0.30 hooks */
+    VAStatus (*vaCreateSurfaceFromCIFrame)(void *, unsigned long, VASurfaceID *);
+    VAStatus (*vaCreateSurfaceFromV4L2Buf)(void *, int, struct v4l2_format *, struct v4l2_buffer *, VASurfaceID *);
+    VAStatus (*vaCopySurfaceToBuffer)(void *, VASurfaceID, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, void **);
+
+    /* 0.31 hooks */
+    VAStatus (*vaPutImage)(void *, VASurfaceID, VAImageID, int, int, unsigned int, unsigned int, int, int, unsigned int, unsigned int);
+    VAStatus (*vaAssociateSubpicture)(void *, VASubpictureID, VASurfaceID *, int, short, short, unsigned short, unsigned short, short, short, unsigned short, unsigned short, unsigned int);
+    VAStatus (*vaSyncSurface)(void *, VASurfaceID);
+
+#if 0
+    /* 0.31.1 hooks */
+    VAStatus (*vaBufferInfo)(void *, VAContextID, VABufferID, VABufferType *, unsigned int *, unsigned int *);
+    VAStatus (*vaLockSurface)(void *, VASurfaceID, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, void **);
+    VAStatus (*vaUnlockSurface)(void *, VASurfaceID);
+#endif
+} VACompatDriverVTable;
+
+typedef struct VACompatContext {
+    VABufferCompat             *buffers;
+    unsigned int                buffers_count_max;
+    unsigned int                compat_version;
+    void                       *compat_ctx;
+    VACompatDriverVTable        vtable;                 /* original vtable */
+    VADriverID                  driver_id;
+    char                       *driver_name;
+    VAContextMapP               context_map;
+    VAContextMapP               last_context_map_match;
+    unsigned int                skip_frame : 1;
+} VACompatContext;
+
+#define COMPAT_MAJOR 0
+#define COMPAT_MINOR 29
+#include "va_compat_template.h"
+
+#define COMPAT_MAJOR 0
+#define COMPAT_MINOR 30
+#include "va_compat_template.h"
+
+#define COMPAT_MAJOR 0
+#define COMPAT_MINOR 31
+#include "va_compat_template.h"
+
+static inline int va_IsIntelBuffer(VADriverContextP ctx, VABufferID id)
+{
+    VACompatContextP compat = ctx->compat;
+
+    if (compat->driver_id == VA_DRIVER_ID_POULSBO) {
+        /* There were only Intel implementations for VA API. Besides, the
+           returned buffer IDs had the following format [ 0 BASE ID ] where
+           BASE is the 7-bit value 0x04 and ID an index into the heap of
+           objects */
+        return (id & 0x7f000000) == 0x04000000;
+    }
+
+    if (compat->driver_id == VA_DRIVER_ID_IEGD) {
+        /* XXX: there is no means to differentiate the buffers, they
+           are linearly generated (IEGD 10.0 build 1335) */
+        return 1;
+    }
+
+    return 0;
+}
+
+static VAContextMapP va_context_map_lookup_p(
+    VACompatContextP    ctx,
+    VASurfaceID         surface
+)
+{
+    VAContextMapP m = ctx->context_map;
+
+    while (m) {
+        if (m->surface == surface)
+            return m;
+        m = m->next;
+    }
+    return NULL;
+}
+
+static VAContextID va_context_map_lookup(
+    VACompatContextP    ctx,
+    VASurfaceID         surface
+)
+{
+    VAContextMapP m;
+
+    /* Lookup in cached */
+    m = ctx->last_context_map_match;
+    if (m && m->surface == surface)
+        return m->context;
+
+    /* Full (slow) lookup */
+    m = va_context_map_lookup_p(ctx, surface);
+    if (m) {
+        ctx->last_context_map_match = m;
+        return m->context;
+    }
+    return VA_INVALID_ID;
+}
+
+static void va_context_map_add(
+    VACompatContextP    ctx,
+    VAContextID         context,
+    VASurfaceID         surface
+)
+{
+    VAContextMapP m;
+
+    /* Update existing entry */
+    m = va_context_map_lookup_p(ctx, surface);
+    if (m) {
+        m->context = context;
+        return;
+    }
+
+    /* Create new mapping */
+    m = malloc(sizeof(*m));
+    ASSERT(m);
+    if (m) {
+        m->surface = surface;
+        m->context = context;
+        m->next    = ctx->context_map;
+        ctx->context_map = m;
+    }
+}
+
+static void va_context_map_remove(
+    VACompatContextP    ctx,
+    VAContextID         context
+)
+{
+    VAContextMapP p = NULL;
+    VAContextMapP m = ctx->context_map;
+    VAContextMapP d;
+
+    while (m) {
+        if (m->context == context) {
+            d = m;
+
+            /* Unlink current node */
+            if (p)
+                p->next = m->next;
+            else
+                ctx->context_map = m->next;
+            m = m->next;
+
+            /* Reset cache */
+            if (ctx->last_context_map_match == d)
+                ctx->last_context_map_match = NULL;
+
+            free(d);
+        }
+        else {
+            p = m;
+            m = m->next;
+        }
+    }
+}
+
+static VABufferCompat *va_GetBufferCompat (
+    VADriverContextP ctx,
+    VABufferID id
+)
+{
+    VACompatContextP compat = ctx->compat;
+    int index;
+
+    if (!va_IsIntelBuffer(ctx, id))
+        return NULL;
+
+    index = id & 0x00ffffff;
+    if (index >= compat->buffers_count_max)
+        return NULL;
+
+    if (compat->buffers[index].id != id)
+        return NULL;
+
+    return &compat->buffers[index];
+}
+
+static VAStatus va_TranslateBufferCompat (
+    VADriverContextP ctx,
+    VABufferCompat *compat_buffer
+)
+{
+    VAStatus status;
+    unsigned char *src, *dest;
+    int i;
+
+    status = VA_INVOKE(vaMapBuffer, ctx, compat_buffer->id, (void **)&src);
+    if (status != VA_STATUS_SUCCESS)
+        return status;
+
+    ASSERT(compat_buffer->data);
+    ASSERT(src == compat_buffer->data);
+    ASSERT(compat_buffer->compat_data);
+    dest = compat_buffer->compat_data;
+    for (i = 0; i < compat_buffer->num_elements; i++)
+    {
+        /* XXX: check errors */
+        status = compat_buffer->translate(ctx->compat, dest, src);
+
+        src   += compat_buffer->size;
+        dest  += compat_buffer->compat_size;
+    }
+
+    return VA_INVOKE(vaUnmapBuffer, ctx, compat_buffer->id);
+}
+
+static VAStatus va_CreateBufferCompat (
+    VADriverContextP ctx,
+    VAContextID context,
+    VABufferID id,
+    VABufferType type,
+    unsigned int size,
+    unsigned int num_elements,
+    unsigned int compat_size,
+    VABufferTranslateFunc translate_func
+)
+{
+    VACompatContextP compat = ctx->compat;
+    VABufferCompat *compat_buffer;
+    int index;
+
+    if (!va_IsIntelBuffer(ctx, id))
+        return VA_STATUS_ERROR_INVALID_BUFFER;
+    index = id & 0x00ffffff;
+
+    /* XXX: this allocation strategy is not really space efficient... */
+    if (index >= compat->buffers_count_max)
+    {
+        compat->buffers = realloc(
+            compat->buffers,
+            ((index + 1) * sizeof(VABufferCompat))
+        );
+        if (compat->buffers == NULL)
+            return VA_STATUS_ERROR_ALLOCATION_FAILED;
+        memset(
+            &compat->buffers[compat->buffers_count_max],
+            0,
+            (index + 1 - compat->buffers_count_max) * sizeof(compat->buffers[0])
+        );
+        compat->buffers_count_max = index + 1;
+    }
+
+    compat_buffer = &compat->buffers[index];
+    compat_buffer->id           = id;
+    compat_buffer->type         = type;
+    compat_buffer->size         = size;
+    compat_buffer->num_elements = num_elements;
+    compat_buffer->data         = NULL;
+    compat_buffer->translate    = translate_func;
+    compat_buffer->compat_size  = compat_size;
+    compat_buffer->compat_data  = NULL;
+    compat_buffer->map_count    = 0;
+
+    return VA_INVOKE_COMPAT(vaCreateBuffer,
+                            ctx,
+                            context,
+                            type,
+                            compat_size,
+                            num_elements,
+                            NULL,
+                            &compat_buffer->compat_id);
+}
+
+static VAStatus va_DestroyBufferCompat (
+    VADriverContextP ctx,
+    VABufferID id
+)
+{
+    VABufferCompat *compat_buffer;
+    VAStatus status;
+
+    if ((compat_buffer = va_GetBufferCompat(ctx, id)) == NULL)
+        return VA_STATUS_SUCCESS;
+
+    /* Force unmap if there were more maps than unmaps */
+    if (compat_buffer->map_count > 1)
+        compat_buffer->map_count = 1;
+    if (compat_buffer->map_count > 1)
+    {
+        if ((status = VA_INVOKE(vaUnmapBuffer, ctx, id)) != VA_STATUS_SUCCESS)
+            return status;
+    }
+
+    compat_buffer->id = 0;
+    return VA_INVOKE_COMPAT(vaDestroyBuffer, ctx, compat_buffer->compat_id);
+}
+
+static VAStatus va_compat_CreateBuffer (
+    VADriverContextP ctx,
+    VAContextID context,	/* in */
+    VABufferType type,		/* in */
+    unsigned int size,		/* in */
+    unsigned int num_elements,	/* in */
+    void *data,			/* in */
+    VABufferID *buf_id		/* out */
+)
+{
+    VABufferTranslateFunc translate_func = NULL;
+    unsigned int compat_size = 0;
+    VAStatus status;
+
+    status = VA_INVOKE_COMPAT(vaCreateBuffer,
+                              ctx,
+                              context,
+                              type,
+                              size,
+                              num_elements,
+                              data,
+                              buf_id);
+
+    if (status != VA_STATUS_SUCCESS)
+        return status;
+
+#define INIT_TRANSLATE_FUNC_(STRUCT, MAJOR, MINOR) do {                 \
+    translate_func = va_compat_translate_VA##STRUCT##_##MAJOR##_##MINOR; \
+    compat_size = sizeof(VA##STRUCT##_##MAJOR##_##MINOR);               \
+} while (0)
+#define INIT_TRANSLATE_FUNC(BUFFER, CODEC, MAJOR, MINOR) \
+    INIT_TRANSLATE_FUNC_(BUFFER##Buffer##CODEC, MAJOR, MINOR)
+
+    /* XXX: this assumes all structures have different sizes from each other */
+    switch (size) {
+    case sizeof(VAPictureParameterBufferH264):
+        if (type == VAPictureParameterBufferType && ctx->version_major == 0)
+        {
+            switch (ctx->version_minor) {
+            case 29: INIT_TRANSLATE_FUNC(PictureParameter,H264, 0,29); break;
+            case 30: INIT_TRANSLATE_FUNC(PictureParameter,H264, 0,30); break;
+            }
+        }
+        break;
+    case sizeof(VASliceParameterBufferH264):
+        if (type == VASliceParameterBufferType && ctx->version_major == 0)
+        {
+            switch (ctx->version_minor) {
+            case 29: INIT_TRANSLATE_FUNC(SliceParameter,H264, 0,29); break;
+            case 30: INIT_TRANSLATE_FUNC(SliceParameter,H264, 0,30); break;
+            }
+        }
+        break;
+    case sizeof(VAPictureParameterBufferVC1):
+        if (type == VAPictureParameterBufferType && ctx->version_major == 0)
+        {
+            switch (ctx->version_minor) {
+            case 29: INIT_TRANSLATE_FUNC(PictureParameter,VC1, 0,29); break;
+            case 30: INIT_TRANSLATE_FUNC(PictureParameter,VC1, 0,30); break;
+            }
+        }
+        break;
+    case sizeof(VAPictureParameterBufferMPEG2):
+        if (type == VAPictureParameterBufferType && ctx->version_major == 0)
+        {
+            switch (ctx->version_minor) {
+            case 29: INIT_TRANSLATE_FUNC(PictureParameter,MPEG2, 0,29); break;
+            case 30: INIT_TRANSLATE_FUNC(PictureParameter,MPEG2, 0,30); break;
+            }
+        }
+        break;
+    case sizeof(VASliceParameterBufferMPEG2):
+        if (type == VASliceParameterBufferType && ctx->version_major == 0)
+        {
+            switch (ctx->version_minor) {
+            case 29: INIT_TRANSLATE_FUNC(SliceParameter,MPEG2, 0,29); break;
+            case 30: INIT_TRANSLATE_FUNC(SliceParameter,MPEG2, 0,30); break;
+            }
+        }
+        break;
+    case sizeof(VAPictureParameterBufferMPEG4):
+        if (type == VAPictureParameterBufferType && ctx->version_major == 0)
+        {
+            switch (ctx->version_minor) {
+            case 29: INIT_TRANSLATE_FUNC(PictureParameter,MPEG4, 0,29); break;
+            case 30: INIT_TRANSLATE_FUNC(PictureParameter,MPEG4, 0,30); break;
+            case 31: INIT_TRANSLATE_FUNC(PictureParameter,MPEG4, 0,31); break;
+            }
+        }
+        break;
+    case sizeof(VAEncSliceParameterBuffer):
+        if (type == VAEncSliceParameterBufferType && ctx->version_major == 0)
+        {
+            switch (ctx->version_minor) {
+            case 30: INIT_TRANSLATE_FUNC_(EncSliceParameterBuffer, 0,30); break;
+            }
+        }
+        break;
+    }
+
+#undef INIT_TRANSLATE_FUNC
+
+    /* Create thunk */
+    if (buf_id && translate_func)
+    {
+        ASSERT(compat_size > 0);
+
+        status = va_CreateBufferCompat(ctx,
+                                       context,
+                                       *buf_id,
+                                       type,
+                                       size,
+                                       num_elements,
+                                       compat_size,
+                                       translate_func);
+    }
+
+    return status;
+}
+
+static VAStatus va_compat_BufferSetNumElements (
+    VADriverContextP ctx,
+    VABufferID buf_id,	/* in */
+    unsigned int num_elements /* in */
+)
+{
+    VABufferCompat *compat_buffer;
+    VAStatus status;
+
+    status = VA_INVOKE_COMPAT(vaBufferSetNumElements, ctx, buf_id, num_elements);
+    if (status != VA_STATUS_SUCCESS)
+        return status;
+
+    if ((compat_buffer = va_GetBufferCompat(ctx, buf_id)) != NULL)
+    {
+        compat_buffer->num_elements = num_elements;
+        status = VA_INVOKE_COMPAT(vaBufferSetNumElements,
+                                  ctx,
+                                  compat_buffer->compat_id,
+                                  num_elements);
+    }
+
+    return status;
+}
+
+static VAStatus va_compat_DestroyBuffer (
+    VADriverContextP ctx,
+    VABufferID buffer_id
+)
+{
+    VAStatus status;
+    if ((status = va_DestroyBufferCompat(ctx, buffer_id)) != VA_STATUS_SUCCESS)
+        return status;
+
+    return VA_INVOKE_COMPAT(vaDestroyBuffer, ctx, buffer_id);
+}
+
+static VAStatus va_compat_MapBuffer (
+    VADriverContextP ctx,
+    VABufferID buf_id,	/* in */
+    void **pbuf 	/* out */
+)
+{
+    VABufferCompat *compat_buffer;
+    VAStatus status;
+
+    if ((compat_buffer = va_GetBufferCompat(ctx, buf_id)) == NULL)
+        return VA_INVOKE_COMPAT(vaMapBuffer, ctx, buf_id, pbuf);
+
+    if (compat_buffer->map_count++ == 0)
+    {
+        status = VA_INVOKE_COMPAT(vaMapBuffer, ctx, buf_id, (void **)&compat_buffer->data);
+        if (status != VA_STATUS_SUCCESS)
+            return status;
+
+        status = VA_INVOKE_COMPAT(vaMapBuffer, ctx, compat_buffer->compat_id, (void **)&compat_buffer->compat_data);
+        if (status != VA_STATUS_SUCCESS)
+            return status;
+    }
+
+    if (pbuf)
+        *pbuf = compat_buffer->data;
+
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus va_compat_UnmapBuffer (
+    VADriverContextP ctx,
+    VABufferID buf_id	/* in */
+)
+{
+    VABufferCompat *compat_buffer;
+    VAStatus status;
+
+    if ((compat_buffer = va_GetBufferCompat(ctx, buf_id)) == NULL)
+        return VA_INVOKE_COMPAT(vaUnmapBuffer, ctx, buf_id);
+
+    if (--compat_buffer->map_count == 0)
+    {
+        status = VA_INVOKE_COMPAT(vaUnmapBuffer, ctx, compat_buffer->compat_id);
+        if (status != VA_STATUS_SUCCESS)
+            return status;
+        compat_buffer->compat_data = NULL;
+
+        status = VA_INVOKE_COMPAT(vaUnmapBuffer, ctx, compat_buffer->id);
+        if (status != VA_STATUS_SUCCESS)
+            return status;
+        compat_buffer->data = NULL;
+    }
+
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus va_compat_BeginPicture (
+    VADriverContextP ctx,
+    VAContextID context,
+    VASurfaceID render_target
+)
+{
+    VACompatContextP compat = ctx->compat;
+    compat->skip_frame = 0;
+    return VA_INVOKE_COMPAT(vaBeginPicture, ctx, context, render_target);
+}
+
+static VAStatus va_compat_EndPicture (
+    VADriverContextP ctx,
+    VAContextID context
+)
+{
+    VACompatContextP compat = ctx->compat;
+    VAStatus status = VA_INVOKE_COMPAT(vaEndPicture, ctx, context);
+
+    /* Ignore errors if the HW decoder did not handle VC-1 skipped P-frames */
+    if (compat->skip_frame && status == VA_STATUS_ERROR_UNKNOWN)
+        status = VA_STATUS_SUCCESS;
+
+    return status;
+}
+
+static VAStatus va_compat_RenderPicture (
+    VADriverContextP ctx,
+    VAContextID context,
+    VABufferID *buffers,
+    int num_buffers
+)
+{
+    VACompatContextP compat = ctx->compat;
+    VABufferCompat *compat_buffer;
+    VABufferID *compat_buffer_ids;
+    VAStatus status;
+    int i, n;
+
+    if ((n = num_buffers) < 1)
+        n = 1;
+    compat_buffer_ids = alloca(n * sizeof(compat_buffer_ids[0]));
+
+    for (i = 0; i < num_buffers; i++)
+    {
+        if ((compat_buffer = va_GetBufferCompat(ctx, buffers[i])) == NULL)
+            compat_buffer_ids[i] = buffers[i];
+        else
+        {
+            status = va_TranslateBufferCompat(ctx, compat_buffer);
+            if (status != VA_STATUS_SUCCESS)
+                return status;
+            compat_buffer_ids[i] = compat_buffer->compat_id;
+        }
+    }
+
+    if (!compat->skip_frame)
+    {
+        status = VA_INVOKE_COMPAT(vaRenderPicture, ctx, context, compat_buffer_ids, num_buffers);
+        if (status != VA_STATUS_SUCCESS)
+            return status;
+    }
+
+    /* Buffers are automatically destroyed afterwards */
+    for (i = 0; i < num_buffers; i++)
+    {
+        if ((compat_buffer = va_GetBufferCompat(ctx, buffers[i])) != NULL)
+        {
+            status = VA_INVOKE_COMPAT(vaDestroyBuffer, ctx, compat_buffer->id);
+            if (status != VA_STATUS_SUCCESS)
+                return status;
+        }
+    }
+
+    return VA_STATUS_SUCCESS;
+}
+
+#define DEFINE_VTABLE_ENTRY_(RETVAL, PROC, ARGS, COMPAT_PROC, COMPAT_ARGS, COMPAT_PRE, COMPAT_POST) \
+static RETVAL va_compat_##PROC ARGS                                        \
+{                                                                          \
+    if (COMPAT_CTX(ctx)->vtable.va##COMPAT_PROC == NULL)                   \
+        return VA_STATUS_ERROR_OPERATION_FAILED;                           \
+    COMPAT_PRE;                                                            \
+    RETVAL ret = COMPAT_CTX(ctx)->vtable.va##COMPAT_PROC VA_INVOKE_COMPAT_ARGS COMPAT_ARGS; \
+    COMPAT_POST;                                                           \
+    return ret;                                                            \
+}
+
+#define DEFINE_VTABLE_ENTRY(RETVAL, PROC, DECL_ARGS, CALL_ARGS) \
+DEFINE_VTABLE_ENTRY_(RETVAL, PROC, DECL_ARGS, PROC, CALL_ARGS, {}, {})
+
+static VAStatus va_compat_Terminate(VADriverContextP ctx)
+{
+    if (COMPAT_CTX(ctx)->vtable.vaTerminate == NULL)
+        return VA_STATUS_ERROR_OPERATION_FAILED;
+    return COMPAT_CTX(ctx)->vtable.vaTerminate(COMPAT_CTX(ctx)->compat_ctx);
+}
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, QueryConfigProfiles,
+    (VADriverContextP ctx, VAProfile *profile_list, int *num_profiles),
+    (ctx, profile_list, num_profiles))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, QueryConfigEntrypoints,
+    (VADriverContextP ctx, VAProfile profile,
+     VAEntrypoint *entrypoint_list, int *num_entrypoints),
+    (ctx, profile, entrypoint_list, num_entrypoints))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, GetConfigAttributes,
+    (VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
+     VAConfigAttrib *attrib_list, int num_attribs),
+    (ctx, profile, entrypoint, attrib_list, num_attribs))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, CreateConfig,
+    (VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
+     VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id),
+    (ctx, profile, entrypoint, attrib_list, num_attribs, config_id))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, DestroyConfig,
+    (VADriverContextP ctx, VAConfigID config_id),
+    (ctx, config_id))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, QueryConfigAttributes,
+    (VADriverContextP ctx, VAConfigID config_id, VAProfile *profile,
+     VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs),
+    (ctx, config_id, profile, entrypoint, attrib_list, num_attribs))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, CreateSurfaces,
+    (VADriverContextP ctx, int width, int height, int format,
+     int num_surfaces, VASurfaceID *surfaces),
+    (ctx, width, height, format, num_surfaces, surfaces))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, DestroySurfaces,
+    (VADriverContextP ctx, VASurfaceID *surface_list, int num_surfaces),
+    (ctx, surface_list, num_surfaces))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, CreateContext,
+    (VADriverContextP ctx, VAConfigID config_id,
+     int picture_width, int picture_height, int flag,
+     VASurfaceID *render_targets, int num_render_targets, VAContextID *context),
+    (ctx, config_id, picture_width, picture_height, flag,
+     render_targets, num_render_targets, context))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, DestroyContext,
+    (VADriverContextP ctx, VAContextID context),
+    (ctx, context))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, SyncSurface,
+    (VADriverContextP ctx, VASurfaceID render_target),
+    (ctx, render_target))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, QuerySurfaceStatus,
+    (VADriverContextP ctx, VASurfaceID render_target, VASurfaceStatus *status),
+    (ctx, render_target, status))
+
+DEFINE_VTABLE_ENTRY_(
+    VAStatus, PutSurface,
+    (VADriverContextP ctx, VASurfaceID surface, Drawable draw,
+     short srcx, short srcy, unsigned short srcw, unsigned short srch,
+     short destx, short desty, unsigned short destw, unsigned short desth,
+     VARectangle *cliprects, unsigned int number_cliprects, unsigned int flags),
+    PutSurface,
+    (ctx, surface, draw, srcx, srcy, srcw, srch, destx, desty, destw, desth,
+     cliprects, number_cliprects, flags),
+    {
+        if (COMPAT_CTX(ctx)->compat_version < 30) /* 0.30 */
+            flags &= (VA_TOP_FIELD|VA_BOTTOM_FIELD|VA_CLEAR_DRAWABLE);
+    },
+    {})
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, QueryImageFormats,
+    (VADriverContextP ctx, VAImageFormat *format_list, int *num_formats),
+    (ctx, format_list, num_formats))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, CreateImage,
+    (VADriverContextP ctx, VAImageFormat *format,
+     int width, int height, VAImage *image),
+    (ctx, format, width, height, image))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, DeriveImage,
+    (VADriverContextP ctx, VASurfaceID surface, VAImage *image),
+    (ctx, surface, image))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, DestroyImage,
+    (VADriverContextP ctx, VAImageID image),
+    (ctx, image))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, SetImagePalette,
+    (VADriverContextP ctx, VAImageID image, unsigned char *palette),
+    (ctx, image, palette))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, GetImage,
+    (VADriverContextP ctx, VASurfaceID surface,
+     int x, int y, unsigned int width, unsigned int height, VAImageID image),
+    (ctx, surface, x, y, width, height, image))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, PutImage,
+    (VADriverContextP ctx, VASurfaceID surface, VAImageID image,
+     int srcx, int srcy, unsigned int srcw, unsigned int srch,
+     int destx, int desty, unsigned int destw, unsigned int desth),
+    (ctx, surface, image, srcx, srcy, srcw, srch, destx, desty, destw, desth))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, QuerySubpictureFormats,
+    (VADriverContextP ctx, VAImageFormat *format_list,
+     unsigned int *flags, unsigned int *num_formats),
+    (ctx, format_list, flags, num_formats))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, CreateSubpicture,
+    (VADriverContextP ctx, VAImageID image, VASubpictureID *subpicture),
+    (ctx, image, subpicture))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, DestroySubpicture,
+    (VADriverContextP ctx, VASubpictureID subpicture),
+    (ctx, subpicture))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, SetSubpictureImage,
+    (VADriverContextP ctx, VASubpictureID subpicture, VAImageID image),
+    (ctx, subpicture, image))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, SetSubpictureChromakey,
+    (VADriverContextP ctx, VASubpictureID subpicture,
+     unsigned int chromakey_min,
+     unsigned int chromakey_max,
+     unsigned int chromakey_mask),
+    (ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, SetSubpictureGlobalAlpha,
+    (VADriverContextP ctx, VASubpictureID subpicture, float global_alpha),
+    (ctx, subpicture, global_alpha))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, AssociateSubpicture,
+    (VADriverContextP ctx, VASubpictureID subpicture,
+     VASurfaceID *target_surfaces, int num_surfaces,
+     short srcx, short srcy, unsigned short srcw, unsigned short srch,
+     short destx, short desty, unsigned short destw, unsigned short desth,
+     unsigned int flags),
+    (ctx, subpicture, target_surfaces, num_surfaces,
+     srcx, srcy, srcw, srch, destx, desty, destw, desth, flags))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, DeassociateSubpicture,
+    (VADriverContextP ctx, VASubpictureID subpicture,
+     VASurfaceID *target_surfaces, int num_surfaces),
+    (ctx, subpicture, target_surfaces, num_surfaces))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, QueryDisplayAttributes,
+    (VADriverContextP ctx, VADisplayAttribute *attr_list, int *num_attributes),
+    (ctx, attr_list, num_attributes))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, GetDisplayAttributes,
+    (VADriverContextP ctx, VADisplayAttribute *attr_list, int num_attributes),
+    (ctx, attr_list, num_attributes))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, SetDisplayAttributes,
+    (VADriverContextP ctx, VADisplayAttribute *attr_list, int num_attributes),
+    (ctx, attr_list, num_attributes))
+
+#if 0
+DEFINE_VTABLE_ENTRY(
+    VAStatus, CreateSurfaceFromCIFrame,
+    (VADriverContextP ctx, unsigned long frame_id, VASurfaceID *surface),
+    (ctx, frame_id, surface))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, CreateSurfaceFromV4L2Buf,
+    (VADriverContextP ctx, int v4l2_fd,
+     struct v4l2_format *v4l2_fmt, struct v4l2_buffer *v4l2_buf,
+     VASurfaceID *surface),
+    (ctx, v4l2_fd, v4l2_fmt, v4l2_buf, surface))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, CopySurfaceToBuffer,
+    (VADriverContextP ctx, VASurfaceID surface, unsigned int *fourcc,
+     unsigned int *luma_stride,
+     unsigned int *chroma_u_stride, unsigned int *chroma_v_stride,
+     unsigned int *luma_offset,
+     unsigned int *chroma_u_offset, unsigned int *chroma_v_offset,
+     void **buffer),
+    (ctx, surface, fourcc,
+     luma_stride, chroma_u_stride, chroma_v_stride,
+     luma_offset, chroma_u_offset, chroma_v_offset,
+     buffer))
+#endif
+
+DEFINE_VTABLE_ENTRY_(
+    VAStatus, SyncSurface_pre31,
+    (VADriverContextP ctx, VASurfaceID render_target),
+    SyncSurface_pre31,
+    (ctx, va_context_map_lookup(COMPAT_CTX(ctx), render_target), render_target),
+    {}, {})
+
+DEFINE_VTABLE_ENTRY_(
+    VAStatus, PutImage_pre31,
+    (VADriverContextP ctx, VASurfaceID surface, VAImageID image,
+     int srcx, int srcy, unsigned int srcw, unsigned int srch,
+     int destx, int desty, unsigned int destw, unsigned int desth),
+    PutImage2_pre31,
+    (ctx, surface, image, srcx, srcy, srcw, srch, destx, desty, destw, desth),
+    {}, {})
+
+DEFINE_VTABLE_ENTRY_(
+    VAStatus, AssociateSubpicture_pre31,
+    (VADriverContextP ctx, VASubpictureID subpicture,
+     VASurfaceID *target_surfaces, int num_surfaces,
+     short srcx, short srcy, unsigned short srcw, unsigned short srch,
+     short destx, short desty, unsigned short destw, unsigned short desth,
+     unsigned int flags),
+    AssociateSubpicture2_pre31,
+    (ctx, subpicture, target_surfaces, num_surfaces,
+     srcx, srcy, srcw, srch, destx, desty, destw, desth, flags),
+    {}, {})
+
+DEFINE_VTABLE_ENTRY_(
+    VAStatus, CreateContext_pre31,
+    (VADriverContextP ctx, VAConfigID config_id,
+     int picture_width, int picture_height, int flag,
+     VASurfaceID *render_targets, int num_render_targets, VAContextID *context),
+    CreateContext,
+    (ctx, config_id, picture_width, picture_height, flag,
+     render_targets, num_render_targets, context),
+    {}, {
+        VACompatContextP const compat_ctx = COMPAT_CTX(ctx);
+        int i;
+        for (i = 0; i < num_render_targets; i++)
+            va_context_map_add(compat_ctx, *context, render_targets[i]);
+    })
+
+DEFINE_VTABLE_ENTRY_(
+    VAStatus, DestroyContext_pre31,
+    (VADriverContextP ctx, VAContextID context),
+    DestroyContext,
+    (ctx, context),
+    {}, { va_context_map_remove(COMPAT_CTX(ctx), context); })
+
+#if 0
+DEFINE_VTABLE_ENTRY(
+    VAStatus, BufferInfo,
+    (VADriverContextP ctx, VAContextID context, VABufferID buf_id,
+     VABufferType *type, unsigned int *size, unsigned int *num_elements),
+    (ctx, context, buf_id, type, size, num_elements))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, LockSurface,
+    (VADriverContextP ctx, VASurfaceID surface, unsigned int *fourcc,
+     unsigned int *luma_stride, unsigned int *chroma_u_stride,
+     unsigned int *chroma_v_stride,
+     unsigned int *luma_offset, unsigned int *chroma_u_offset,
+     unsigned int *chroma_v_offset,
+     unsigned int *buffer_name, void **buffer),
+    (ctx, surface, fourcc,
+     luma_stride, chroma_u_stride, chroma_v_stride,
+     luma_offset, chroma_u_offset, chroma_v_offset,
+     buffer_name, buffer))
+
+DEFINE_VTABLE_ENTRY(
+    VAStatus, UnlockSurface,
+    (VADriverContextP ctx, VASurfaceID surface),
+    (ctx, surface))
+#endif
+
+#undef DEFINE_VTABLE_ENTRY
+#undef DEFINE_VTABLE_ENTRY_
+
+static VAStatus
+va_compat_BufferInfo_default(
+    VADriverContextP ctx,
+    VAContextID      context,
+    VABufferID       buf_id,
+    VABufferType    *type,
+    unsigned int    *size,
+    unsigned int    *num_elements
+)
+{
+    VABufferCompat *compat_buffer;
+    VAStatus status;
+
+    compat_buffer = va_GetBufferCompat(ctx, buf_id);
+    if (!compat_buffer)
+        return VA_STATUS_ERROR_INVALID_BUFFER;
+
+    if (type)         *type         = compat_buffer->type;
+    if (size)         *size         = compat_buffer->size;
+    if (num_elements) *num_elements = compat_buffer->num_elements;
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus
+va_compat_LockSurface_default(
+    VADriverContextP ctx,
+    VASurfaceID      surface,
+    unsigned int    *fourcc,
+    unsigned int    *luma_stride,
+    unsigned int    *chroma_u_stride,
+    unsigned int    *chroma_v_stride,
+    unsigned int    *luma_offset,
+    unsigned int    *chroma_u_offset,
+    unsigned int    *chroma_v_offset,
+    unsigned int    *buffer_name,
+    void           **buffer
+)
+{
+    if (fourcc)          *fourcc          = VA_FOURCC('N','V','1','2');
+    if (luma_stride)     *luma_stride     = 0;
+    if (chroma_u_stride) *chroma_u_stride = 0;
+    if (chroma_v_stride) *chroma_v_stride = 0;
+    if (luma_offset)     *luma_offset     = 0;
+    if (chroma_u_offset) *chroma_u_offset = 0;
+    if (chroma_v_offset) *chroma_v_offset = 0;
+    if (buffer_name)     *buffer_name     = 0;
+    if (buffer)          *buffer          = NULL;
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus
+va_compat_UnlockSurface_default(
+    VADriverContextP ctx,
+    VASurfaceID      surface
+)
+{
+    return VA_STATUS_SUCCESS;
+}
+
+static void va_compat_init_VADriverVTable(VADriverContextP ctx, int compat_version)
+{
+#define INIT_VTABLE_(CTX, DST_PROC, SRC_PROC) \
+    (CTX)->vtable.va##DST_PROC = va_compat_##SRC_PROC
+#define INIT_VTABLE(CTX, PROC) \
+    INIT_VTABLE_(CTX, PROC, PROC)
+
+    INIT_VTABLE(ctx, Terminate);
+    INIT_VTABLE(ctx, QueryConfigProfiles);
+    INIT_VTABLE(ctx, QueryConfigEntrypoints);
+    INIT_VTABLE(ctx, GetConfigAttributes);
+    INIT_VTABLE(ctx, CreateConfig);
+    INIT_VTABLE(ctx, DestroyConfig);
+    INIT_VTABLE(ctx, QueryConfigAttributes);
+    INIT_VTABLE(ctx, CreateSurfaces);
+    INIT_VTABLE(ctx, DestroySurfaces);
+    INIT_VTABLE(ctx, CreateContext);
+    INIT_VTABLE(ctx, DestroyContext);
+    INIT_VTABLE(ctx, CreateBuffer);
+    INIT_VTABLE(ctx, BufferSetNumElements);
+    INIT_VTABLE(ctx, MapBuffer);
+    INIT_VTABLE(ctx, UnmapBuffer);
+    INIT_VTABLE(ctx, DestroyBuffer);
+    INIT_VTABLE(ctx, BeginPicture);
+    INIT_VTABLE(ctx, RenderPicture);
+    INIT_VTABLE(ctx, EndPicture);
+    INIT_VTABLE(ctx, SyncSurface);
+    INIT_VTABLE(ctx, QuerySurfaceStatus);
+    INIT_VTABLE(ctx, PutSurface);
+    INIT_VTABLE(ctx, QueryImageFormats);
+    INIT_VTABLE(ctx, CreateImage);
+    INIT_VTABLE(ctx, DeriveImage);
+    INIT_VTABLE(ctx, DestroyImage);
+    INIT_VTABLE(ctx, SetImagePalette);
+    INIT_VTABLE(ctx, GetImage);
+    INIT_VTABLE(ctx, PutImage);
+    INIT_VTABLE(ctx, QuerySubpictureFormats);
+    INIT_VTABLE(ctx, CreateSubpicture);
+    INIT_VTABLE(ctx, DestroySubpicture);
+    INIT_VTABLE(ctx, SetSubpictureImage);
+    INIT_VTABLE(ctx, SetSubpictureChromakey);
+    INIT_VTABLE(ctx, SetSubpictureGlobalAlpha);
+    INIT_VTABLE(ctx, AssociateSubpicture);
+    INIT_VTABLE(ctx, DeassociateSubpicture);
+    INIT_VTABLE(ctx, QueryDisplayAttributes);
+    INIT_VTABLE(ctx, GetDisplayAttributes);
+    INIT_VTABLE(ctx, SetDisplayAttributes);
+
+#if 0
+    /* XXX: vtable_tpi */
+    INIT_VTABLE(ctx, CreateSurfaceFromCIFrame);
+    INIT_VTABLE(ctx, CreateSurfaceFromV4L2Buf);
+    INIT_VTABLE(ctx, CopySurfaceToBuffer);
+#endif
+
+    if (compat_version && compat_version < 31) {
+        INIT_VTABLE_(ctx, CreateContext,        CreateContext_pre31);
+        INIT_VTABLE_(ctx, DestroyContext,       DestroyContext_pre31);
+        INIT_VTABLE_(ctx, SyncSurface,          SyncSurface_pre31);
+        INIT_VTABLE_(ctx, PutImage,             PutImage_pre31);
+        INIT_VTABLE_(ctx, AssociateSubpicture,  AssociateSubpicture_pre31);
+    }
+
+#undef INIT_VTABLE
+#undef INIT_VTABLE__
+
+#define INIT_VTABLE_DEFAULT(CTX, PROC) \
+    (CTX)->vtable.va##PROC = va_compat_##PROC##_default
+
+    /* XXX: this should be 0.32 */
+    INIT_VTABLE_DEFAULT(ctx, BufferInfo);
+    INIT_VTABLE_DEFAULT(ctx, LockSurface);
+    INIT_VTABLE_DEFAULT(ctx, UnlockSurface);
+
+#undef INIT_VTABLE_DEFAULT
+}
+
+VAStatus va_compat_init(VADisplay dpy, int compat_version, void *compat_ctx)
+{
+    VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
+    VADriverContextP ctx = CTX(dpy);
+    VADriverContextP_0_29 ctx_0_29;
+    VADriverContextP_0_30 ctx_0_30;
+    VACompatContextP compat;
+    VAStatus status;
+    char *driver_name;
+
+    ctx->compat                         = NULL;
+
+    if (compat_version == 0)
+        return VA_STATUS_SUCCESS;
+
+    ASSERT(compat_ctx);
+    if (compat_ctx == NULL)
+        return VA_STATUS_ERROR_UNKNOWN;
+
+    driver_name = NULL;
+    status = pDisplayContext->vaGetDriverName(pDisplayContext, &driver_name);
+    ASSERT(status == VA_STATUS_SUCCESS);
+    if (status != VA_STATUS_SUCCESS)
+        return status;
+
+    if ((compat = malloc(sizeof(*compat))) == NULL)
+        return VA_STATUS_ERROR_ALLOCATION_FAILED;
+    compat->buffers                     = NULL;
+    compat->buffers_count_max           = 0;
+    compat->compat_version              = compat_version;
+    compat->compat_ctx                  = NULL;
+    compat->driver_name                 = driver_name;
+    compat->context_map                 = NULL;
+    compat->last_context_map_match      = NULL;
+    ctx->compat                         = compat;
+
+    if (strcmp(driver_name, "psb") == 0)
+        compat->driver_id = VA_DRIVER_ID_POULSBO;
+    else if (strcmp(driver_name, "iegd") == 0)
+        compat->driver_id = VA_DRIVER_ID_IEGD;
+    else
+        compat->driver_id = VA_DRIVER_ID_UNKNOWN;
+
+    switch (compat_version) {
+    case 29:
+        if ((ctx_0_29 = malloc(sizeof(*ctx_0_29))) == NULL)
+            return VA_STATUS_ERROR_ALLOCATION_FAILED;
+        memcpy(ctx_0_29, compat_ctx, sizeof(*ctx_0_29));
+        va_compat_translate_VADriverContext_0_29(compat, ctx_0_29);
+        compat->compat_ctx = ctx_0_29;
+        COPY_FIELD(ctx, ctx_0_29, version_major);
+        COPY_FIELD(ctx, ctx_0_29, version_minor);
+        COPY_FIELD(ctx, ctx_0_29, max_profiles);
+        COPY_FIELD(ctx, ctx_0_29, max_entrypoints);
+        COPY_FIELD(ctx, ctx_0_29, max_attributes);
+        COPY_FIELD(ctx, ctx_0_29, max_image_formats);
+        COPY_FIELD(ctx, ctx_0_29, max_subpic_formats);
+        COPY_FIELD(ctx, ctx_0_29, max_display_attributes);
+        COPY_FIELD(ctx, ctx_0_29, str_vendor);
+        break;
+    case 30:
+        if ((ctx_0_30 = malloc(sizeof(*ctx_0_30))) == NULL)
+            return VA_STATUS_ERROR_ALLOCATION_FAILED;
+        memcpy(ctx_0_30, compat_ctx, sizeof(*ctx_0_30));
+        va_compat_translate_VADriverContext_0_30(compat, ctx_0_30);
+        compat->compat_ctx = ctx_0_30;
+        COPY_FIELD(ctx, ctx_0_30, version_major);
+        COPY_FIELD(ctx, ctx_0_30, version_minor);
+        COPY_FIELD(ctx, ctx_0_30, max_profiles);
+        COPY_FIELD(ctx, ctx_0_30, max_entrypoints);
+        COPY_FIELD(ctx, ctx_0_30, max_attributes);
+        COPY_FIELD(ctx, ctx_0_30, max_image_formats);
+        COPY_FIELD(ctx, ctx_0_30, max_subpic_formats);
+        COPY_FIELD(ctx, ctx_0_30, max_display_attributes);
+        COPY_FIELD(ctx, ctx_0_30, str_vendor);
+        break;
+    case VA_MINOR_VERSION:
+        va_compat_translate_VADriverContext(compat, compat_ctx);
+        compat->compat_ctx = compat_ctx;
+        break;
+    default:
+        ASSERT(compat_version == 0);
+        return VA_STATUS_ERROR_UNKNOWN;
+    }
+
+    va_compat_init_VADriverVTable(ctx, compat_version);
+    return VA_STATUS_SUCCESS;
+}
+
+VAStatus va_compat_fini(VADisplay dpy)
+{
+    VADriverContextP ctx = CTX(dpy);
+    VACompatContextP compat = ctx->compat;
+    int i;
+
+    if (compat == NULL)
+        return VA_STATUS_SUCCESS;
+
+    if (compat->driver_name)
+    {
+        free(compat->driver_name);
+        compat->driver_name = NULL;
+    }
+
+    if (compat->buffers)
+    {
+        for (i = 0; i < compat->buffers_count_max; i++)
+        {
+            if (compat->buffers[i].id && compat->buffers[i].size > 0)
+                va_DestroyBufferCompat(ctx, compat->buffers[i].id);
+        }
+        free(compat->buffers);
+        compat->buffers = NULL;
+    }
+
+    if (compat->compat_ctx && compat->compat_version != VA_MINOR_VERSION)
+    {
+        free(compat->compat_ctx);
+        compat->compat_ctx = NULL;
+    }
+
+    if (compat->context_map)
+    {
+        VAContextMapP d, m = compat->context_map;
+        while (m) {
+            d = m;
+            m = m->next;
+            free(d);
+        }
+    }
+    compat->last_context_map_match = NULL;
+
+    free(compat);
+    ctx->compat = NULL;
+    return VA_STATUS_SUCCESS;
+}
diff --git a/va/va_compat.h b/va/va_compat.h
new file mode 100644
index 0000000..2c9d801
--- /dev/null
+++ b/va/va_compat.h
@@ -0,0 +1,1467 @@
+/*
+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_COMPAT_H
+#define VA_COMPAT_H
+
+VAStatus va_compat_init(VADisplay dpy, int compat_version, void *compat_ctx);
+VAStatus va_compat_fini(VADisplay dpy);
+
+/* H.264 Picture (0.29) */
+typedef struct _VAPictureH264_0_29
+{
+    VASurfaceID picture_id;
+    unsigned int flags;
+    unsigned int TopFieldOrderCnt;
+    unsigned int BottomFieldOrderCnt;
+} VAPictureH264_0_29;
+
+/* H.264 Picture Parameter Buffer (0.29) */
+typedef struct _VAPictureParameterBufferH264_0_29
+{
+    VAPictureH264_0_29 CurrPic;
+    VAPictureH264_0_29 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;
+    signed char pic_init_qp_minus26;
+    signed char chroma_qp_index_offset;
+    signed 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			: 2;
+            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_0_29;
+
+/* H.264 Slice Parameter Buffer (0.29) */
+typedef struct _VASliceParameterBufferH264_0_29
+{
+    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 NAL start code for this slice */
+    unsigned int slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX defintions */
+    unsigned short slice_data_bit_offset; /* bit offset from NAL start code to the beginning of slice 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_0_29 RefPicList0[32];	/* See 8.2.4.2 */
+    VAPictureH264_0_29 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_0_29;
+
+/* VC-1 Picture Parameter Buffer (0.29) */
+typedef struct _VAPictureParameterBufferVC1_0_29
+{
+    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 forward_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 bp_mv_type_mb   : 1;    /* PICTURE::MVTYPEMB */
+            unsigned char bp_direct_mb    : 1;    /* PICTURE::DIRECTMB */
+            unsigned char bp_skip_mb      : 1;    /* PICTURE::SKIPMB */  
+            unsigned char bp_field_tx     : 1;    /* PICTURE::FIELDTX */ 
+            unsigned char bp_forward_mb   : 1;    /* PICTURE::FORWARDMB */
+            unsigned char bp_ac_pred      : 1;    /* PICTURE::ACPRED */   
+            unsigned char bp_overflags    : 1;    /* PICTURE::OVERFLAGS */
+        };
+        unsigned char bitplane_present_flag; /* signal what bitplane is being passed via the bitplane buffer */
+    };
+    union {
+        struct {
+            unsigned char reference_distance_flag : 1;/* PICTURE_LAYER::REFDIST_FLAG */
+            unsigned char reference_distance	: 5;/* 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 {
+            VAMvModeVC1 mv_mode              : 3; /* PICTURE_LAYER::MVMODE */
+            VAMvModeVC1 mv_mode2             : 3; /* 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 quantizer     : 2; 	/* ENTRY_POINT_LAYER::QUANTIZER */
+            unsigned char half_qp	: 1; 	/* PICTURE_LAYER::HALFQP */
+            unsigned char pic_quantizer_scale : 5;/* 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_0_29;
+
+/* MPEG-2 Picture Parameter Buffer (0.29) */
+typedef struct _VAPictureParameterBufferMPEG2_0_29
+{
+    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_0_29;
+
+/* MPEG-2 Slice Parameter Buffer (0.29) */
+typedef struct _VASliceParameterBufferMPEG2_0_29
+{
+    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_0_29;
+
+/* MPEG-4 Picture Parameter Buffer (0.29) */
+typedef struct _VAPictureParameterBufferMPEG4_0_29
+{
+    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_0_29;
+
+/* H.264 Picture (0.30) */
+typedef struct _VAPictureH264_0_30
+{
+    VASurfaceID picture_id;
+    unsigned int flags;
+    unsigned int TopFieldOrderCnt;
+    unsigned int BottomFieldOrderCnt;
+} VAPictureH264_0_30;
+
+/* H.264 Picture Parameter Buffer (0.30) */
+typedef struct _VAPictureParameterBufferH264_0_30
+{
+    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 */
+        } bits;
+        unsigned char value;
+    } seq_fields;
+    unsigned char num_slice_groups_minus1;
+    unsigned char slice_group_map_type;
+    signed char pic_init_qp_minus26;
+    signed char chroma_qp_index_offset;
+    signed 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		: 2;
+            unsigned char transform_8x8_mode_flag	: 1;
+            unsigned char field_pic_flag			: 1;
+            unsigned char constrained_intra_pred_flag	: 1;
+        } bits;
+        unsigned char value;
+    } pic_fields;
+    unsigned short frame_num;
+} VAPictureParameterBufferH264_0_30;
+
+/* H.264 Slice Parameter Buffer (0.30) */
+typedef struct _VASliceParameterBufferH264_0_30
+{
+    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 NAL start code for this slice */
+    unsigned int slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX defintions */
+    unsigned short slice_data_bit_offset; /* bit offset from NAL start code to the beginning of slice 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_0_30;
+
+/* VC-1 Picture Parameter Buffer (0.30) */
+typedef struct _VAPictureParameterBufferVC1_0_30
+{
+    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 */
+        } bits;
+        unsigned char value;
+    } 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 luma_flag	: 1; /* ENTRY_POINT_LAYER::RANGE_MAPY_FLAG */
+            unsigned char luma		: 3; /* ENTRY_POINT_LAYER::RANGE_MAPY */
+            unsigned char chroma_flag	: 1; /* ENTRY_POINT_LAYER::RANGE_MAPUV_FLAG */
+            unsigned char chroma		: 3; /* ENTRY_POINT_LAYER::RANGE_MAPUV */
+        } bits;
+        unsigned char value;
+    } 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 */
+        } bits;
+        unsigned char value;
+    } 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 forward_mb	: 1;	/* PICTURE::FORWARDMB */
+            unsigned char ac_pred	: 1;	/* PICTURE::ACPRED */
+            unsigned char overflags	: 1;	/* PICTURE::OVERFLAGS */
+        } flags;
+        unsigned char value;
+    } raw_coding;
+    union {
+        struct {
+            unsigned char bp_mv_type_mb   : 1;    /* PICTURE::MVTYPEMB */
+            unsigned char bp_direct_mb    : 1;    /* PICTURE::DIRECTMB */
+            unsigned char bp_skip_mb      : 1;    /* PICTURE::SKIPMB */  
+            unsigned char bp_field_tx     : 1;    /* PICTURE::FIELDTX */ 
+            unsigned char bp_forward_mb   : 1;    /* PICTURE::FORWARDMB */
+            unsigned char bp_ac_pred      : 1;    /* PICTURE::ACPRED */   
+            unsigned char bp_overflags    : 1;    /* PICTURE::OVERFLAGS */
+        } flags;
+        unsigned char value;
+    } bitplane_present; /* signal what bitplane is being passed via the bitplane buffer */
+    union {
+        struct {
+            unsigned char reference_distance_flag : 1;/* PICTURE_LAYER::REFDIST_FLAG */
+            unsigned char reference_distance	: 5;/* PICTURE_LAYER::REFDIST */
+            unsigned char num_reference_pictures: 1;/* PICTURE_LAYER::NUMREF */
+            unsigned char reference_field_pic_indicator	: 1;/* PICTURE_LAYER::REFFIELD */
+        } bits;
+        unsigned short value;
+    } reference_fields;
+    union {
+        struct {
+            unsigned char mv_mode		: 3; /* PICTURE_LAYER::MVMODE */
+            unsigned char mv_mode2		: 3; /* 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_POCHAR_LAYER::EXTENDED_DMV */
+            unsigned char extended_dmv_range	: 2; /* PICTURE_LAYER::DMVRANGE */
+        } bits;
+        unsigned int value;
+    } mv_fields;
+    union {
+        struct {
+            unsigned char dquant	: 2; 	/* ENTRY_POINT_LAYER::DQUANT */
+            unsigned char quantizer     : 2; 	/* ENTRY_POINT_LAYER::QUANTIZER */
+            unsigned char half_qp	: 1; 	/* PICTURE_LAYER::HALFQP */
+            unsigned char pic_quantizer_scale : 5;/* 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 */
+        } bits;
+        unsigned long value;
+    } 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 */
+        } bits;
+        unsigned short value;
+    } transform_fields;
+} VAPictureParameterBufferVC1_0_30;
+
+/* MPEG-2 Picture Parameter Buffer (0.30) */
+typedef struct _VAPictureParameterBufferMPEG2_0_30
+{
+    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 int intra_dc_precision		: 2; 
+            unsigned int picture_structure		: 2; 
+            unsigned int top_field_first		: 1; 
+            unsigned int frame_pred_frame_dct		: 1; 
+            unsigned int concealment_motion_vectors	: 1;
+            unsigned int q_scale_type			: 1;
+            unsigned int intra_vlc_format		: 1;
+            unsigned int alternate_scan			: 1;
+            unsigned int repeat_first_field		: 1;
+            unsigned int progressive_frame		: 1;
+            unsigned int is_first_field			: 1; /* indicate whether the current field
+                                                              * is the first field for field picture
+                                                              */
+        } bits;
+        unsigned int value;
+    } picture_coding_extension;
+} VAPictureParameterBufferMPEG2_0_30;
+
+/* MPEG-2 Slice Parameter Buffer (0.29) */
+typedef VASliceParameterBufferMPEG2_0_29 VASliceParameterBufferMPEG2_0_30;
+
+/* MPEG-4 Picture Parameter Buffer (0.30) */
+typedef struct _VAPictureParameterBufferMPEG4_0_30
+{
+    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; 
+        } bits;
+        unsigned short value;
+    } 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; 
+        } bits;
+        unsigned short value;
+    } 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_0_30;
+
+/* Encode Slice Parameter Buffer (0.30) */
+typedef struct _VAEncSliceParameterBuffer_0_30
+{
+    unsigned int start_row_number;	/* starting MB row number for this slice */
+    unsigned int slice_height;	/* slice height measured in MB */
+    union {
+        struct {
+            unsigned char is_intra	: 1;
+            unsigned char disable_deblocking_filter_idc : 2;
+        } bits;
+        unsigned char value;
+    } slice_flags;
+} VAEncSliceParameterBuffer_0_30;
+
+/* MPEG-4 Picture Parameter Buffer (0.31) */
+typedef struct _VAPictureParameterBufferMPEG4_0_31
+{
+    unsigned short vop_width;
+    unsigned short vop_height;
+    VASurfaceID forward_reference_picture;
+    VASurfaceID backward_reference_picture;
+    union {
+        struct {
+            unsigned int short_video_header		: 1; 
+            unsigned int chroma_format			: 2; 
+            unsigned int interlaced			: 1; 
+            unsigned int obmc_disable			: 1; 
+            unsigned int sprite_enable			: 2; 
+            unsigned int sprite_warping_accuracy	: 2; 
+            unsigned int quant_type			: 1; 
+            unsigned int quarter_sample			: 1; 
+            unsigned int data_partitioned		: 1; 
+            unsigned int reversible_vlc			: 1; 
+        } bits;
+        unsigned int value;
+    } 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 int vop_coding_type		: 2; 
+            unsigned int backward_reference_vop_coding_type	: 2; 
+            unsigned int vop_rounding_type		: 1; 
+            unsigned int intra_dc_vlc_thr		: 3; 
+            unsigned int top_field_first		: 1; 
+            unsigned int alternate_vertical_scan_flag	: 1; 
+        } bits;
+        unsigned int value;
+    } 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_0_31;
+
+typedef struct VADriverContext_0_29 *VADriverContextP_0_29;
+
+/* Driver VTable (0.29) */
+struct VADriverVTable_0_29
+{
+	VAStatus (*vaTerminate) ( VADriverContextP_0_29 ctx );
+
+	VAStatus (*vaQueryConfigProfiles) (
+		VADriverContextP_0_29 ctx,
+		VAProfile *profile_list,	/* out */
+		int *num_profiles			/* out */
+	);
+
+	VAStatus (*vaQueryConfigEntrypoints) (
+		VADriverContextP_0_29 ctx,
+		VAProfile profile,
+		VAEntrypoint  *entrypoint_list,	/* out */
+		int *num_entrypoints			/* out */
+	);
+
+	VAStatus (*vaGetConfigAttributes) (
+		VADriverContextP_0_29 ctx,
+		VAProfile profile,
+		VAEntrypoint entrypoint,
+		VAConfigAttrib *attrib_list,	/* in/out */
+		int num_attribs
+	);
+
+	VAStatus (*vaCreateConfig) (
+		VADriverContextP_0_29 ctx,
+		VAProfile profile, 
+		VAEntrypoint entrypoint, 
+		VAConfigAttrib *attrib_list,
+		int num_attribs,
+		VAConfigID *config_id		/* out */
+	);
+
+	VAStatus (*vaDestroyConfig) (
+		VADriverContextP_0_29 ctx,
+		VAConfigID config_id
+	);
+
+	VAStatus (*vaQueryConfigAttributes) (
+		VADriverContextP_0_29 ctx,
+		VAConfigID config_id, 
+		VAProfile *profile,		/* out */
+		VAEntrypoint *entrypoint, 	/* out */
+		VAConfigAttrib *attrib_list,	/* out */
+		int *num_attribs		/* out */
+	);
+
+	VAStatus (*vaCreateSurfaces) (
+		VADriverContextP_0_29 ctx,
+		int width,
+		int height,
+		int format,
+		int num_surfaces,
+		VASurfaceID *surfaces		/* out */
+	);
+
+	VAStatus (*vaDestroySurfaces) (
+		VADriverContextP_0_29 ctx,
+		VASurfaceID *surface_list,
+		int num_surfaces
+	);
+
+	VAStatus (*vaCreateContext) (
+		VADriverContextP_0_29 ctx,
+		VAConfigID config_id,
+		int picture_width,
+		int picture_height,
+		int flag,
+		VASurfaceID *render_targets,
+		int num_render_targets,
+		VAContextID *context		/* out */
+	);
+
+	VAStatus (*vaDestroyContext) (
+		VADriverContextP_0_29 ctx,
+		VAContextID context
+	);
+
+	VAStatus (*vaCreateBuffer) (
+		VADriverContextP_0_29 ctx,
+		VAContextID context,		/* in */
+		VABufferType type,		/* in */
+		unsigned int size,		/* in */
+		unsigned int num_elements,	/* in */
+		void *data,			/* in */
+		VABufferID *buf_id		/* out */
+	);
+
+	VAStatus (*vaBufferSetNumElements) (
+		VADriverContextP_0_29 ctx,
+		VABufferID buf_id,	/* in */
+		unsigned int num_elements	/* in */
+	);
+
+	VAStatus (*vaMapBuffer) (
+		VADriverContextP_0_29 ctx,
+		VABufferID buf_id,	/* in */
+		void **pbuf         /* out */
+	);
+
+	VAStatus (*vaUnmapBuffer) (
+		VADriverContextP_0_29 ctx,
+		VABufferID buf_id	/* in */
+	);
+
+	VAStatus (*vaDestroyBuffer) (
+		VADriverContextP_0_29 ctx,
+		VABufferID buffer_id
+	);
+
+	VAStatus (*vaBeginPicture) (
+		VADriverContextP_0_29 ctx,
+		VAContextID context,
+		VASurfaceID render_target
+	);
+
+	VAStatus (*vaRenderPicture) (
+		VADriverContextP_0_29 ctx,
+		VAContextID context,
+		VABufferID *buffers,
+		int num_buffers
+	);
+
+	VAStatus (*vaEndPicture) (
+		VADriverContextP_0_29 ctx,
+		VAContextID context
+	);
+
+	VAStatus (*vaSyncSurface) (
+		VADriverContextP_0_29 ctx,
+		VAContextID context,
+		VASurfaceID render_target
+	);
+
+	VAStatus (*vaQuerySurfaceStatus) (
+		VADriverContextP_0_29 ctx,
+		VASurfaceID render_target,
+		VASurfaceStatus *status	/* out */
+	);
+
+	VAStatus (*vaPutSurface) (
+    		VADriverContextP_0_29 ctx,
+		VASurfaceID surface,
+		unsigned long draw, /* X Drawable */
+		short srcx,
+		short srcy,
+		unsigned short srcw,
+		unsigned short srch,
+		short destx,
+		short desty,
+		unsigned short destw,
+		unsigned short desth,
+		VARectangle *cliprects, /* client supplied clip list */
+		unsigned int number_cliprects, /* number of clip rects in the clip list */
+		unsigned int flags /* de-interlacing flags */
+	);
+
+	VAStatus (*vaQueryImageFormats) (
+		VADriverContextP_0_29 ctx,
+		VAImageFormat *format_list,        /* out */
+		int *num_formats           /* out */
+	);
+
+	VAStatus (*vaCreateImage) (
+		VADriverContextP_0_29 ctx,
+		VAImageFormat *format,
+		int width,
+		int height,
+		VAImage *image     /* out */
+	);
+
+	VAStatus (*vaDeriveImage) (
+		VADriverContextP_0_29 ctx,
+		VASurfaceID surface,
+		VAImage *image     /* out */
+	);
+
+	VAStatus (*vaDestroyImage) (
+		VADriverContextP_0_29 ctx,
+		VAImageID image
+	);
+	
+	VAStatus (*vaSetImagePalette) (
+	        VADriverContextP_0_29 ctx,
+	        VAImageID image,
+	        /*
+                 * 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 VAImage struct
+                 */
+                unsigned char *palette
+	);
+	
+	VAStatus (*vaGetImage) (
+		VADriverContextP_0_29 ctx,
+		VASurfaceID surface,
+		int x,     /* coordinates of the upper left source pixel */
+		int y,
+		unsigned int width, /* width and height of the region */
+		unsigned int height,
+		VAImageID image
+	);
+
+	VAStatus (*vaPutImage) (
+		VADriverContextP_0_29 ctx,
+		VASurfaceID surface,
+		VAImageID image,
+		int src_x,
+		int src_y,
+		unsigned int width,
+		unsigned int height,
+		int dest_x,
+		int dest_y 
+	);
+
+	VAStatus (*vaPutImage2) (
+		VADriverContextP_0_29 ctx,
+		VASurfaceID surface,
+		VAImageID image,
+		int src_x,
+		int src_y,
+		unsigned int src_width,
+		unsigned int src_height,
+		int dest_x,
+		int dest_y,
+		unsigned int dest_width,
+		unsigned int dest_height
+	);
+
+	VAStatus (*vaQuerySubpictureFormats) (
+		VADriverContextP_0_29 ctx,
+		VAImageFormat *format_list,        /* out */
+		unsigned int *flags,       /* out */
+		unsigned int *num_formats  /* out */
+	);
+
+	VAStatus (*vaCreateSubpicture) (
+		VADriverContextP_0_29 ctx,
+		VAImageID image,
+		VASubpictureID *subpicture   /* out */
+	);
+
+	VAStatus (*vaDestroySubpicture) (
+		VADriverContextP_0_29 ctx,
+		VASubpictureID subpicture
+	);
+
+        VAStatus (*vaSetSubpictureImage) (
+                VADriverContextP_0_29 ctx,
+                VASubpictureID subpicture,
+                VAImageID image
+        );
+        
+	VAStatus (*vaSetSubpicturePalette) (
+		VADriverContextP_0_29 ctx,
+		VASubpictureID 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_0_29 ctx,
+		VASubpictureID subpicture,
+		unsigned int chromakey_min,
+		unsigned int chromakey_max,
+		unsigned int chromakey_mask
+	);
+
+	VAStatus (*vaSetSubpictureGlobalAlpha) (
+		VADriverContextP_0_29 ctx,
+		VASubpictureID subpicture,
+		float global_alpha 
+	);
+
+	VAStatus (*vaAssociateSubpicture) (
+		VADriverContextP_0_29 ctx,
+		VASubpictureID subpicture,
+		VASurfaceID *target_surfaces,
+		int num_surfaces,
+		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 (*vaAssociateSubpicture2) (
+		VADriverContextP_0_29 ctx,
+		VASubpictureID subpicture,
+		VASurfaceID *target_surfaces,
+		int num_surfaces,
+		short src_x, /* upper left offset in subpicture */
+		short src_y,
+		unsigned short src_width,
+		unsigned short src_height,
+		short dest_x, /* upper left offset in surface */
+		short dest_y,
+		unsigned short dest_width,
+		unsigned short dest_height,
+		/*
+		 * whether to enable chroma-keying or global-alpha
+		 * see VA_SUBPICTURE_XXX values
+		 */
+		unsigned int flags
+	);
+
+	VAStatus (*vaDeassociateSubpicture) (
+		VADriverContextP_0_29 ctx,
+		VASubpictureID subpicture,
+		VASurfaceID *target_surfaces,
+		int num_surfaces
+	);
+
+	VAStatus (*vaQueryDisplayAttributes) (
+		VADriverContextP_0_29 ctx,
+		VADisplayAttribute *attr_list,	/* out */
+		int *num_attributes		/* out */
+        );
+
+	VAStatus (*vaGetDisplayAttributes) (
+		VADriverContextP_0_29 ctx,
+		VADisplayAttribute *attr_list,	/* in/out */
+		int num_attributes
+        );
+        
+        VAStatus (*vaSetDisplayAttributes) (
+		VADriverContextP_0_29 ctx,
+                VADisplayAttribute *attr_list,
+                int num_attributes
+        );
+
+
+	VAStatus (*vaDbgCopySurfaceToBuffer) (
+		VADriverContextP_0_29 ctx,
+		VASurfaceID surface,
+		void **buffer, /* out */
+		unsigned int *stride /* out */
+	);
+};
+
+/* Driver context (0.29) */
+struct VADriverContext_0_29
+{
+    void *old_pNext;			/* preserved for binary compatibility */
+
+    void *pDriverData;
+    struct VADriverVTable_0_29 vtable;
+
+    void *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;
+    int max_display_attributes;
+    const char *str_vendor;
+
+    void *handle;			/* dlopen handle */
+};
+
+/* Forward declarations for VA API 0.30 */
+struct v4l2_format;
+struct v4l2_buffer;
+typedef struct VADriverContext_0_30 *VADriverContextP_0_30;
+
+/* Driver VTable (0.30) */
+struct VADriverVTable_0_30
+{
+	VAStatus (*vaTerminate) ( VADriverContextP_0_30 ctx );
+
+	VAStatus (*vaQueryConfigProfiles) (
+		VADriverContextP_0_30 ctx,
+		VAProfile *profile_list,	/* out */
+		int *num_profiles			/* out */
+	);
+
+	VAStatus (*vaQueryConfigEntrypoints) (
+		VADriverContextP_0_30 ctx,
+		VAProfile profile,
+		VAEntrypoint  *entrypoint_list,	/* out */
+		int *num_entrypoints			/* out */
+	);
+
+	VAStatus (*vaGetConfigAttributes) (
+		VADriverContextP_0_30 ctx,
+		VAProfile profile,
+		VAEntrypoint entrypoint,
+		VAConfigAttrib *attrib_list,	/* in/out */
+		int num_attribs
+	);
+
+	VAStatus (*vaCreateConfig) (
+		VADriverContextP_0_30 ctx,
+		VAProfile profile, 
+		VAEntrypoint entrypoint, 
+		VAConfigAttrib *attrib_list,
+		int num_attribs,
+		VAConfigID *config_id		/* out */
+	);
+
+	VAStatus (*vaDestroyConfig) (
+		VADriverContextP_0_30 ctx,
+		VAConfigID config_id
+	);
+
+	VAStatus (*vaQueryConfigAttributes) (
+		VADriverContextP_0_30 ctx,
+		VAConfigID config_id, 
+		VAProfile *profile,		/* out */
+		VAEntrypoint *entrypoint, 	/* out */
+		VAConfigAttrib *attrib_list,	/* out */
+		int *num_attribs		/* out */
+	);
+
+	VAStatus (*vaCreateSurfaces) (
+		VADriverContextP_0_30 ctx,
+		int width,
+		int height,
+		int format,
+		int num_surfaces,
+		VASurfaceID *surfaces		/* out */
+	);
+
+	VAStatus (*vaDestroySurfaces) (
+		VADriverContextP_0_30 ctx,
+		VASurfaceID *surface_list,
+		int num_surfaces
+	);
+
+	VAStatus (*vaCreateContext) (
+		VADriverContextP_0_30 ctx,
+		VAConfigID config_id,
+		int picture_width,
+		int picture_height,
+		int flag,
+		VASurfaceID *render_targets,
+		int num_render_targets,
+		VAContextID *context		/* out */
+	);
+
+	VAStatus (*vaDestroyContext) (
+		VADriverContextP_0_30 ctx,
+		VAContextID context
+	);
+
+	VAStatus (*vaCreateBuffer) (
+		VADriverContextP_0_30 ctx,
+		VAContextID context,		/* in */
+		VABufferType type,		/* in */
+		unsigned int size,		/* in */
+		unsigned int num_elements,	/* in */
+		void *data,			/* in */
+		VABufferID *buf_id		/* out */
+	);
+
+	VAStatus (*vaBufferSetNumElements) (
+		VADriverContextP_0_30 ctx,
+		VABufferID buf_id,	/* in */
+		unsigned int num_elements	/* in */
+	);
+
+	VAStatus (*vaMapBuffer) (
+		VADriverContextP_0_30 ctx,
+		VABufferID buf_id,	/* in */
+		void **pbuf         /* out */
+	);
+
+	VAStatus (*vaUnmapBuffer) (
+		VADriverContextP_0_30 ctx,
+		VABufferID buf_id	/* in */
+	);
+
+	VAStatus (*vaDestroyBuffer) (
+		VADriverContextP_0_30 ctx,
+		VABufferID buffer_id
+	);
+
+	VAStatus (*vaBeginPicture) (
+		VADriverContextP_0_30 ctx,
+		VAContextID context,
+		VASurfaceID render_target
+	);
+
+	VAStatus (*vaRenderPicture) (
+		VADriverContextP_0_30 ctx,
+		VAContextID context,
+		VABufferID *buffers,
+		int num_buffers
+	);
+
+	VAStatus (*vaEndPicture) (
+		VADriverContextP_0_30 ctx,
+		VAContextID context
+	);
+
+	VAStatus (*vaSyncSurface) (
+		VADriverContextP_0_30 ctx,
+		VAContextID context,
+		VASurfaceID render_target
+	);
+
+	VAStatus (*vaQuerySurfaceStatus) (
+		VADriverContextP_0_30 ctx,
+		VASurfaceID render_target,
+		VASurfaceStatus *status	/* out */
+	);
+
+	VAStatus (*vaPutSurface) (
+    		VADriverContextP_0_30 ctx,
+		VASurfaceID surface,
+		unsigned long draw, /* X Drawable */
+		short srcx,
+		short srcy,
+		unsigned short srcw,
+		unsigned short srch,
+		short destx,
+		short desty,
+		unsigned short destw,
+		unsigned short desth,
+		VARectangle *cliprects, /* client supplied clip list */
+		unsigned int number_cliprects, /* number of clip rects in the clip list */
+		unsigned int flags /* de-interlacing flags */
+	);
+
+	VAStatus (*vaQueryImageFormats) (
+		VADriverContextP_0_30 ctx,
+		VAImageFormat *format_list,        /* out */
+		int *num_formats           /* out */
+	);
+
+	VAStatus (*vaCreateImage) (
+		VADriverContextP_0_30 ctx,
+		VAImageFormat *format,
+		int width,
+		int height,
+		VAImage *image     /* out */
+	);
+
+	VAStatus (*vaDeriveImage) (
+		VADriverContextP_0_30 ctx,
+		VASurfaceID surface,
+		VAImage *image     /* out */
+	);
+
+	VAStatus (*vaDestroyImage) (
+		VADriverContextP_0_30 ctx,
+		VAImageID image
+	);
+	
+	VAStatus (*vaSetImagePalette) (
+	        VADriverContextP_0_30 ctx,
+	        VAImageID image,
+	        /*
+                 * 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 VAImage struct
+                 */
+                unsigned char *palette
+	);
+	
+	VAStatus (*vaGetImage) (
+		VADriverContextP_0_30 ctx,
+		VASurfaceID surface,
+		int x,     /* coordinates of the upper left source pixel */
+		int y,
+		unsigned int width, /* width and height of the region */
+		unsigned int height,
+		VAImageID image
+	);
+
+	VAStatus (*vaPutImage) (
+		VADriverContextP_0_30 ctx,
+		VASurfaceID surface,
+		VAImageID image,
+		int src_x,
+		int src_y,
+		unsigned int width,
+		unsigned int height,
+		int dest_x,
+		int dest_y 
+	);
+
+	VAStatus (*vaPutImage2) (
+		VADriverContextP_0_30 ctx,
+		VASurfaceID surface,
+		VAImageID image,
+		int src_x,
+		int src_y,
+		unsigned int src_width,
+		unsigned int src_height,
+		int dest_x,
+		int dest_y,
+		unsigned int dest_width,
+		unsigned int dest_height
+	);
+
+	VAStatus (*vaQuerySubpictureFormats) (
+		VADriverContextP_0_30 ctx,
+		VAImageFormat *format_list,        /* out */
+		unsigned int *flags,       /* out */
+		unsigned int *num_formats  /* out */
+	);
+
+	VAStatus (*vaCreateSubpicture) (
+		VADriverContextP_0_30 ctx,
+		VAImageID image,
+		VASubpictureID *subpicture   /* out */
+	);
+
+	VAStatus (*vaDestroySubpicture) (
+		VADriverContextP_0_30 ctx,
+		VASubpictureID subpicture
+	);
+
+        VAStatus (*vaSetSubpictureImage) (
+                VADriverContextP_0_30 ctx,
+                VASubpictureID subpicture,
+                VAImageID image
+        );
+
+	VAStatus (*vaSetSubpictureChromakey) (
+		VADriverContextP_0_30 ctx,
+		VASubpictureID subpicture,
+		unsigned int chromakey_min,
+		unsigned int chromakey_max,
+		unsigned int chromakey_mask
+	);
+
+	VAStatus (*vaSetSubpictureGlobalAlpha) (
+		VADriverContextP_0_30 ctx,
+		VASubpictureID subpicture,
+		float global_alpha 
+	);
+
+	VAStatus (*vaAssociateSubpicture) (
+		VADriverContextP_0_30 ctx,
+		VASubpictureID subpicture,
+		VASurfaceID *target_surfaces,
+		int num_surfaces,
+		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 (*vaAssociateSubpicture2) (
+		VADriverContextP_0_30 ctx,
+		VASubpictureID subpicture,
+		VASurfaceID *target_surfaces,
+		int num_surfaces,
+		short src_x, /* upper left offset in subpicture */
+		short src_y,
+		unsigned short src_width,
+		unsigned short src_height,
+		short dest_x, /* upper left offset in surface */
+		short dest_y,
+		unsigned short dest_width,
+		unsigned short dest_height,
+		/*
+		 * whether to enable chroma-keying or global-alpha
+		 * see VA_SUBPICTURE_XXX values
+		 */
+		unsigned int flags
+	);
+
+	VAStatus (*vaDeassociateSubpicture) (
+		VADriverContextP_0_30 ctx,
+		VASubpictureID subpicture,
+		VASurfaceID *target_surfaces,
+		int num_surfaces
+	);
+
+	VAStatus (*vaQueryDisplayAttributes) (
+		VADriverContextP_0_30 ctx,
+		VADisplayAttribute *attr_list,	/* out */
+		int *num_attributes		/* out */
+        );
+
+	VAStatus (*vaGetDisplayAttributes) (
+		VADriverContextP_0_30 ctx,
+		VADisplayAttribute *attr_list,	/* in/out */
+		int num_attributes
+        );
+        
+        VAStatus (*vaSetDisplayAttributes) (
+		VADriverContextP_0_30 ctx,
+                VADisplayAttribute *attr_list,
+                int num_attributes
+        );
+
+        /* device specific */
+	VAStatus (*vaCreateSurfaceFromCIFrame) (
+		VADriverContextP_0_30 ctx,
+		unsigned long frame_id,
+		VASurfaceID *surface		/* out */
+	);
+    
+    
+        VAStatus (*vaCreateSurfaceFromV4L2Buf) (
+		VADriverContextP_0_30 ctx,
+                int v4l2_fd,         /* file descriptor of V4L2 device */
+                struct v4l2_format *v4l2_fmt,       /* format of V4L2 */
+                struct v4l2_buffer *v4l2_buf,       /* V4L2 buffer */
+                VASurfaceID *surface	           /* out */
+        );
+    
+        VAStatus (*vaCopySurfaceToBuffer) (
+		VADriverContextP_0_30 ctx,
+                VASurfaceID surface,
+                unsigned int *fourcc, /* out  for follow argument */
+                unsigned int *luma_stride,
+                unsigned int *chroma_u_stride,
+                unsigned int *chroma_v_stride,
+                unsigned int *luma_offset,
+                unsigned int *chroma_u_offset,
+                unsigned int *chroma_v_offset,
+                void **buffer
+        );
+};
+
+/* Driver context (0.30) */
+struct VADriverContext_0_30
+{
+    void *pDriverData;
+    struct VADriverVTable_0_30 vtable;
+
+    void *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;
+    int max_display_attributes;
+    const char *str_vendor;
+
+    void *handle;			/* dlopen handle */
+    
+    void *dri_state;
+};
+
+/* Driver VTable and context (0.31) */
+#define VADriverVTable_0_31     VADriverVTable
+#define VADriverContext_0_31    VADriverContext
+
+#endif /* VA_COMPAT_H */
diff --git a/va/va_compat_template.h b/va/va_compat_template.h
new file mode 100644
index 0000000..ee41aee
--- /dev/null
+++ b/va/va_compat_template.h
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#undef  CONCAT_
+#define CONCAT_(x, y)                   x##y
+#undef  CONCAT
+#define CONCAT(x, y)                    CONCAT_(x, y)
+#undef  MKCOMPAT_
+#define MKCOMPAT_(NAME,MINOR)           CONCAT(CONCAT(NAME,_0_),MINOR)
+#undef  MKCOMPAT
+#define MKCOMPAT(NAME)                  MKCOMPAT_(NAME,COMPAT_MINOR)
+#undef  STRUCT
+#define STRUCT(BUFFER, CODEC)           MKCOMPAT(VA##BUFFER##Buffer##CODEC)
+#undef  TRANSLATE_1
+#define TRANSLATE_1(NAME)               CONCAT(va_compat_translate_,NAME)
+#undef  TRANSLATE_
+#define TRANSLATE_(NAME)                TRANSLATE_1(MKCOMPAT(NAME))
+#undef  TRANSLATE
+#define TRANSLATE(BUFFER, CODEC)        TRANSLATE_1(STRUCT(BUFFER,CODEC))
+
+#undef  COPY_ARRAY
+#define COPY_ARRAY(DST, SRC, ARRAY) \
+    memcpy((DST)->ARRAY, (SRC)->ARRAY, sizeof((DST)->ARRAY))
+
+#undef  COPY_FIELD
+#define COPY_FIELD(DST, SRC, MEMBER) \
+    (DST)->MEMBER = (SRC)->MEMBER
+
+#undef  COPY_VTABLE__
+#define COPY_VTABLE__(DST, DST_MEMBER, SRC, SRC_MEMBER) \
+    (DST##_vtable)->DST_MEMBER = (SRC##_vtable)->SRC_MEMBER
+
+#undef  COPY_VTABLE_
+#define COPY_VTABLE_(DST, DST_SUFFIX, SRC, MEMBER) \
+    COPY_VTABLE__(DST, MEMBER##_##DST_SUFFIX, SRC, MEMBER)
+
+#undef  COPY_VTABLE
+#define COPY_VTABLE(DST, SRC, MEMBER) \
+    COPY_VTABLE__(DST, MEMBER, SRC, MEMBER)
+
+/* 0.29 */
+#if COMPAT_MAJOR == 0 && COMPAT_MINOR == 29
+#undef  BFV
+#define BFV(a, b) a
+#undef  BFM
+#define BFM(a, b, c) c
+#undef  COPY_BIT_FIELD
+#define COPY_BIT_FIELD(DST, SRC, FIELD, MEMBER)  \
+    (DST)->MEMBER = (SRC)->FIELD.bits.MEMBER
+#undef  COPY_BIT_FLAG
+#define COPY_BIT_FLAG(DST, SRC, FIELD, MEMBER)  \
+    (DST)->MEMBER = (SRC)->FIELD.flags.MEMBER
+#endif
+
+/* 0.29 glue to match 0.30 names */
+#undef M_raw_coding
+#undef M_bitplane_present
+#undef M_luma_flag
+#undef M_luma
+#undef M_chroma_flag
+#undef M_chroma
+
+#if COMPAT_MAJOR == 0 && COMPAT_MINOR == 29
+#define M_raw_coding            raw_coding_flag
+#define M_bitplane_present      bitplane_present_flag
+#define M_luma_flag             range_mapping_luma_flag
+#define M_luma                  range_mapping_luma
+#define M_chroma_flag           range_mapping_chroma_flag
+#define M_chroma                range_mapping_chroma
+#else
+#define M_raw_coding            raw_coding
+#define M_bitplane_present      bitplane_present
+#define M_luma_flag             luma_flag
+#define M_luma                  luma
+#define M_chroma_flag           chroma_flag
+#define M_chroma                chroma
+#endif
+
+/* 0.30 */
+#if COMPAT_MAJOR == 0 && COMPAT_MINOR == 30
+#undef  BFV
+#define BFV(a, b) a.b
+#undef  BFM
+#define BFM(a, b, c) a.b.c
+#undef  COPY_BIT_FIELD
+#define COPY_BIT_FIELD(DST, SRC, FIELD, MEMBER)  \
+    (DST)->FIELD.bits.MEMBER = (SRC)->FIELD.bits.MEMBER
+#undef  COPY_BIT_FLAG
+#define COPY_BIT_FLAG(DST, SRC, FIELD, MEMBER)  \
+    (DST)->FIELD.flags.MEMBER = (SRC)->FIELD.flags.MEMBER
+#endif
+
+#if COMPAT_MAJOR == 0 && COMPAT_MINOR < 31
+static VAStatus TRANSLATE_(VAPictureH264)(
+    VACompatContextP    ctx,
+    void               *dest_pic,
+    const void         *src_pic
+)
+{
+    MKCOMPAT(VAPictureH264) *dest = dest_pic;
+    const VAPictureH264 *src = src_pic;
+
+    COPY_FIELD(dest, src, picture_id);
+    COPY_FIELD(dest, src, flags);
+    COPY_FIELD(dest, src, TopFieldOrderCnt);
+    COPY_FIELD(dest, src, BottomFieldOrderCnt);
+
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus TRANSLATE(PictureParameter,H264)(
+    VACompatContextP    ctx,
+    void               *dest_buffer,
+    const void         *src_buffer
+)
+{
+    STRUCT(PictureParameter,H264) *dest = dest_buffer;
+    const VAPictureParameterBufferH264 *src = src_buffer;
+    VAStatus status;
+    int i;
+
+    status = TRANSLATE_(VAPictureH264)(ctx,
+                                      &dest->CurrPic, &src->CurrPic);
+    if (status != VA_STATUS_SUCCESS)
+        return status;
+
+    for (i = 0; i < 16; i++) {
+        status = TRANSLATE_(VAPictureH264)(ctx,
+                                           &dest->ReferenceFrames[i],
+                                           &src->ReferenceFrames[i]);
+        if (status != VA_STATUS_SUCCESS)
+            return status;
+    }
+
+    COPY_FIELD(dest, src, picture_width_in_mbs_minus1);
+    COPY_FIELD(dest, src, picture_height_in_mbs_minus1);
+    COPY_FIELD(dest, src, bit_depth_luma_minus8);
+    COPY_FIELD(dest, src, bit_depth_chroma_minus8);
+    COPY_FIELD(dest, src, num_ref_frames);
+    dest->BFV(seq_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, seq_fields, chroma_format_idc);
+    COPY_BIT_FIELD(dest, src, seq_fields, residual_colour_transform_flag);
+    COPY_BIT_FIELD(dest, src, seq_fields, frame_mbs_only_flag);
+    COPY_BIT_FIELD(dest, src, seq_fields, mb_adaptive_frame_field_flag);
+    COPY_BIT_FIELD(dest, src, seq_fields, direct_8x8_inference_flag);
+    COPY_BIT_FIELD(dest, src, seq_fields, MinLumaBiPredSize8x8);
+    COPY_FIELD(dest, src, num_slice_groups_minus1);
+    COPY_FIELD(dest, src, slice_group_map_type);
+    COPY_FIELD(dest, src, pic_init_qp_minus26);
+    COPY_FIELD(dest, src, chroma_qp_index_offset);
+    COPY_FIELD(dest, src, second_chroma_qp_index_offset);
+    dest->BFV(pic_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, pic_fields, entropy_coding_mode_flag);
+    COPY_BIT_FIELD(dest, src, pic_fields, weighted_pred_flag);
+    COPY_BIT_FIELD(dest, src, pic_fields, weighted_bipred_idc);
+    COPY_BIT_FIELD(dest, src, pic_fields, transform_8x8_mode_flag);
+    COPY_BIT_FIELD(dest, src, pic_fields, field_pic_flag);
+    COPY_BIT_FIELD(dest, src, pic_fields, constrained_intra_pred_flag);
+    COPY_FIELD(dest, src, frame_num);
+
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus TRANSLATE(SliceParameter,H264)(
+    VACompatContextP    ctx,
+    void               *dest_buffer,
+    const void         *src_buffer
+)
+{
+    STRUCT(SliceParameter,H264) *dest = dest_buffer;
+    const VASliceParameterBufferH264 *src = src_buffer;
+    VAStatus status;
+    int i;
+
+    COPY_FIELD(dest, src, slice_data_size);
+    COPY_FIELD(dest, src, slice_data_offset);
+    COPY_FIELD(dest, src, slice_data_flag);
+    COPY_FIELD(dest, src, slice_data_bit_offset);
+    COPY_FIELD(dest, src, first_mb_in_slice);
+    COPY_FIELD(dest, src, slice_type);
+    COPY_FIELD(dest, src, direct_spatial_mv_pred_flag);
+    COPY_FIELD(dest, src, num_ref_idx_l0_active_minus1);
+    COPY_FIELD(dest, src, num_ref_idx_l1_active_minus1);
+    COPY_FIELD(dest, src, cabac_init_idc);
+    COPY_FIELD(dest, src, slice_qp_delta);
+    COPY_FIELD(dest, src, disable_deblocking_filter_idc);
+    COPY_FIELD(dest, src, slice_alpha_c0_offset_div2);
+    COPY_FIELD(dest, src, slice_beta_offset_div2);
+    for (i = 0; i < 32; i++) {
+        status = TRANSLATE_(VAPictureH264)(ctx,
+                                           &dest->RefPicList0[i],
+                                           &src->RefPicList0[i]);
+        if (status != VA_STATUS_SUCCESS)
+            return status;
+        status = TRANSLATE_(VAPictureH264)(ctx,
+                                           &dest->RefPicList1[i],
+                                           &src->RefPicList1[i]);
+        if (status != VA_STATUS_SUCCESS)
+            return status;
+    }
+    COPY_FIELD(dest, src, luma_log2_weight_denom);
+    COPY_FIELD(dest, src, chroma_log2_weight_denom);
+    COPY_FIELD(dest, src, luma_weight_l0_flag);
+    COPY_ARRAY(dest, src, luma_weight_l0);
+    COPY_ARRAY(dest, src, luma_offset_l0);
+    COPY_FIELD(dest, src, chroma_weight_l0_flag);
+    COPY_ARRAY(dest, src, chroma_weight_l0);
+    COPY_ARRAY(dest, src, chroma_offset_l0);
+    COPY_FIELD(dest, src, luma_weight_l1_flag);
+    COPY_ARRAY(dest, src, luma_weight_l1);
+    COPY_ARRAY(dest, src, luma_offset_l1);
+    COPY_FIELD(dest, src, chroma_weight_l1_flag);
+    COPY_ARRAY(dest, src, chroma_weight_l1);
+    COPY_ARRAY(dest, src, chroma_offset_l1);
+
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus TRANSLATE(PictureParameter,VC1)(
+    VACompatContextP    ctx,
+    void               *dest_buffer,
+    const void         *src_buffer
+)
+{
+    STRUCT(PictureParameter,VC1) *dest = dest_buffer;
+    const VAPictureParameterBufferVC1 *src = src_buffer;
+
+    COPY_FIELD(dest, src, forward_reference_picture);
+    COPY_FIELD(dest, src, backward_reference_picture);
+    COPY_FIELD(dest, src, inloop_decoded_picture);
+    dest->BFV(sequence_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, sequence_fields, interlace);
+    COPY_BIT_FIELD(dest, src, sequence_fields, syncmarker);
+    COPY_BIT_FIELD(dest, src, sequence_fields, overlap);
+    COPY_FIELD(dest, src, coded_width);
+    COPY_FIELD(dest, src, coded_height);
+#if COMPAT_MAJOR == 0 && COMPAT_MINOR == 30
+    dest->closed_entry = src->entrypoint_fields.bits.closed_entry;
+    dest->broken_link  = src->entrypoint_fields.bits.broken_link;
+    dest->loopfilter   = src->entrypoint_fields.bits.loopfilter;
+#else
+    COPY_BIT_FIELD(dest, src, entrypoint_fields, closed_entry);
+    COPY_BIT_FIELD(dest, src, entrypoint_fields, broken_link);
+    COPY_BIT_FIELD(dest, src, entrypoint_fields, loopfilter);
+#endif
+    COPY_FIELD(dest, src, conditional_overlap_flag);
+    COPY_FIELD(dest, src, fast_uvmc_flag);
+    dest->BFV(range_mapping_fields, value) = 0; /* reset all bits */
+    dest->BFM(range_mapping_fields, bits, M_luma_flag) =
+        src->range_mapping_fields.bits.luma_flag;
+    dest->BFM(range_mapping_fields, bits, M_luma) =
+        src->range_mapping_fields.bits.luma;
+    dest->BFM(range_mapping_fields, bits, M_chroma_flag) =
+        src->range_mapping_fields.bits.chroma_flag;
+    dest->BFM(range_mapping_fields, bits, M_chroma) =
+        src->range_mapping_fields.bits.chroma;
+    COPY_FIELD(dest, src, b_picture_fraction);
+    COPY_FIELD(dest, src, cbp_table);
+    COPY_FIELD(dest, src, mb_mode_table);
+    COPY_FIELD(dest, src, range_reduction_frame);
+    COPY_FIELD(dest, src, rounding_control);
+    COPY_FIELD(dest, src, post_processing);
+    COPY_FIELD(dest, src, picture_resolution_index);
+    COPY_FIELD(dest, src, luma_scale);
+    COPY_FIELD(dest, src, luma_shift);
+    dest->BFV(picture_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, picture_fields, picture_type);
+    COPY_BIT_FIELD(dest, src, picture_fields, frame_coding_mode);
+    COPY_BIT_FIELD(dest, src, picture_fields, top_field_first);
+    COPY_BIT_FIELD(dest, src, picture_fields, is_first_field);
+    COPY_BIT_FIELD(dest, src, picture_fields, intensity_compensation);
+    dest->BFV(M_raw_coding, value) = 0; /* reset all bits */
+    COPY_BIT_FLAG(dest, src, raw_coding, mv_type_mb);
+    COPY_BIT_FLAG(dest, src, raw_coding, direct_mb);
+    COPY_BIT_FLAG(dest, src, raw_coding, skip_mb);
+    COPY_BIT_FLAG(dest, src, raw_coding, field_tx);
+    COPY_BIT_FLAG(dest, src, raw_coding, forward_mb);
+    COPY_BIT_FLAG(dest, src, raw_coding, ac_pred);
+    COPY_BIT_FLAG(dest, src, raw_coding, overflags);
+    dest->BFV(M_bitplane_present, value) = 0; /* reset all bits */
+    COPY_BIT_FLAG(dest, src, bitplane_present, bp_mv_type_mb);
+    COPY_BIT_FLAG(dest, src, bitplane_present, bp_direct_mb);
+    COPY_BIT_FLAG(dest, src, bitplane_present, bp_skip_mb);
+    COPY_BIT_FLAG(dest, src, bitplane_present, bp_field_tx);
+    COPY_BIT_FLAG(dest, src, bitplane_present, bp_forward_mb);
+    COPY_BIT_FLAG(dest, src, bitplane_present, bp_ac_pred);
+    COPY_BIT_FLAG(dest, src, bitplane_present, bp_overflags);
+    dest->BFV(reference_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, reference_fields, reference_distance_flag);
+    COPY_BIT_FIELD(dest, src, reference_fields, reference_distance);
+    COPY_BIT_FIELD(dest, src, reference_fields, num_reference_pictures);
+    COPY_BIT_FIELD(dest, src, reference_fields, reference_field_pic_indicator);
+    dest->BFV(mv_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, mv_fields, mv_mode);
+    COPY_BIT_FIELD(dest, src, mv_fields, mv_mode2);
+    COPY_BIT_FIELD(dest, src, mv_fields, mv_table);
+    COPY_BIT_FIELD(dest, src, mv_fields, two_mv_block_pattern_table);
+    COPY_BIT_FIELD(dest, src, mv_fields, four_mv_switch);
+    COPY_BIT_FIELD(dest, src, mv_fields, four_mv_block_pattern_table);
+    COPY_BIT_FIELD(dest, src, mv_fields, extended_mv_flag);
+    COPY_BIT_FIELD(dest, src, mv_fields, extended_mv_range);
+    COPY_BIT_FIELD(dest, src, mv_fields, extended_dmv_flag);
+    COPY_BIT_FIELD(dest, src, mv_fields, extended_dmv_range);
+    dest->BFV(pic_quantizer_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, dquant);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, quantizer);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, half_qp);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, pic_quantizer_scale);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, pic_quantizer_type);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, dq_frame);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, dq_profile);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, dq_sb_edge);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, dq_db_edge);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, dq_binary_level);
+    COPY_BIT_FIELD(dest, src, pic_quantizer_fields, alt_pic_quantizer);
+    dest->BFV(transform_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, transform_fields, variable_sized_transform_flag);
+    COPY_BIT_FIELD(dest, src, transform_fields, mb_level_transform_type_flag);
+    COPY_BIT_FIELD(dest, src, transform_fields, frame_level_transform_type);
+    COPY_BIT_FIELD(dest, src, transform_fields, transform_ac_codingset_idx1);
+    COPY_BIT_FIELD(dest, src, transform_fields, transform_ac_codingset_idx2);
+    COPY_BIT_FIELD(dest, src, transform_fields, intra_transform_dc_table);
+
+    if (src->picture_fields.bits.picture_type == 4) {
+        dest->BFM(picture_fields, bits, picture_type) = 1; /* P-frame */
+        ctx->skip_frame = 1;
+    }
+
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus TRANSLATE(PictureParameter,MPEG2)(
+    VACompatContextP    ctx,
+    void               *dest_buffer,
+    const void         *src_buffer
+)
+{
+    STRUCT(PictureParameter,MPEG2) *dest = dest_buffer;
+    const VAPictureParameterBufferMPEG2 *src = src_buffer;
+
+    COPY_FIELD(dest, src, horizontal_size);
+    COPY_FIELD(dest, src, vertical_size);
+    COPY_FIELD(dest, src, forward_reference_picture);
+    COPY_FIELD(dest, src, backward_reference_picture);
+    COPY_FIELD(dest, src, picture_coding_type);
+    COPY_FIELD(dest, src, f_code);
+    dest->BFV(picture_coding_extension, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, intra_dc_precision);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, picture_structure);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, top_field_first);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, frame_pred_frame_dct);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, concealment_motion_vectors);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, q_scale_type);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, intra_vlc_format);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, alternate_scan);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, repeat_first_field);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, progressive_frame);
+    COPY_BIT_FIELD(dest, src, picture_coding_extension, is_first_field);
+
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus TRANSLATE(SliceParameter,MPEG2)(
+    VACompatContextP    ctx,
+    void               *dest_buffer,
+    const void         *src_buffer
+)
+{
+    STRUCT(SliceParameter,MPEG2) *dest = dest_buffer;
+    const VASliceParameterBufferMPEG2 *src = src_buffer;
+
+    COPY_FIELD(dest, src, slice_data_size);
+    COPY_FIELD(dest, src, slice_data_offset);
+    COPY_FIELD(dest, src, slice_data_flag);
+    COPY_FIELD(dest, src, macroblock_offset);
+    COPY_FIELD(dest, src, slice_vertical_position);
+    COPY_FIELD(dest, src, quantiser_scale_code);
+    COPY_FIELD(dest, src, intra_slice_flag);
+
+    return VA_STATUS_SUCCESS;
+}
+#endif
+
+static VAStatus TRANSLATE(PictureParameter,MPEG4)(
+    VACompatContextP    ctx,
+    void               *dest_buffer,
+    const void         *src_buffer
+)
+{
+    STRUCT(PictureParameter,MPEG4) *dest = dest_buffer;
+    const VAPictureParameterBufferMPEG4 *src = src_buffer;
+
+    COPY_FIELD(dest, src, vop_width);
+    COPY_FIELD(dest, src, vop_height);
+    COPY_FIELD(dest, src, forward_reference_picture);
+    COPY_FIELD(dest, src, backward_reference_picture);
+    dest->BFV(vol_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, vol_fields, short_video_header);
+    COPY_BIT_FIELD(dest, src, vol_fields, chroma_format);
+    COPY_BIT_FIELD(dest, src, vol_fields, interlaced);
+    COPY_BIT_FIELD(dest, src, vol_fields, obmc_disable);
+    COPY_BIT_FIELD(dest, src, vol_fields, sprite_enable);
+    COPY_BIT_FIELD(dest, src, vol_fields, sprite_warping_accuracy);
+    COPY_BIT_FIELD(dest, src, vol_fields, quant_type);
+    COPY_BIT_FIELD(dest, src, vol_fields, quarter_sample);
+    COPY_BIT_FIELD(dest, src, vol_fields, data_partitioned);
+    COPY_BIT_FIELD(dest, src, vol_fields, reversible_vlc);
+    COPY_FIELD(dest, src, no_of_sprite_warping_points);
+    COPY_ARRAY(dest, src, sprite_trajectory_du);
+    COPY_ARRAY(dest, src, sprite_trajectory_dv);
+    COPY_FIELD(dest, src, quant_precision);
+    dest->BFV(vop_fields, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, vop_fields, vop_coding_type);
+    COPY_BIT_FIELD(dest, src, vop_fields, backward_reference_vop_coding_type);
+    COPY_BIT_FIELD(dest, src, vop_fields, vop_rounding_type);
+    COPY_BIT_FIELD(dest, src, vop_fields, intra_dc_vlc_thr);
+    COPY_BIT_FIELD(dest, src, vop_fields, top_field_first);
+    COPY_BIT_FIELD(dest, src, vop_fields, alternate_vertical_scan_flag);
+    COPY_FIELD(dest, src, vop_fcode_forward);
+    COPY_FIELD(dest, src, vop_fcode_backward);
+    COPY_FIELD(dest, src, num_gobs_in_vop);
+    COPY_FIELD(dest, src, num_macroblocks_in_gob);
+    COPY_FIELD(dest, src, TRB);
+    COPY_FIELD(dest, src, TRD);
+
+    return VA_STATUS_SUCCESS;
+}
+
+#if COMPAT_MAJOR == 0 && COMPAT_MINOR == 30
+static VAStatus TRANSLATE_(VAEncSliceParameterBuffer)(
+    VACompatContextP    ctx,
+    void               *dest_buffer,
+    const void         *src_buffer
+)
+{
+    MKCOMPAT(VAEncSliceParameterBuffer) * const dest = dest_buffer;
+    const VAEncSliceParameterBuffer * const src = src_buffer;
+
+    COPY_FIELD(dest, src, start_row_number);
+    COPY_FIELD(dest, src, slice_height);
+    dest->BFV(slice_flags, value) = 0; /* reset all bits */
+    COPY_BIT_FIELD(dest, src, slice_flags, is_intra);
+    COPY_BIT_FIELD(dest, src, slice_flags, disable_deblocking_filter_idc);
+
+    return VA_STATUS_SUCCESS;
+}
+#endif
+
+static void TRANSLATE_(VADriverContext)(
+    VACompatContext *dest,
+    const struct MKCOMPAT(VADriverContext) *src
+)
+{
+    VACompatDriverVTable *dest_vtable = &dest->vtable;
+    const struct MKCOMPAT(VADriverVTable) *src_vtable = &src->vtable;
+
+    memset(dest_vtable, 0, sizeof(*dest_vtable));
+    COPY_VTABLE(dest, src, vaTerminate);
+    COPY_VTABLE(dest, src, vaQueryConfigProfiles);
+    COPY_VTABLE(dest, src, vaQueryConfigEntrypoints);
+    COPY_VTABLE(dest, src, vaGetConfigAttributes);
+    COPY_VTABLE(dest, src, vaCreateConfig);
+    COPY_VTABLE(dest, src, vaDestroyConfig);
+    COPY_VTABLE(dest, src, vaQueryConfigAttributes);
+    COPY_VTABLE(dest, src, vaCreateSurfaces);
+    COPY_VTABLE(dest, src, vaDestroySurfaces);
+    COPY_VTABLE(dest, src, vaCreateContext);
+    COPY_VTABLE(dest, src, vaDestroyContext);
+    COPY_VTABLE(dest, src, vaCreateBuffer);
+    COPY_VTABLE(dest, src, vaBufferSetNumElements);
+    COPY_VTABLE(dest, src, vaMapBuffer);
+    COPY_VTABLE(dest, src, vaUnmapBuffer);
+    COPY_VTABLE(dest, src, vaDestroyBuffer);
+    COPY_VTABLE(dest, src, vaBeginPicture);
+    COPY_VTABLE(dest, src, vaRenderPicture);
+    COPY_VTABLE(dest, src, vaEndPicture);
+    COPY_VTABLE(dest, src, vaQuerySurfaceStatus);
+    COPY_VTABLE(dest, src, vaPutSurface);
+    COPY_VTABLE(dest, src, vaQueryImageFormats);
+    COPY_VTABLE(dest, src, vaCreateImage);
+    COPY_VTABLE(dest, src, vaDeriveImage);
+    COPY_VTABLE(dest, src, vaDestroyImage);
+    COPY_VTABLE(dest, src, vaSetImagePalette);
+    COPY_VTABLE(dest, src, vaGetImage);
+    COPY_VTABLE(dest, src, vaQuerySubpictureFormats);
+    COPY_VTABLE(dest, src, vaCreateSubpicture);
+    COPY_VTABLE(dest, src, vaDestroySubpicture);
+    COPY_VTABLE(dest, src, vaSetSubpictureImage);
+    COPY_VTABLE(dest, src, vaSetSubpictureChromakey);
+    COPY_VTABLE(dest, src, vaSetSubpictureGlobalAlpha);
+    COPY_VTABLE(dest, src, vaDeassociateSubpicture);
+    COPY_VTABLE(dest, src, vaQueryDisplayAttributes);
+    COPY_VTABLE(dest, src, vaGetDisplayAttributes);
+    COPY_VTABLE(dest, src, vaSetDisplayAttributes);
+#if COMPAT_MAJOR == 0 && COMPAT_MINOR <= 29
+    COPY_VTABLE(dest, src, vaSetSubpicturePalette);
+    COPY_VTABLE(dest, src, vaDbgCopySurfaceToBuffer);
+#endif
+#if COMPAT_MAJOR == 0 && COMPAT_MINOR >= 30 && 0
+    COPY_VTABLE(dest, src, vaCreateSurfaceFromCIFrame);
+    COPY_VTABLE(dest, src, vaCreateSurfaceFromV4L2Buf);
+    COPY_VTABLE(dest, src, vaCopySurfaceToBuffer);
+#endif
+#if COMPAT_MAJOR == 0 && COMPAT_MINOR >= 31
+    COPY_VTABLE(dest, src, vaSyncSurface);
+    COPY_VTABLE(dest, src, vaPutImage);
+    COPY_VTABLE(dest, src, vaAssociateSubpicture);
+#else
+    COPY_VTABLE_(dest, pre31, src, vaSyncSurface);
+    COPY_VTABLE_(dest, pre31, src, vaPutImage);
+    COPY_VTABLE_(dest, pre31, src, vaPutImage2);
+    COPY_VTABLE_(dest, pre31, src, vaAssociateSubpicture);
+    COPY_VTABLE_(dest, pre31, src, vaAssociateSubpicture2);
+#endif
+}
+
+#undef COMPAT_MAJOR
+#undef COMPAT_MINOR
