am fb1b2403: am 44dd3ee8: [PORT FROM ICS][libva] modify offsets/pitches components to 3

* commit 'fb1b240358b25efb96792e76b3c461ea428a0061':
diff --git a/.gitignore b/.gitignore
index ac24e17..b155a93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,25 +9,26 @@
 *.pc
 .deps
 .libs
-install-sh
-libtool
-ltmain.sh
-missing
 Makefile
 Makefile.in
-config.h
-config.h.in
-stamp-h1
+TAGS
 aclocal.m4
 autom4te.cache
 config.guess
+config.h
+config.h.in
 config.log
 config.status
 config.sub
 configure
+debian.upstream/changelog
+debian.upstream/control
 depcomp
-TAGS
-/va/va_version.h
+install-sh
+libtool
+ltmain.sh
+missing
+stamp-h1
 /test/basic/test_01
 /test/basic/test_02
 /test/basic/test_03
@@ -39,8 +40,12 @@
 /test/basic/test_09
 /test/basic/test_10
 /test/basic/test_11
+/test/decode/loadjpeg
 /test/decode/mpeg2vldemo
-/test/encode/h264encode
+/test/egl/va_egl
 /test/encode/avcenc
+/test/encode/h264encode
 /test/putsurface/putsurface
-/test/vainfo
+/test/transcode/mpeg2transcode
+/test/vainfo/vainfo
+/va/va_version.h
diff --git a/Makefile.am b/Makefile.am
index 1425b0f..3313df2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,7 +22,7 @@
 
 AUTOMAKE_OPTIONS = foreign
 
-SUBDIRS = va dummy_drv_video pkgconfig test debian.upstream doc
+SUBDIRS = va  pkgconfig test debian.upstream doc
 
 # Extra clean files so that maintainer-clean removes *everything*
 MAINTAINERCLEANFILES = \
diff --git a/autogen.sh b/autogen.sh
index 9c2f4f6..ab04e1d 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,3 +1,51 @@
-#! /bin/sh
-autoreconf -v --install
-./configure "$@"
+#!/bin/sh
+# Copyright (c) 2007 Intel Corporation. All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sub license, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+# 
+# The above copyright notice and this permission notice (including the
+# next paragraph) shall be included in all copies or substantial portions
+# of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+PROJECT="libva"
+
+test -n "$srcdir" || srcdir="`dirname \"$0\"`"
+test -n "$srcdir" || srcdir=.
+
+if ! test -f "$srcdir/configure.ac"; then
+    echo "Failed to find the top-level $PROJECT directory"
+    exit 1
+fi
+
+olddir="`pwd`"
+cd "$srcdir"
+
+mkdir -p m4
+
+AUTORECONF=`which autoreconf`
+if test -z $AUTORECONF; then
+    echo "*** No autoreconf found ***"
+    exit 1
+else
+    autoreconf -v --install || exit $?
+fi
+
+cd "$olddir"
+
+if test -z "$NO_CONFIGURE"; then
+    $srcdir/configure "$@" && echo "Now type 'make' to compile $PROJECT."
+fi
diff --git a/build/gen_version.sh b/build/gen_version.sh
index f594ddd..8864f7d 100644
--- a/build/gen_version.sh
+++ b/build/gen_version.sh
@@ -1,3 +1,25 @@
+# Copyright (c) 2007 Intel Corporation. All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sub license, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+# 
+# The above copyright notice and this permission notice (including the
+# next paragraph) shall be included in all copies or substantial portions
+# of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
 #!/bin/sh
 
 libva_topdir="$1"
diff --git a/configure.ac b/configure.ac
index 4b50912..1d9be8d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,6 +77,9 @@
 # libdrm minimun version requirement
 m4_define([libdrm_version], [2.4])
 
+# Wayland minimum version number
+m4_define([wayland_api_version], [1.0.0])
+
 AC_PREREQ(2.57)
 AC_INIT([libva], [libva_version], [waldo.bastian@intel.com], libva)
 AC_CONFIG_SRCDIR([Makefile.am])
@@ -116,26 +119,30 @@
                     [build Doxygen documentation @<:@default=no@:>@])],
     [], [enable_docs="no"])
 
+AC_ARG_ENABLE(drm,
+    [AC_HELP_STRING([--enable-drm],
+                    [build with VA/DRM API support @<:@default=yes@:>@])],
+    [], [enable_drm="yes"])
+
+AC_ARG_ENABLE(x11,
+    [AC_HELP_STRING([--enable-x11],
+                    [build with VA/X11 API support @<:@default=yes@:>@])],
+    [], [enable_x11="yes"])
+
 AC_ARG_ENABLE(glx,
     [AC_HELP_STRING([--enable-glx],
-                    [build with GLX support @<:@default=yes@:>@])],
+                    [build with VA/GLX API support @<:@default=yes@:>@])],
     [], [enable_glx="yes"])
 
 AC_ARG_ENABLE(egl,
     [AC_HELP_STRING([--enable-egl],
-                    [build with EGL support @<:@default=yes@:>@])],
+                    [build with VA/EGL API support @<:@default=yes@:>@])],
     [], [enable_egl="yes"])
 
-AC_ARG_ENABLE(dummy-driver,
-    [AC_HELP_STRING([--enable-dummy-driver],
-                    [build dummy video driver @<:@default=yes@:>@])],
-    [], [enable_dummy_driver="yes"])
-AM_CONDITIONAL(BUILD_DUMMY_DRIVER, test x$enable_dummy_driver = xyes)
-
-AC_ARG_ENABLE(dummy-backend,
-    [AC_HELP_STRING([--enable-dummy-backend],
-                    [build dummy libva backend])],
-    [], [enable_dummy_backend="no"])
+AC_ARG_ENABLE([wayland],
+    [AC_HELP_STRING([--enable-wayland],
+                    [build with VA/Wayland API support @<:@default=yes@:>@])],
+    [], [enable_wayland="yes"])
 
 AC_ARG_WITH(drivers-path,
     [AC_HELP_STRING([--with-drivers-path=[[path]]],
@@ -149,64 +156,124 @@
 AC_PROG_LIBTOOL
 AC_PROG_CC
 AC_PROG_CXX
+AM_PROG_CC_C_O
+PKG_PROG_PKG_CONFIG
 
 AC_HEADER_STDC
 AC_SYS_LARGEFILE
 
-PKG_CHECK_MODULES([X11], [x11])
-PKG_CHECK_MODULES([XEXT],[xext])
-PKG_CHECK_MODULES([XFIXES], [xfixes])
-
 # Check for Doxygen
 if test "$enable_docs" = "yes"; then
-    AC_CHECK_TOOL([DOXYGEN], [doxygen], [enable_docs="no"])
+    AC_CHECK_TOOL([DOXYGEN], [doxygen], [no])
+    if test "$DOXYGEN" = "no"; then
+       enable_docs="no"
+    fi
 fi
 AM_CONDITIONAL(ENABLE_DOCS, test "$enable_docs" = "yes")
 
-# Check for recent enough DRM
+# Check for __attribute__((visibility()))
+AC_CACHE_CHECK([whether __attribute__((visibility())) is supported],
+    ac_cv_have_gnuc_visibility_attribute,
+    [cat > conftest.c <<EOF
+int foo __attribute__ ((visibility ("hidden"))) = 1;
+int bar __attribute__ ((visibility ("protected"))) = 1;
+EOF
+    ac_cv_have_gnuc_visibility_attribute="no"
+    if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+        if grep '\.hidden.*foo' conftest.s >/dev/null; then
+            if grep '\.protected.*bar' conftest.s >/dev/null; then
+                ac_cv_have_gnuc_visibility_attribute="yes"
+            fi
+        fi
+    fi
+    rm -f conftest.[cs]
+])
+if test "$ac_cv_have_gnuc_visibility_attribute" = "yes"; then
+    AC_DEFINE([HAVE_GNUC_VISIBILITY_ATTRIBUTE], [1],
+              [Defined to 1 if GCC visibility attribute is supported])
+fi
+
+
+# Check for DRM (mandatory)
 LIBDRM_VERSION=libdrm_version
 PKG_CHECK_MODULES([DRM], [libdrm >= $LIBDRM_VERSION])
 AC_SUBST(LIBDRM_VERSION)
 
-if test x$enable_dummy_backend = xyes; then
-    PKG_CHECK_MODULES([UDEV], [libudev], [libudev=yes], [libudev=no])
+USE_DRM="no"
+if test "$enable_drm" = "yes"; then
+    USE_DRM="yes"
+    AC_DEFINE([HAVE_VA_DRM], [1], [Defined to 1 if VA/DRM API is built])
 fi
-if test x$libudev = xno; then
-   enable_dummy_backend=no
+AM_CONDITIONAL(USE_DRM, test "$USE_DRM" = "yes")
+
+# Check for X11
+USE_X11="no"
+if test "$enable_x11" = "yes"; then
+    USE_X11="yes"
+    PKG_CHECK_MODULES([X11],    [x11],    [:], [USE_X11="no"])
+    PKG_CHECK_MODULES([XEXT],   [xext],   [:], [USE_X11="no"])
+    PKG_CHECK_MODULES([XFIXES], [xfixes], [:], [USE_X11="no"])
+    if test "$USE_X11" = "yes"; then
+        AC_DEFINE([HAVE_VA_X11], [1], [Defined to 1 if VA/X11 API is built])
+    fi
 fi
-AM_CONDITIONAL(BUILD_DUMMY_BACKEND, test x$enable_dummy_backend = xyes)
+AM_CONDITIONAL(USE_X11, test "$USE_X11" = "yes")
 
 # Check for GLX
 USE_GLX="no"
-GL_DEPS_CFLAGS=""
-GL_DEPS_LIBS=""
-if test x$enable_glx = xyes; then
-    AC_CHECK_HEADERS([GL/gl.h])
-    AC_CHECK_HEADERS([GL/glx.h])
-    AC_CHECK_LIB(GL, glXCreateContext, [
-        USE_GLX="yes"
-        GL_DEPS_LIBS="-lX11 -lGL"
-    ])
+if test "$USE_X11:$enable_glx" = "yes:yes"; then
+    PKG_CHECK_MODULES([GLX], [gl x11], [USE_GLX="yes"], [:])
+    saved_CPPFLAGS="$CPPFLAGS"
+    saved_LIBS="$LIBS"
+    CPPFLAGS="$CPPFLAGS $GLX_CFLAGS"
+    LIBS="$LIBS $GLX_LIBS"
+    AC_CHECK_HEADERS([GL/gl.h GL/glx.h], [:], [USE_GLX="no"])
+    AC_CHECK_LIB([GL], [glXCreateContext], [:] [USE_GLX="no"])
+    CPPFLAGS="$saved_CPPFLAGS"
+    LIBS="$saved_LIBS"
+    if test "$USE_GLX" = "yes"; then
+        AC_DEFINE([HAVE_VA_GLX], [1], [Defined to 1 if VA/GLX API is built])
+    fi
 fi
-AC_SUBST(GL_DEPS_CFLAGS)
-AC_SUBST(GL_DEPS_LIBS)
 AM_CONDITIONAL(USE_GLX, test "$USE_GLX" = "yes")
 
 # Check for EGL
 USE_EGL="no"
-EGL_DEPS_CFLAGS=""
-EGL_DEPS_LIBS=""
 if test "$enable_egl" = "yes"; then
-    AC_CHECK_HEADERS([EGL/egl.h])
-    AC_CHECK_LIB(EGL, eglGetDisplay, [
-        USE_EGL="yes"
-        EGL_DEPS_LIBS="-lEGL"
-    ])
+    PKG_CHECK_MODULES([EGL], [egl], [USE_EGL="yes"], [:])
+    saved_CPPFLAGS="$CPPFLAGS"
+    saved_LIBS="$LIBS"
+    CPPFLAGS="$CPPFLAGS $EGL_CFLAGS"
+    LIBS="$LIBS $EGL_LIBS"
+    AC_CHECK_HEADERS([EGL/egl.h], [:], [USE_EGL="no"])
+    AC_CHECK_LIB([EGL], [eglGetDisplay], [:], [USE_EGL="no"])
+    CPPFLAGS="$saved_CPPFLAGS"
+    LIBS="$saved_LIBS"
+    if test "$USE_EGL" = "yes"; then
+        AC_DEFINE([HAVE_VA_EGL], [1], [Defined to 1 if VA/EGL API is built])
+    fi
 fi
-AC_SUBST(EGL_DEPS_CFLAGS)
-AC_SUBST(EGL_DEPS_LIBS)
 AM_CONDITIONAL(USE_EGL, test "$USE_EGL" = "yes")
 
+# Check for Wayland
+WAYLAND_API_VERSION=wayland_api_version
+AC_SUBST(WAYLAND_API_VERSION)
+
+USE_WAYLAND="no"
+if test "$enable_wayland" = "yes"; then
+    PKG_CHECK_MODULES([WAYLAND], [wayland-client >= wayland_api_version],
+        [USE_WAYLAND="yes"], [:])
+    if test "$USE_WAYLAND" = "yes"; then
+        AC_DEFINE([HAVE_VA_WAYLAND], [1],
+                  [Defined to 1 if VA/Wayland API is built])
+    fi
+fi
+AM_CONDITIONAL(USE_WAYLAND, test "$USE_WAYLAND" = "yes")
+
+m4_ifdef([WAYLAND_SCANNER_RULES],
+    [WAYLAND_SCANNER_RULES(['$(top_srcdir)/va/wayland/protocol'])],
+    [wayland_scanner_rules=""; AC_SUBST(wayland_scanner_rules)])
+
 # We only need the headers, we don't link against the DRM libraries
 LIBVA_CFLAGS="$DRM_CFLAGS"
 AC_SUBST(LIBVA_CFLAGS)
@@ -215,41 +282,47 @@
 pkgconfigdir=${libdir}/pkgconfig
 AC_SUBST(pkgconfigdir)
 
-LIBVA_DISPLAY=x11
-libvacorelib=libva.la
-libvabackendlib=libva-$LIBVA_DISPLAY.la
-AC_SUBST([libvacorelib])
-AC_SUBST([libvabackendlib])
+# Check for builds without backend
+if test "$USE_DRM:$USE_X11:$USE_WAYLAND" = "no:no:no"; then
+    AC_MSG_ERROR([Please select at least one backend (DRM, X11, Wayland)])
+fi
 
 AC_OUTPUT([
     Makefile
     debian.upstream/Makefile
     doc/Makefile
-    dummy_drv_video/Makefile
     pkgconfig/Makefile
+    pkgconfig/libva-drm.pc
     pkgconfig/libva-egl.pc
     pkgconfig/libva-glx.pc
     pkgconfig/libva-tpi.pc
+    pkgconfig/libva-wayland.pc
     pkgconfig/libva-x11.pc
     pkgconfig/libva.pc
     test/Makefile
     test/basic/Makefile
+    test/common/Makefile
     test/decode/Makefile
     test/encode/Makefile
     test/putsurface/Makefile
     test/transcode/Makefile
     test/vainfo/Makefile
     va/Makefile
-    va/dummy/Makefile
+    va/drm/Makefile
     va/egl/Makefile
     va/glx/Makefile
     va/va_version.h
+    va/wayland/Makefile
+    va/wayland/protocol/Makefile
     va/x11/Makefile
 ])
 
 # Print a small summary
+AS_IF([test x$USE_DRM = xyes], [BACKENDS="drm $BACKENDS"])
+AS_IF([test x$USE_X11 = xyes], [BACKENDS="x11 $BACKENDS"])
 AS_IF([test x$USE_GLX = xyes], [BACKENDS="glx $BACKENDS"])
 AS_IF([test x$USE_EGL = xyes], [BACKENDS="egl $BACKENDS"])
+AS_IF([test x$USE_WAYLAND = xyes], [BACKENDS="wayland $BACKENDS"])
 
 echo
 echo "libva - ${LIBVA_VERSION} (VA-API ${VA_API_VERSION})"
@@ -257,7 +330,5 @@
 echo Installation prefix .............. : $prefix
 echo Default driver path .............. : $LIBVA_DRIVERS_PATH
 echo Extra window systems ............. : $BACKENDS
-echo build dummy backend .............. : $enable_dummy_backend
-echo Build dummy driver ............... : $enable_dummy_driver
 echo Build documentation .............. : $enable_docs
 echo
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 2770ecb..2715ed1 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -48,7 +48,14 @@
 html: html-out/index.html
 install-html-local:
 	install -d $(DESTDIR)$(docdir)/html
-	install -m 0644 html-out/* $(DESTDIR)$(docdir)/html
+	for file in `ls html-out/` ; do \
+	    if test -f html-out/$$file ; then \
+		install -m 0644 html-out/$$file $(DESTDIR)$(docdir)/html ; \
+	    else \
+		install -d $(DESTDIR)$(docdir)/html/$$file ; \
+		install -m 0644 html-out/$$file/* $(DESTDIR)$(docdir)/html/$$file; \
+	    fi ; \
+	done
 uninstall-local:
 	rm -rf $(DESTDIR)$(docdir)/html
 endif
diff --git a/dummy_drv_video/Makefile.am b/dummy_drv_video/Makefile.am
deleted file mode 100644
index 245e6e8..0000000
--- a/dummy_drv_video/Makefile.am
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (c) 2007 Intel Corporation. All Rights Reserved.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sub license, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-# 
-# The above copyright notice and this permission notice (including the
-# next paragraph) shall be included in all copies or substantial portions
-# of the Software.
-# 
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-INCLUDES = -I$(top_srcdir)
-
-if BUILD_DUMMY_DRIVER
-dummy_drv_video_la_LTLIBRARIES	= dummy_drv_video.la
-dummy_drv_video_ladir		= $(LIBVA_DRIVERS_PATH)
-dummy_drv_video_la_LDFLAGS	= -module -avoid-version -no-undefined -Wl,--no-undefined
-dummy_drv_video_la_LIBADD	= $(top_builddir)/va/$(libvabackendlib)
-dummy_drv_video_la_DEPENDENCIES	= $(top_builddir)/va/$(libvabackendlib)
-dummy_drv_video_la_SOURCES	= dummy_drv_video.c object_heap.c
-noinst_HEADERS			= dummy_drv_video.h object_heap.h
-endif
diff --git a/dummy_drv_video/dummy_drv_video.c b/dummy_drv_video/dummy_drv_video.c
deleted file mode 100644
index 310fb20..0000000
--- a/dummy_drv_video/dummy_drv_video.c
+++ /dev/null
@@ -1,1277 +0,0 @@
-/*
- * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "config.h"
-#include <va/va_backend.h>
-
-#include "dummy_drv_video.h"
-
-#include "assert.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-#define ASSERT	assert
-
-#define INIT_DRIVER_DATA	struct dummy_driver_data *driver_data = (struct dummy_driver_data *) ctx->pDriverData;
-
-#define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
-#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
-#define SURFACE(id)	((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
-#define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
-
-#define CONFIG_ID_OFFSET		0x01000000
-#define CONTEXT_ID_OFFSET		0x02000000
-#define SURFACE_ID_OFFSET		0x04000000
-#define BUFFER_ID_OFFSET		0x08000000
-
-static void dummy__error_message(const char *msg, ...)
-{
-    va_list args;
-
-    fprintf(stderr, "dummy_drv_video error: ");
-    va_start(args, msg);
-    vfprintf(stderr, msg, args);
-    va_end(args);
-}
-
-static void dummy__information_message(const char *msg, ...)
-{
-    va_list args;
-
-    fprintf(stderr, "dummy_drv_video: ");
-    va_start(args, msg);
-    vfprintf(stderr, msg, args);
-    va_end(args);
-}
-
-VAStatus dummy_QueryConfigProfiles(
-		VADriverContextP ctx,
-		VAProfile *profile_list,	/* out */
-		int *num_profiles			/* out */
-	)
-{
-    INIT_DRIVER_DATA
-    int i = 0;
-
-    profile_list[i++] = VAProfileMPEG2Simple;
-    profile_list[i++] = VAProfileMPEG2Main;
-    profile_list[i++] = VAProfileMPEG4Simple;
-    profile_list[i++] = VAProfileMPEG4AdvancedSimple;
-    profile_list[i++] = VAProfileMPEG4Main;
-    profile_list[i++] = VAProfileH264Baseline;
-    profile_list[i++] = VAProfileH264Main;
-    profile_list[i++] = VAProfileH264High;
-    profile_list[i++] = VAProfileVC1Simple;
-    profile_list[i++] = VAProfileVC1Main;
-    profile_list[i++] = VAProfileVC1Advanced;
-
-    /* If the assert fails then DUMMY_MAX_PROFILES needs to be bigger */
-    ASSERT(i <= DUMMY_MAX_PROFILES);
-    *num_profiles = i;
-
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_QueryConfigEntrypoints(
-		VADriverContextP ctx,
-		VAProfile profile,
-		VAEntrypoint  *entrypoint_list,	/* out */
-		int *num_entrypoints		/* out */
-	)
-{
-    INIT_DRIVER_DATA
-
-    switch (profile) {
-        case VAProfileMPEG2Simple:
-        case VAProfileMPEG2Main:
-                *num_entrypoints = 2;
-                entrypoint_list[0] = VAEntrypointVLD;
-                entrypoint_list[1] = VAEntrypointMoComp;
-                break;
-
-        case VAProfileMPEG4Simple:
-        case VAProfileMPEG4AdvancedSimple:
-        case VAProfileMPEG4Main:
-                *num_entrypoints = 1;
-                entrypoint_list[0] = VAEntrypointVLD;
-                break;
-
-        case VAProfileH264Baseline:
-        case VAProfileH264Main:
-        case VAProfileH264High:
-                *num_entrypoints = 1;
-                entrypoint_list[0] = VAEntrypointVLD;
-                break;
-
-        case VAProfileVC1Simple:
-        case VAProfileVC1Main:
-        case VAProfileVC1Advanced:
-                *num_entrypoints = 1;
-                entrypoint_list[0] = VAEntrypointVLD;
-                break;
-
-        default:
-                *num_entrypoints = 0;
-                break;
-    }
-
-    /* If the assert fails then DUMMY_MAX_ENTRYPOINTS needs to be bigger */
-    ASSERT(*num_entrypoints <= DUMMY_MAX_ENTRYPOINTS);
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_GetConfigAttributes(
-		VADriverContextP ctx,
-		VAProfile profile,
-		VAEntrypoint entrypoint,
-		VAConfigAttrib *attrib_list,	/* in/out */
-		int num_attribs
-	)
-{
-    INIT_DRIVER_DATA
-
-    int i;
-
-    /* Other attributes don't seem to be defined */
-    /* What to do if we don't know the attribute? */
-    for (i = 0; i < num_attribs; i++)
-    {
-        switch (attrib_list[i].type)
-        {
-          case VAConfigAttribRTFormat:
-              attrib_list[i].value = VA_RT_FORMAT_YUV420;
-              break;
-
-          default:
-              /* Do nothing */
-              attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
-              break;
-        }
-    }
-
-    return VA_STATUS_SUCCESS;
-}
-
-static VAStatus dummy__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib)
-{
-    int i;
-    /* Check existing attrbiutes */
-    for(i = 0; obj_config->attrib_count < i; i++)
-    {
-        if (obj_config->attrib_list[i].type == attrib->type)
-        {
-            /* Update existing attribute */
-            obj_config->attrib_list[i].value = attrib->value;
-            return VA_STATUS_SUCCESS;
-        }
-    }
-    if (obj_config->attrib_count < DUMMY_MAX_CONFIG_ATTRIBUTES)
-    {
-        i = obj_config->attrib_count;
-        obj_config->attrib_list[i].type = attrib->type;
-        obj_config->attrib_list[i].value = attrib->value;
-        obj_config->attrib_count++;
-        return VA_STATUS_SUCCESS;
-    }
-    return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
-}
-
-VAStatus dummy_CreateConfig(
-		VADriverContextP ctx,
-		VAProfile profile,
-		VAEntrypoint entrypoint,
-		VAConfigAttrib *attrib_list,
-		int num_attribs,
-		VAConfigID *config_id		/* out */
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus;
-    int configID;
-    object_config_p obj_config;
-    int i;
-
-    /* Validate profile & entrypoint */
-    switch (profile) {
-        case VAProfileMPEG2Simple:
-        case VAProfileMPEG2Main:
-                if ((VAEntrypointVLD == entrypoint) ||
-                    (VAEntrypointMoComp == entrypoint))
-                {
-                    vaStatus = VA_STATUS_SUCCESS;
-                }
-                else
-                {
-                    vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
-                }
-                break;
-
-        case VAProfileMPEG4Simple:
-        case VAProfileMPEG4AdvancedSimple:
-        case VAProfileMPEG4Main:
-                if (VAEntrypointVLD == entrypoint)
-                {
-                    vaStatus = VA_STATUS_SUCCESS;
-                }
-                else
-                {
-                    vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
-                }
-                break;
-
-        case VAProfileH264Baseline:
-        case VAProfileH264Main:
-        case VAProfileH264High:
-                if (VAEntrypointVLD == entrypoint)
-                {
-                    vaStatus = VA_STATUS_SUCCESS;
-                }
-                else
-                {
-                    vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
-                }
-                break;
-
-        case VAProfileVC1Simple:
-        case VAProfileVC1Main:
-        case VAProfileVC1Advanced:
-                if (VAEntrypointVLD == entrypoint)
-                {
-                    vaStatus = VA_STATUS_SUCCESS;
-                }
-                else
-                {
-                    vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
-                }
-                break;
-
-        default:
-                vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
-                break;
-    }
-
-    if (VA_STATUS_SUCCESS != vaStatus)
-    {
-        return vaStatus;
-    }
-
-    configID = object_heap_allocate( &driver_data->config_heap );
-    obj_config = CONFIG(configID);
-    if (NULL == obj_config)
-    {
-        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
-        return vaStatus;
-    }
-
-    obj_config->profile = profile;
-    obj_config->entrypoint = entrypoint;
-    obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
-    obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
-    obj_config->attrib_count = 1;
-
-    for(i = 0; i < num_attribs; i++)
-    {
-        vaStatus = dummy__update_attribute(obj_config, &(attrib_list[i]));
-        if (VA_STATUS_SUCCESS != vaStatus)
-        {
-            break;
-        }
-    }
-
-    /* Error recovery */
-    if (VA_STATUS_SUCCESS != vaStatus)
-    {
-        object_heap_free( &driver_data->config_heap, (object_base_p) obj_config);
-    }
-    else
-    {
-        *config_id = configID;
-    }
-
-    return vaStatus;
-}
-
-VAStatus dummy_DestroyConfig(
-		VADriverContextP ctx,
-		VAConfigID config_id
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus;
-    object_config_p obj_config;
-
-    obj_config = CONFIG(config_id);
-    if (NULL == obj_config)
-    {
-        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
-        return vaStatus;
-    }
-
-    object_heap_free( &driver_data->config_heap, (object_base_p) obj_config);
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_QueryConfigAttributes(
-		VADriverContextP ctx,
-		VAConfigID config_id,
-		VAProfile *profile,		/* out */
-		VAEntrypoint *entrypoint, 	/* out */
-		VAConfigAttrib *attrib_list,	/* out */
-		int *num_attribs		/* out */
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    object_config_p obj_config;
-    int i;
-
-    obj_config = CONFIG(config_id);
-    ASSERT(obj_config);
-
-    *profile = obj_config->profile;
-    *entrypoint = obj_config->entrypoint;
-    *num_attribs =  obj_config->attrib_count;
-    for(i = 0; i < obj_config->attrib_count; i++)
-    {
-        attrib_list[i] = obj_config->attrib_list[i];
-    }
-
-    return vaStatus;
-}
-
-VAStatus dummy_CreateSurfaces(
-		VADriverContextP ctx,
-		int width,
-		int height,
-		int format,
-		int num_surfaces,
-		VASurfaceID *surfaces		/* out */
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    int i;
-
-    /* We only support one format */
-    if (VA_RT_FORMAT_YUV420 != format)
-    {
-        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
-    }
-
-    for (i = 0; i < num_surfaces; i++)
-    {
-        int surfaceID = object_heap_allocate( &driver_data->surface_heap );
-        object_surface_p obj_surface = SURFACE(surfaceID);
-        if (NULL == obj_surface)
-        {
-            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
-            break;
-        }
-        obj_surface->surface_id = surfaceID;
-        surfaces[i] = surfaceID;
-    }
-
-    /* Error recovery */
-    if (VA_STATUS_SUCCESS != vaStatus)
-    {
-        /* surfaces[i-1] was the last successful allocation */
-        for(; i--; )
-        {
-            object_surface_p obj_surface = SURFACE(surfaces[i]);
-            surfaces[i] = VA_INVALID_SURFACE;
-            ASSERT(obj_surface);
-            object_heap_free( &driver_data->surface_heap, (object_base_p) obj_surface);
-        }
-    }
-
-    return vaStatus;
-}
-
-VAStatus dummy_DestroySurfaces(
-		VADriverContextP ctx,
-		VASurfaceID *surface_list,
-		int num_surfaces
-	)
-{
-    INIT_DRIVER_DATA
-    int i;
-    for(i = num_surfaces; i--; )
-    {
-        object_surface_p obj_surface = SURFACE(surface_list[i]);
-        ASSERT(obj_surface);
-        object_heap_free( &driver_data->surface_heap, (object_base_p) obj_surface);
-    }
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_QueryImageFormats(
-	VADriverContextP ctx,
-	VAImageFormat *format_list,        /* out */
-	int *num_formats           /* out */
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_CreateImage(
-	VADriverContextP ctx,
-	VAImageFormat *format,
-	int width,
-	int height,
-	VAImage *image     /* out */
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_DeriveImage(
-	VADriverContextP ctx,
-	VASurfaceID surface,
-	VAImage *image     /* out */
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_DestroyImage(
-	VADriverContextP ctx,
-	VAImageID image
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_SetImagePalette(
-	VADriverContextP ctx,
-	VAImageID image,
-	unsigned char *palette
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_GetImage(
-	VADriverContextP 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
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-
-VAStatus dummy_PutImage(
-	VADriverContextP 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
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_QuerySubpictureFormats(
-	VADriverContextP ctx,
-	VAImageFormat *format_list,        /* out */
-	unsigned int *flags,       /* out */
-	unsigned int *num_formats  /* out */
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_CreateSubpicture(
-	VADriverContextP ctx,
-	VAImageID image,
-	VASubpictureID *subpicture   /* out */
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_DestroySubpicture(
-	VADriverContextP ctx,
-	VASubpictureID subpicture
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_SetSubpictureImage(
-        VADriverContextP ctx,
-        VASubpictureID subpicture,
-        VAImageID image
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_SetSubpicturePalette(
-	VADriverContextP 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
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_SetSubpictureChromakey(
-	VADriverContextP ctx,
-	VASubpictureID subpicture,
-	unsigned int chromakey_min,
-	unsigned int chromakey_max,
-	unsigned int chromakey_mask
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_SetSubpictureGlobalAlpha(
-	VADriverContextP ctx,
-	VASubpictureID subpicture,
-	float global_alpha 
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-
-VAStatus dummy_AssociateSubpicture(
-	VADriverContextP 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
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_DeassociateSubpicture(
-	VADriverContextP ctx,
-	VASubpictureID subpicture,
-	VASurfaceID *target_surfaces,
-	int num_surfaces
-)
-{
-    INIT_DRIVER_DATA
-    
-    /* TODO */
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_CreateContext(
-		VADriverContextP ctx,
-		VAConfigID config_id,
-		int picture_width,
-		int picture_height,
-		int flag,
-		VASurfaceID *render_targets,
-		int num_render_targets,
-		VAContextID *context		/* out */
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    object_config_p obj_config;
-    int i;
-
-    obj_config = CONFIG(config_id);
-    if (NULL == obj_config)
-    {
-        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
-        return vaStatus;
-    }
-
-    /* Validate flag */
-    /* Validate picture dimensions */
-
-    int contextID = object_heap_allocate( &driver_data->context_heap );
-    object_context_p obj_context = CONTEXT(contextID);
-    if (NULL == obj_context)
-    {
-        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
-        return vaStatus;
-    }
-
-    obj_context->context_id  = contextID;
-    *context = contextID;
-    obj_context->current_render_target = -1;
-    obj_context->config_id = config_id;
-    obj_context->picture_width = picture_width;
-    obj_context->picture_height = picture_height;
-    obj_context->num_render_targets = num_render_targets;
-    obj_context->render_targets = (VASurfaceID *) malloc(num_render_targets * sizeof(VASurfaceID));
-    if (obj_context->render_targets == NULL)
-    {
-        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
-        return vaStatus;
-    }
-    
-    for(i = 0; i < num_render_targets; i++)
-    {
-        if (NULL == SURFACE(render_targets[i]))
-        {
-            vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
-            break;
-        }
-        obj_context->render_targets[i] = render_targets[i];
-    }
-    obj_context->flags = flag;
-
-    /* Error recovery */
-    if (VA_STATUS_SUCCESS != vaStatus)
-    {
-        obj_context->context_id = -1;
-        obj_context->config_id = -1;
-        free(obj_context->render_targets);
-        obj_context->render_targets = NULL;
-        obj_context->num_render_targets = 0;
-        obj_context->flags = 0;
-        object_heap_free( &driver_data->context_heap, (object_base_p) obj_context);
-    }
-
-    return vaStatus;
-}
-
-
-VAStatus dummy_DestroyContext(
-		VADriverContextP ctx,
-		VAContextID context
-	)
-{
-    INIT_DRIVER_DATA
-    object_context_p obj_context = CONTEXT(context);
-    ASSERT(obj_context);
-
-    obj_context->context_id = -1;
-    obj_context->config_id = -1;
-    obj_context->picture_width = 0;
-    obj_context->picture_height = 0;
-    if (obj_context->render_targets)
-    {
-        free(obj_context->render_targets);
-    }
-    obj_context->render_targets = NULL;
-    obj_context->num_render_targets = 0;
-    obj_context->flags = 0;
-
-    obj_context->current_render_target = -1;
-
-    object_heap_free( &driver_data->context_heap, (object_base_p) obj_context);
-
-    return VA_STATUS_SUCCESS;
-}
-
-
-
-static VAStatus dummy__allocate_buffer(object_buffer_p obj_buffer, int size)
-{
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-
-    obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size);
-    if (NULL == obj_buffer->buffer_data)
-    {
-        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
-    }
-    return vaStatus;
-}
-
-VAStatus dummy_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 */
-)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    int bufferID;
-    object_buffer_p obj_buffer;
-
-    /* Validate type */
-    switch (type)
-    {
-        case VAPictureParameterBufferType:
-        case VAIQMatrixBufferType:
-        case VABitPlaneBufferType:
-        case VASliceGroupMapBufferType:
-        case VASliceParameterBufferType:
-        case VASliceDataBufferType:
-        case VAMacroblockParameterBufferType:
-        case VAResidualDataBufferType:
-        case VADeblockingParameterBufferType:
-        case VAImageBufferType:
-            /* Ok */
-            break;
-        default:
-            vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
-            return vaStatus;
-    }
-
-    bufferID = object_heap_allocate( &driver_data->buffer_heap );
-    obj_buffer = BUFFER(bufferID);
-    if (NULL == obj_buffer)
-    {
-        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
-        return vaStatus;
-    }
-
-    obj_buffer->buffer_data = NULL;
-
-    vaStatus = dummy__allocate_buffer(obj_buffer, size * num_elements);
-    if (VA_STATUS_SUCCESS == vaStatus)
-    {
-        obj_buffer->max_num_elements = num_elements;
-        obj_buffer->num_elements = num_elements;
-        if (data)
-        {
-            memcpy(obj_buffer->buffer_data, data, size * num_elements);
-        }
-    }
-
-    if (VA_STATUS_SUCCESS == vaStatus)
-    {
-        *buf_id = bufferID;
-    }
-
-    return vaStatus;
-}
-
-
-VAStatus dummy_BufferSetNumElements(
-		VADriverContextP ctx,
-		VABufferID buf_id,	/* in */
-        unsigned int num_elements	/* in */
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    object_buffer_p obj_buffer = BUFFER(buf_id);
-    ASSERT(obj_buffer);
-
-    if ((num_elements < 0) || (num_elements > obj_buffer->max_num_elements))
-    {
-        vaStatus = VA_STATUS_ERROR_UNKNOWN;
-    }
-    if (VA_STATUS_SUCCESS == vaStatus)
-    {
-        obj_buffer->num_elements = num_elements;
-    }
-
-    return vaStatus;
-}
-
-VAStatus dummy_MapBuffer(
-		VADriverContextP ctx,
-		VABufferID buf_id,	/* in */
-		void **pbuf         /* out */
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
-    object_buffer_p obj_buffer = BUFFER(buf_id);
-    ASSERT(obj_buffer);
-    if (NULL == obj_buffer)
-    {
-        vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
-        return vaStatus;
-    }
-
-    if (NULL != obj_buffer->buffer_data)
-    {
-        *pbuf = obj_buffer->buffer_data;
-        vaStatus = VA_STATUS_SUCCESS;
-    }
-    return vaStatus;
-}
-
-VAStatus dummy_UnmapBuffer(
-		VADriverContextP ctx,
-		VABufferID buf_id	/* in */
-	)
-{
-    /* Do nothing */
-    return VA_STATUS_SUCCESS;
-}
-
-static void dummy__destroy_buffer(struct dummy_driver_data *driver_data, object_buffer_p obj_buffer)
-{
-    if (NULL != obj_buffer->buffer_data)
-    {
-        free(obj_buffer->buffer_data);
-        obj_buffer->buffer_data = NULL;
-    }
-
-    object_heap_free( &driver_data->buffer_heap, (object_base_p) obj_buffer);
-}
-
-VAStatus dummy_DestroyBuffer(
-		VADriverContextP ctx,
-		VABufferID buffer_id
-	)
-{
-    INIT_DRIVER_DATA
-    object_buffer_p obj_buffer = BUFFER(buffer_id);
-    ASSERT(obj_buffer);
-
-    dummy__destroy_buffer(driver_data, obj_buffer);
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus dummy_BeginPicture(
-		VADriverContextP ctx,
-		VAContextID context,
-		VASurfaceID render_target
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    object_context_p obj_context;
-    object_surface_p obj_surface;
-
-    obj_context = CONTEXT(context);
-    ASSERT(obj_context);
-
-    obj_surface = SURFACE(render_target);
-    ASSERT(obj_surface);
-
-    obj_context->current_render_target = obj_surface->base.id;
-
-    return vaStatus;
-}
-
-VAStatus dummy_RenderPicture(
-		VADriverContextP ctx,
-		VAContextID context,
-		VABufferID *buffers,
-		int num_buffers
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    object_context_p obj_context;
-    object_surface_p obj_surface;
-    int i;
-
-    obj_context = CONTEXT(context);
-    ASSERT(obj_context);
-
-    obj_surface = SURFACE(obj_context->current_render_target);
-    ASSERT(obj_surface);
-
-    /* verify that we got valid buffer references */
-    for(i = 0; i < num_buffers; i++)
-    {
-        object_buffer_p obj_buffer = BUFFER(buffers[i]);
-        ASSERT(obj_buffer);
-        if (NULL == obj_buffer)
-        {
-            vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
-            break;
-        }
-    }
-    
-    /* Release buffers */
-    for(i = 0; i < num_buffers; i++)
-    {
-        object_buffer_p obj_buffer = BUFFER(buffers[i]);
-        ASSERT(obj_buffer);
-        dummy__destroy_buffer(driver_data, obj_buffer);
-    }
-
-    return vaStatus;
-}
-
-VAStatus dummy_EndPicture(
-		VADriverContextP ctx,
-		VAContextID context
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    object_context_p obj_context;
-    object_surface_p obj_surface;
-
-    obj_context = CONTEXT(context);
-    ASSERT(obj_context);
-
-    obj_surface = SURFACE(obj_context->current_render_target);
-    ASSERT(obj_surface);
-
-    // For now, assume that we are done with rendering right away
-    obj_context->current_render_target = -1;
-
-    return vaStatus;
-}
-
-
-VAStatus dummy_SyncSurface(
-		VADriverContextP ctx,
-		VASurfaceID render_target
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    object_surface_p obj_surface;
-
-    obj_surface = SURFACE(render_target);
-    ASSERT(obj_surface);
-
-    return vaStatus;
-}
-
-VAStatus dummy_QuerySurfaceStatus(
-		VADriverContextP ctx,
-		VASurfaceID render_target,
-		VASurfaceStatus *status	/* out */
-	)
-{
-    INIT_DRIVER_DATA
-    VAStatus vaStatus = VA_STATUS_SUCCESS;
-    object_surface_p obj_surface;
-
-    obj_surface = SURFACE(render_target);
-    ASSERT(obj_surface);
-
-    *status = VASurfaceReady;
-
-    return vaStatus;
-}
-
-VAStatus dummy_PutSurface(
-   		VADriverContextP ctx,
-		VASurfaceID surface,
-		void *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 */
-	)
-{
-    /* TODO */
-    Drawable drawable = (Drawable)draw;
-
-    (void)drawable;
-
-    return VA_STATUS_ERROR_UNKNOWN;
-}
-
-/* 
- * Query display attributes 
- * The caller must provide a "attr_list" array that can hold at
- * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
- * returned in "attr_list" is returned in "num_attributes".
- */
-VAStatus dummy_QueryDisplayAttributes (
-		VADriverContextP ctx,
-		VADisplayAttribute *attr_list,	/* out */
-		int *num_attributes		/* out */
-	)
-{
-    /* TODO */
-    return VA_STATUS_ERROR_UNKNOWN;
-}
-
-/* 
- * Get display attributes 
- * This function returns the current attribute values in "attr_list".
- * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
- * from vaQueryDisplayAttributes() can have their values retrieved.  
- */
-VAStatus dummy_GetDisplayAttributes (
-		VADriverContextP ctx,
-		VADisplayAttribute *attr_list,	/* in/out */
-		int num_attributes
-	)
-{
-    /* TODO */
-    return VA_STATUS_ERROR_UNKNOWN;
-}
-
-/* 
- * Set display attributes 
- * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
- * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
- * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
- */
-VAStatus dummy_SetDisplayAttributes (
-		VADriverContextP ctx,
-		VADisplayAttribute *attr_list,
-		int num_attributes
-	)
-{
-    /* TODO */
-    return VA_STATUS_ERROR_UNKNOWN;
-}
-
-
-VAStatus dummy_BufferInfo(
-        VADriverContextP ctx,
-        VABufferID buf_id,	/* in */
-        VABufferType *type,	/* out */
-        unsigned int *size,    	/* out */
-        unsigned int *num_elements /* out */
-    )
-{
-    /* TODO */
-    return VA_STATUS_ERROR_UNIMPLEMENTED;
-}
-
-    
-
-VAStatus dummy_LockSurface(
-		VADriverContextP ctx,
-		VASurfaceID surface,
-                unsigned int *fourcc, /* following are output argument */
-                unsigned int *luma_stride,
-                unsigned int *chroma_u_stride,
-                unsigned int *chroma_v_stride,
-                unsigned int *luma_offset,
-                unsigned int *chroma_u_offset,
-                unsigned int *chroma_v_offset,
-                unsigned int *buffer_name,
-		void **buffer
-	)
-{
-    /* TODO */
-    return VA_STATUS_ERROR_UNIMPLEMENTED;
-}
-
-VAStatus dummy_UnlockSurface(
-		VADriverContextP ctx,
-		VASurfaceID surface
-	)
-{
-    /* TODO */
-    return VA_STATUS_ERROR_UNIMPLEMENTED;
-}
-
-VAStatus dummy_Terminate( VADriverContextP ctx )
-{
-    INIT_DRIVER_DATA
-    object_buffer_p obj_buffer;
-    object_surface_p obj_surface;
-    object_context_p obj_context;
-    object_config_p obj_config;
-    object_heap_iterator iter;
-
-    /* Clean up left over buffers */
-    obj_buffer = (object_buffer_p) object_heap_first( &driver_data->buffer_heap, &iter);
-    while (obj_buffer)
-    {
-        dummy__information_message("vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id);
-        dummy__destroy_buffer(driver_data, obj_buffer);
-        obj_buffer = (object_buffer_p) object_heap_next( &driver_data->buffer_heap, &iter);
-    }
-    object_heap_destroy( &driver_data->buffer_heap );
-
-    /* TODO cleanup */
-    object_heap_destroy( &driver_data->surface_heap );
-
-    /* TODO cleanup */
-    object_heap_destroy( &driver_data->context_heap );
-
-    /* Clean up configIDs */
-    obj_config = (object_config_p) object_heap_first( &driver_data->config_heap, &iter);
-    while (obj_config)
-    {
-        object_heap_free( &driver_data->config_heap, (object_base_p) obj_config);
-        obj_config = (object_config_p) object_heap_next( &driver_data->config_heap, &iter);
-    }
-    object_heap_destroy( &driver_data->config_heap );
-
-    free(ctx->pDriverData);
-    ctx->pDriverData = NULL;
-
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus VA_DRIVER_INIT_FUNC(  VADriverContextP ctx )
-{
-    struct VADriverVTable * const vtable = ctx->vtable;
-    object_base_p obj;
-    int result;
-    struct dummy_driver_data *driver_data;
-    int i;
-
-    ctx->version_major = VA_MAJOR_VERSION;
-    ctx->version_minor = VA_MINOR_VERSION;
-    ctx->max_profiles = DUMMY_MAX_PROFILES;
-    ctx->max_entrypoints = DUMMY_MAX_ENTRYPOINTS;
-    ctx->max_attributes = DUMMY_MAX_CONFIG_ATTRIBUTES;
-    ctx->max_image_formats = DUMMY_MAX_IMAGE_FORMATS;
-    ctx->max_subpic_formats = DUMMY_MAX_SUBPIC_FORMATS;
-    ctx->max_display_attributes = DUMMY_MAX_DISPLAY_ATTRIBUTES;
-    ctx->str_vendor = DUMMY_STR_VENDOR;
-
-    vtable->vaTerminate = dummy_Terminate;
-    vtable->vaQueryConfigEntrypoints = dummy_QueryConfigEntrypoints;
-    vtable->vaQueryConfigProfiles = dummy_QueryConfigProfiles;
-    vtable->vaQueryConfigEntrypoints = dummy_QueryConfigEntrypoints;
-    vtable->vaQueryConfigAttributes = dummy_QueryConfigAttributes;
-    vtable->vaCreateConfig = dummy_CreateConfig;
-    vtable->vaDestroyConfig = dummy_DestroyConfig;
-    vtable->vaGetConfigAttributes = dummy_GetConfigAttributes;
-    vtable->vaCreateSurfaces = dummy_CreateSurfaces;
-    vtable->vaDestroySurfaces = dummy_DestroySurfaces;
-    vtable->vaCreateContext = dummy_CreateContext;
-    vtable->vaDestroyContext = dummy_DestroyContext;
-    vtable->vaCreateBuffer = dummy_CreateBuffer;
-    vtable->vaBufferSetNumElements = dummy_BufferSetNumElements;
-    vtable->vaMapBuffer = dummy_MapBuffer;
-    vtable->vaUnmapBuffer = dummy_UnmapBuffer;
-    vtable->vaDestroyBuffer = dummy_DestroyBuffer;
-    vtable->vaBeginPicture = dummy_BeginPicture;
-    vtable->vaRenderPicture = dummy_RenderPicture;
-    vtable->vaEndPicture = dummy_EndPicture;
-    vtable->vaSyncSurface = dummy_SyncSurface;
-    vtable->vaQuerySurfaceStatus = dummy_QuerySurfaceStatus;
-    vtable->vaPutSurface = dummy_PutSurface;
-    vtable->vaQueryImageFormats = dummy_QueryImageFormats;
-    vtable->vaCreateImage = dummy_CreateImage;
-    vtable->vaDeriveImage = dummy_DeriveImage;
-    vtable->vaDestroyImage = dummy_DestroyImage;
-    vtable->vaSetImagePalette = dummy_SetImagePalette;
-    vtable->vaGetImage = dummy_GetImage;
-    vtable->vaPutImage = dummy_PutImage;
-    vtable->vaQuerySubpictureFormats = dummy_QuerySubpictureFormats;
-    vtable->vaCreateSubpicture = dummy_CreateSubpicture;
-    vtable->vaDestroySubpicture = dummy_DestroySubpicture;
-    vtable->vaSetSubpictureImage = dummy_SetSubpictureImage;
-    vtable->vaSetSubpictureChromakey = dummy_SetSubpictureChromakey;
-    vtable->vaSetSubpictureGlobalAlpha = dummy_SetSubpictureGlobalAlpha;
-    vtable->vaAssociateSubpicture = dummy_AssociateSubpicture;
-    vtable->vaDeassociateSubpicture = dummy_DeassociateSubpicture;
-    vtable->vaQueryDisplayAttributes = dummy_QueryDisplayAttributes;
-    vtable->vaGetDisplayAttributes = dummy_GetDisplayAttributes;
-    vtable->vaSetDisplayAttributes = dummy_SetDisplayAttributes;
-    vtable->vaLockSurface = dummy_LockSurface;
-    vtable->vaUnlockSurface = dummy_UnlockSurface;
-    vtable->vaBufferInfo = dummy_BufferInfo;
-
-    driver_data = (struct dummy_driver_data *) malloc( sizeof(*driver_data) );
-    ctx->pDriverData = (void *) driver_data;
-
-    result = object_heap_init( &driver_data->config_heap, sizeof(struct object_config), CONFIG_ID_OFFSET );
-    ASSERT( result == 0 );
-
-    result = object_heap_init( &driver_data->context_heap, sizeof(struct object_context), CONTEXT_ID_OFFSET );
-    ASSERT( result == 0 );
-
-    result = object_heap_init( &driver_data->surface_heap, sizeof(struct object_surface), SURFACE_ID_OFFSET );
-    ASSERT( result == 0 );
-
-    result = object_heap_init( &driver_data->buffer_heap, sizeof(struct object_buffer), BUFFER_ID_OFFSET );
-    ASSERT( result == 0 );
-
-
-    return VA_STATUS_SUCCESS;
-}
-
diff --git a/dummy_drv_video/dummy_drv_video.h b/dummy_drv_video/dummy_drv_video.h
deleted file mode 100644
index cd849c5..0000000
--- a/dummy_drv_video/dummy_drv_video.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _DUMMY_DRV_VIDEO_H_
-#define _DUMMY_DRV_VIDEO_H_
-
-#include <va/va.h>
-#include "object_heap.h"
-
-#define DUMMY_MAX_PROFILES			11
-#define DUMMY_MAX_ENTRYPOINTS			5
-#define DUMMY_MAX_CONFIG_ATTRIBUTES		10
-#define DUMMY_MAX_IMAGE_FORMATS			10
-#define DUMMY_MAX_SUBPIC_FORMATS		4
-#define DUMMY_MAX_DISPLAY_ATTRIBUTES		4
-#define DUMMY_STR_VENDOR			"Dummy Driver 1.0"
-
-struct dummy_driver_data {
-    struct object_heap	config_heap;
-    struct object_heap	context_heap;
-    struct object_heap	surface_heap;
-    struct object_heap	buffer_heap;
-};
-
-struct object_config {
-    struct object_base base;
-    VAProfile profile;
-    VAEntrypoint entrypoint;
-    VAConfigAttrib attrib_list[DUMMY_MAX_CONFIG_ATTRIBUTES];
-    int attrib_count;
-};
-
-struct object_context {
-    struct object_base base;
-    VAContextID context_id;
-    VAConfigID config_id;
-    VASurfaceID current_render_target;
-    int picture_width;
-    int picture_height;
-    int num_render_targets;
-    int flags;
-    VASurfaceID *render_targets;
-};
-
-struct object_surface {
-    struct object_base base;
-    VASurfaceID surface_id;
-};
-
-struct object_buffer {
-    struct object_base base;
-    void *buffer_data;
-    int max_num_elements;
-    int num_elements;
-};
-
-typedef struct object_config *object_config_p;
-typedef struct object_context *object_context_p;
-typedef struct object_surface *object_surface_p;
-typedef struct object_buffer *object_buffer_p;
-
-#endif /* _DUMMY_DRV_VIDEO_H_ */
diff --git a/dummy_drv_video/object_heap.c b/dummy_drv_video/object_heap.c
deleted file mode 100644
index e867139..0000000
--- a/dummy_drv_video/object_heap.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "object_heap.h"
-
-#include "assert.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define ASSERT	assert
-
-#define LAST_FREE	-1
-#define ALLOCATED	-2
-
-/*
- * Expands the heap
- * Return 0 on success, -1 on error
- */
-static int object_heap_expand( object_heap_p heap )
-{
-    int i;
-    void *new_heap_index;
-    int next_free;
-    int new_heap_size = heap->heap_size + heap->heap_increment;
-    
-    new_heap_index = (void *) realloc( heap->heap_index, new_heap_size * heap->object_size );
-    if ( NULL == new_heap_index )
-    {
-        return -1; /* Out of memory */
-    }
-    heap->heap_index = new_heap_index;
-    next_free = heap->next_free;
-    for(i = new_heap_size; i-- > heap->heap_size; )
-    {
-        object_base_p obj = (object_base_p) (heap->heap_index + i * heap->object_size);
-        obj->id = i + heap->id_offset;
-        obj->next_free = next_free;
-        next_free = i;
-    }
-    heap->next_free = next_free;
-    heap->heap_size = new_heap_size;
-    return 0; /* Success */
-}
-
-/*
- * Return 0 on success, -1 on error
- */
-int object_heap_init( object_heap_p heap, int object_size, int id_offset)
-{
-    heap->object_size = object_size;
-    heap->id_offset = id_offset & OBJECT_HEAP_OFFSET_MASK;
-    heap->heap_size = 0;
-    heap->heap_increment = 16;
-    heap->heap_index = NULL;
-    heap->next_free = LAST_FREE;
-    return object_heap_expand(heap);
-}
-
-/*
- * Allocates an object
- * Returns the object ID on success, returns -1 on error
- */
-int object_heap_allocate( object_heap_p heap )
-{
-    object_base_p obj;
-    if ( LAST_FREE == heap->next_free )
-    {
-        if( -1 == object_heap_expand( heap ) )
-        {
-            return -1; /* Out of memory */
-        }
-    }
-    ASSERT( heap->next_free >= 0 );
-    
-    obj = (object_base_p) (heap->heap_index + heap->next_free * heap->object_size);
-    heap->next_free = obj->next_free;
-    obj->next_free = ALLOCATED;
-    return obj->id;
-}
-
-/*
- * Lookup an object by object ID
- * Returns a pointer to the object on success, returns NULL on error
- */
-object_base_p object_heap_lookup( object_heap_p heap, int id )
-{
-    object_base_p obj;
-    if ( (id < heap->id_offset) || (id > (heap->heap_size+heap->id_offset)) )
-    {
-        return NULL;
-    }
-    id &= OBJECT_HEAP_ID_MASK;
-    obj = (object_base_p) (heap->heap_index + id * heap->object_size);
-
-	/* Check if the object has in fact been allocated */
-	if ( obj->next_free != ALLOCATED )
-    {
-        return NULL;
-    }
-    return obj;
-}
-
-/*
- * Iterate over all objects in the heap.
- * Returns a pointer to the first object on the heap, returns NULL if heap is empty.
- */
-object_base_p object_heap_first( object_heap_p heap, object_heap_iterator *iter )
-{
-    *iter = -1;
-    return object_heap_next( heap, iter );
-}
-
-/*
- * Iterate over all objects in the heap.
- * Returns a pointer to the next object on the heap, returns NULL if heap is empty.
- */
-object_base_p object_heap_next( object_heap_p heap, object_heap_iterator *iter )
-{
-    object_base_p obj;
-    int i = *iter + 1;
-    while ( i < heap->heap_size)
-    {
-        obj = (object_base_p) (heap->heap_index + i * heap->object_size);
-        if (obj->next_free == ALLOCATED)
-        {
-            *iter = i;
-            return obj;
-        }
-        i++;
-    }
-    *iter = i;
-    return NULL;
-}
-
-
-
-/*
- * Frees an object
- */
-void object_heap_free( object_heap_p heap, object_base_p obj )
-{
-    /* Don't complain about NULL pointers */
-    if (NULL != obj)
-    {
-        /* Check if the object has in fact been allocated */
-        ASSERT( obj->next_free == ALLOCATED );
-    
-        obj->next_free = heap->next_free;
-        heap->next_free = obj->id & OBJECT_HEAP_ID_MASK;
-    }
-}
-
-/*
- * Destroys a heap, the heap must be empty.
- */
-void object_heap_destroy( object_heap_p heap )
-{
-    object_base_p obj;
-    int i;
-    /* Check if heap is empty */
-    for (i = 0; i < heap->heap_size; i++)
-    {
-        /* Check if object is not still allocated */
-        obj = (object_base_p) (heap->heap_index + i * heap->object_size);
-        ASSERT( obj->next_free != ALLOCATED );
-    }
-    free(heap->heap_index);
-    heap->heap_size = 0;
-    heap->heap_index = NULL;
-    heap->next_free = LAST_FREE;
-}
diff --git a/dummy_drv_video/object_heap.h b/dummy_drv_video/object_heap.h
deleted file mode 100644
index 154fddb..0000000
--- a/dummy_drv_video/object_heap.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _OBJECT_HEAP_H_
-#define _OBJECT_HEAP_H_
-
-#define OBJECT_HEAP_OFFSET_MASK		0x7F000000
-#define OBJECT_HEAP_ID_MASK			0x00FFFFFF
-
-typedef struct object_base *object_base_p;
-typedef struct object_heap *object_heap_p;
-
-struct object_base {
-    int id;
-    int next_free;
-};
-
-struct object_heap {
-    int	object_size;
-    int id_offset;
-    void *heap_index;
-    int next_free;
-    int heap_size;
-    int heap_increment;
-};
-
-typedef int object_heap_iterator;
-
-/*
- * Return 0 on success, -1 on error
- */
-int object_heap_init( object_heap_p heap, int object_size, int id_offset);
-
-/*
- * Allocates an object
- * Returns the object ID on success, returns -1 on error
- */
-int object_heap_allocate( object_heap_p heap );
-
-/*
- * Lookup an allocated object by object ID
- * Returns a pointer to the object on success, returns NULL on error
- */
-object_base_p object_heap_lookup( object_heap_p heap, int id );
-
-/*
- * Iterate over all objects in the heap.
- * Returns a pointer to the first object on the heap, returns NULL if heap is empty.
- */
-object_base_p object_heap_first( object_heap_p heap, object_heap_iterator *iter );
-
-/*
- * Iterate over all objects in the heap.
- * Returns a pointer to the next object on the heap, returns NULL if heap is empty.
- */
-object_base_p object_heap_next( object_heap_p heap, object_heap_iterator *iter );
-
-/*
- * Frees an object
- */
-void object_heap_free( object_heap_p heap, object_base_p obj );
-
-/*
- * Destroys a heap, the heap must be empty.
- */
-void object_heap_destroy( object_heap_p heap );
-
-#endif /* _OBJECT_HEAP_H_ */
diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am
index f595413..a3435a4 100644
--- a/pkgconfig/Makefile.am
+++ b/pkgconfig/Makefile.am
@@ -22,19 +22,29 @@
 
 pcfiles		 = libva.pc
 pcfiles		+= libva-tpi.pc
+if USE_DRM
+pcfiles		+= libva-drm.pc
+endif
+if USE_X11
 pcfiles		+= libva-x11.pc
+endif
 if USE_GLX
 pcfiles		+= libva-glx.pc
 endif
 if USE_EGL
 pcfiles		+= libva-egl.pc
 endif
+if USE_WAYLAND
+pcfiles		+= libva-wayland.pc
+endif
 
 all_pcfiles_in	 = libva.pc.in
 all_pcfiles_in	+= libva-tpi.pc.in
+all_pcfiles_in	+= libva-drm.pc.in
 all_pcfiles_in	+= libva-x11.pc.in
 all_pcfiles_in	+= libva-glx.pc.in
 all_pcfiles_in	+= libva-egl.pc.in
+all_pcfiles_in	+= libva-wayland.pc.in
 
 pkgconfigdir = @pkgconfigdir@
 pkgconfig_DATA = $(pcfiles)
diff --git a/pkgconfig/libva-drm.pc.in b/pkgconfig/libva-drm.pc.in
new file mode 100644
index 0000000..b3fb471
--- /dev/null
+++ b/pkgconfig/libva-drm.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+display=drm
+
+Name: libva-${display}
+Description: Userspace Video Acceleration (VA) ${display} interface
+Requires: libva
+Version: @VA_API_VERSION@
+Libs: -L${libdir} -lva-${display}
+Cflags: -I${includedir}
diff --git a/pkgconfig/libva-wayland.pc.in b/pkgconfig/libva-wayland.pc.in
new file mode 100644
index 0000000..ee92ac2
--- /dev/null
+++ b/pkgconfig/libva-wayland.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+display=wayland
+
+Name: libva-${display}
+Description: Userspace Video Acceleration (VA) ${display} interface
+Requires: libva wayland-client
+Version: @VA_API_VERSION@
+Libs: -L${libdir} -lva-${display}
+Cflags: -I${includedir}
diff --git a/test/Makefile.am b/test/Makefile.am
index ad95136..df215b6 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -20,9 +20,9 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-
-AM_CFLAGS = -I$(top_srcdir)/va -I$(top_srcdir)/test/basic -I$(top_srcdir)/src/x11
-
-SUBDIRS = basic decode encode putsurface vainfo transcode
+SUBDIRS = common decode encode vainfo videoprocess
+if USE_X11
+SUBDIRS += basic putsurface transcode
+endif
 
 EXTRA_DIST = loadsurface.h loadsurface_yuv.h
diff --git a/test/android_winsys.cpp b/test/android_winsys.cpp
deleted file mode 100644
index 897d936..0000000
--- a/test/android_winsys.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <ui/DisplayInfo.h>
-
-
-#define min(a,b) (a<b?a:b)
-#define SURFACE_CREATE(client,surface_ctrl,android_surface, android_isurface, x, y, win_width, win_height) \
-do {                                                                    \
-    client = new SurfaceComposerClient();                               \
-    android::DisplayInfo info;                                          \
-    int w, h;                                                           \
-                                                                        \
-    client->getDisplayInfo(android::DisplayID(0), &info);               \
-    /*w = min(win_width, info.w);*/                                     \
-    /*h = min(win_height, info.h);*/                                    \
-    w = win_width, h = win_height;                                      \
-                                                                        \
-    surface_ctrl = client->createSurface(getpid(), 0, w, h, PIXEL_FORMAT_RGB_565, ISurfaceComposer::ePushBuffers); \
-    android_surface = surface_ctrl->getSurface();                       \
-    android_isurface = Test::getISurface(android_surface);              \
-                                                                        \
-    client->openTransaction();                                          \
-    surface_ctrl->setPosition(x, y);                                    \
-    client->closeTransaction();                                         \
-                                                                        \
-    client->openTransaction();                                          \
-    surface_ctrl->setSize(w, h);                                        \
-    client->closeTransaction();                                         \
-                                                                        \
-    client->openTransaction();                                          \
-    surface_ctrl->setLayer(0x100000);                                   \
-    client->closeTransaction();                                         \
-} while (0)
-
-
diff --git a/test/basic/Android.mk b/test/basic/Android.mk
index a4b136c..e5b3a59 100755
--- a/test/basic/Android.mk
+++ b/test/basic/Android.mk
@@ -1,3 +1,7 @@
+LIBVA_TESTS_SHARED_LIBS := libva-android libva libdl libdrm libcutils libutils
+LIBVA_TESTS_CFLAGS := -DANDROID -Wno-unused-parameter
+LIBVA_TESTS_C_INCLUDES := $(TARGET_OUT_HEADERS)/libva
+
 # For test_01
 # =====================================================
 
@@ -8,17 +12,12 @@
 LOCAL_SRC_FILES := \
   test_01.c	\
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS := $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_001 
+LOCAL_MODULE :=	test_001
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -29,17 +28,12 @@
 LOCAL_SRC_FILES := \
   test_02.c	\
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_02_android 
+LOCAL_MODULE :=	test_02_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -50,17 +44,12 @@
 LOCAL_SRC_FILES := \
   test_03.c	\
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_03_android 
+LOCAL_MODULE :=	test_03_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -71,17 +60,12 @@
 LOCAL_SRC_FILES := \
   test_04.c	\
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_04_android 
+LOCAL_MODULE :=	test_04_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -92,17 +76,12 @@
 LOCAL_SRC_FILES := \
   test_05.c	\
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_05_android 
+LOCAL_MODULE :=	test_05_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -113,17 +92,12 @@
 LOCAL_SRC_FILES := \
   test_06.c	\
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_06_android 
+LOCAL_MODULE :=	test_06_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -134,17 +108,12 @@
 LOCAL_SRC_FILES := \
   test_07.c	\
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_07_android 
+LOCAL_MODULE :=	test_07_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -155,17 +124,12 @@
 LOCAL_SRC_FILES := \
   test_08.c	\
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_08_android 
+LOCAL_MODULE :=	test_08_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -176,17 +140,12 @@
 LOCAL_SRC_FILES := \
   test_09.c	\
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_09_android 
+LOCAL_MODULE :=	test_09_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -197,17 +156,12 @@
 LOCAL_SRC_FILES := \
   test_10.c	
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_10_android 
+LOCAL_MODULE :=	test_10_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
@@ -218,17 +172,12 @@
 LOCAL_SRC_FILES := \
   test_11.c	
 
-LOCAL_CFLAGS += \
-    -DANDROID  
-
-LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/
-
+LOCAL_CFLAGS += $(LIBVA_TESTS_CFLAGS)
+LOCAL_C_INCLUDES := $(LIBVA_TESTS_C_INCLUDES)
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE :=	test_11_android 
+LOCAL_MODULE :=	test_11_android
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := $(LIBVA_TESTS_SHARED_LIBS)
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/test/basic/Makefile.am b/test/basic/Makefile.am
index c84c264..21f48dd 100644
--- a/test/basic/Makefile.am
+++ b/test/basic/Makefile.am
@@ -20,12 +20,31 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-check_PROGRAMS = test_01 test_02 test_03 test_04 test_05 test_06 \
-		test_07 test_08 test_09 test_10 test_11
+noinst_PROGRAMS = \
+	test_01			\
+	test_02			\
+	test_03			\
+	test_04			\
+	test_05			\
+	test_06			\
+	test_07			\
+	test_08			\
+	test_09			\
+	test_10			\
+	test_11			\
+	$(NULL)
 
-AM_CFLAGS = -I$(top_srcdir)/va -I$(top_srcdir)/src/x11
+AM_CFLAGS = \
+	-DIN_LIBVA		\
+	-I$(top_srcdir)		\
+	$(X11_CFLAGS)		\
+	$(NULL)
 
-TEST_LIBS = $(top_builddir)/va/$(libvabackendlib)
+TEST_LIBS = \
+	$(top_builddir)/va/libva.la	\
+	$(top_builddir)/va/libva-x11.la	\
+	$(X11_LIBS)			\
+	$(NULL)
 
 test_01_LDADD = $(TEST_LIBS)
 test_01_SOURCES = test_01.c
@@ -60,9 +79,9 @@
 test_11_LDADD = $(TEST_LIBS)
 test_11_SOURCES = test_11.c
 
-EXTRA_DIST = test_common.c
+EXTRA_DIST = test_common.c test_x11.c
 
-valgrind:	$(check_PROGRAMS)
-	for a in $(check_PROGRAMS); do \
+valgrind:	$(noinst_PROGRAMS)
+	for a in $(noinst_PROGRAMS); do \
 		valgrind --leak-check=full --show-reachable=yes .libs/$$a; \
 	done
diff --git a/test/basic/test_07.c b/test/basic/test_07.c
index afdd950..2e01533 100644
--- a/test/basic/test_07.c
+++ b/test/basic/test_07.c
@@ -64,19 +64,19 @@
 
     status("vaCreateSurfaces 1 surface\n");
     surfaces_1[1] = DEAD_SURFACE_ID;
-    va_status = vaCreateSurfaces(va_dpy, 352, 288, VA_RT_FORMAT_YUV420, 1, surfaces_1, NULL, 0);
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, 352, 288, surfaces_1, 1, NULL, 0);
     ASSERT( VA_STATUS_SUCCESS == va_status );
     ASSERT( DEAD_SURFACE_ID == surfaces_1[1] ); /* bounds check */
 
     status("vaCreateSurfaces 4 surfaces\n");
     surfaces_4[4] = DEAD_SURFACE_ID;
-    va_status = vaCreateSurfaces(va_dpy, 352, 288, VA_RT_FORMAT_YUV420, 4, surfaces_4, NULL, 0);
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, 352, 288, surfaces_4, 4, NULL, 0);
     ASSERT( VA_STATUS_SUCCESS == va_status );
     ASSERT( DEAD_SURFACE_ID == surfaces_4[4] ); /* bounds check */
 
     status("vaCreateSurfaces 16 surfaces\n");
     surfaces_16[16] = DEAD_SURFACE_ID;
-    va_status = vaCreateSurfaces(va_dpy, 352, 288, VA_RT_FORMAT_YUV420, 16, surfaces_16, NULL, 0);
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, 352, 288, surfaces_16, 16, NULL, 0);
     ASSERT( VA_STATUS_SUCCESS == va_status );
     ASSERT( DEAD_SURFACE_ID == surfaces_16[16] ); /* bounds check */
     
@@ -92,7 +92,7 @@
     
     status("vaCreateSurfaces 6 surfaces\n");
     surfaces_6[6] = DEAD_SURFACE_ID;
-    va_status = vaCreateSurfaces(va_dpy, 352, 288, VA_RT_FORMAT_YUV420, 6, surfaces_6, NULL, 0);
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, 352, 288, surfaces_6, 6, NULL, 0);
     ASSERT( VA_STATUS_SUCCESS == va_status );
     ASSERT( DEAD_SURFACE_ID == surfaces_6[6] ); /* bounds check */
 
diff --git a/test/basic/test_08.c b/test/basic/test_08.c
index a5b3ecf..299882f 100644
--- a/test/basic/test_08.c
+++ b/test/basic/test_08.c
@@ -74,7 +74,7 @@
     {
         status("vaCreateSurfaces create %dx%d surface\n", test_sizes[i].w, test_sizes[i].h);
         surfaces[i+1] = DEAD_SURFACE_ID;
-        va_status = vaCreateSurfaces(va_dpy,  test_sizes[i].w, test_sizes[i].h, VA_RT_FORMAT_YUV420, 1, &surfaces[i], NULL, 0);
+        va_status = vaCreateSurfaces(va_dpy,  VA_RT_FORMAT_YUV420, test_sizes[i].w, test_sizes[i].h, &surfaces[i], 1, NULL, 0);
         ASSERT( VA_STATUS_SUCCESS == va_status );
         ASSERT( DEAD_SURFACE_ID == surfaces[i+1] );
     }
diff --git a/test/basic/test_09.c b/test/basic/test_09.c
index 0cea466..b8a8f1c 100644
--- a/test/basic/test_09.c
+++ b/test/basic/test_09.c
@@ -69,7 +69,7 @@
     VASurfaceID *surfaces = malloc(total_surfaces * sizeof(VASurfaceID));
 
     // TODO: Don't assume VA_RT_FORMAT_YUV420 is supported / needed for each config
-    va_status = vaCreateSurfaces(va_dpy, width, height, VA_RT_FORMAT_YUV420, total_surfaces, surfaces, NULL, 0);
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, width, height, surfaces, total_surfaces, NULL, 0);
     ASSERT( VA_STATUS_SUCCESS == va_status );
     
     for(i = 0; i < config_count; i++)
diff --git a/test/basic/test_10.c b/test/basic/test_10.c
index cc7bd8d..9c7c566 100644
--- a/test/basic/test_10.c
+++ b/test/basic/test_10.c
@@ -47,7 +47,7 @@
     surfaces = malloc(total_surfaces * sizeof(VASurfaceID));
 
     // TODO: Don't assume VA_RT_FORMAT_YUV420 is supported / needed for each config
-    va_status = vaCreateSurfaces(va_dpy, width, height, VA_RT_FORMAT_YUV420, total_surfaces, surfaces, NULL, 0);
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, width, height, surfaces, total_surfaces, NULL, 0);
     ASSERT( VA_STATUS_SUCCESS == va_status );
     
     status("vaCreateContext with config %08x\n", config);
diff --git a/test/basic/test_11.c b/test/basic/test_11.c
index c9da4f8..99c8785 100644
--- a/test/basic/test_11.c
+++ b/test/basic/test_11.c
@@ -47,7 +47,7 @@
     surfaces = malloc(total_surfaces * sizeof(VASurfaceID));
 
     // TODO: Don't assume VA_RT_FORMAT_YUV420 is supported / needed for each config
-    va_status = vaCreateSurfaces(va_dpy, width, height, VA_RT_FORMAT_YUV420, total_surfaces, surfaces, NULL, 0);
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, width, height, surfaces, total_surfaces, NULL, 0);
     ASSERT( VA_STATUS_SUCCESS == va_status );
     
     status("vaCreateContext with config %08x\n", config);
diff --git a/test/basic/test_common.c b/test/basic/test_common.c
index 5f93c25..f49d02a 100644
--- a/test/basic/test_common.c
+++ b/test/basic/test_common.c
@@ -91,6 +91,7 @@
 {
     switch(profile)
     {
+        PROFILE(None)
         PROFILE(MPEG2Simple)
         PROFILE(MPEG2Main)
         PROFILE(MPEG4Simple)
@@ -101,10 +102,14 @@
         PROFILE(H264Main)
         PROFILE(H264High)
         PROFILE(H264ConstrainedBaseline)
+        PROFILE(H264MultiviewHigh)
+        PROFILE(H264StereoHigh)
         PROFILE(VC1Simple)
         PROFILE(VC1Main)
         PROFILE(VC1Advanced)
         PROFILE(JPEGBaseline)
+        PROFILE(VP8Version0_3)
+        default:return "Unknow";
     }
     ASSERT(0);
     return "Unknown";
@@ -123,6 +128,8 @@
         ENTRYPOINT(Deblocking)
         ENTRYPOINT(EncSlice)
         ENTRYPOINT(EncPicture)
+        ENTRYPOINT(VideoProc)
+        default:return "Unknow";
     }
     ASSERT(0);
     return "Unknown";
diff --git a/test/basic/test_vaSurfaceAttrib.c b/test/basic/test_vaSurfaceAttrib.c
new file mode 100644
index 0000000..617d3e7
--- /dev/null
+++ b/test/basic/test_vaSurfaceAttrib.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define TEST_DESCRIPTION	"vaCreateSurfaces with different VASurfaceAttrib"
+
+#include "test_common.c"
+#include <va/va_drmcommon.h>
+
+void pre()
+{
+    test_init();
+}
+
+void test()
+{
+    VAEntrypoint entrypoints[5];
+    int num_entrypoints,slice_entrypoint;
+    VAConfigAttrib attrib[2];
+    VAConfigID config_id;
+    unsigned int fourcc, luma_stride, chroma_u_stride, chroma_v_stride, luma_offset, chroma_u_offset;
+    unsigned int chroma_v_offset, buffer_name;
+    unsigned int *p_buffer;
+    int i, ret;
+    char c;
+    int frame_width=640,  frame_height=480;
+    VASurfaceID surface_id;
+    VAImage image_id;
+    unsigned char *usrbuf;
+
+    usrbuf = (unsigned char*)malloc(frame_width * frame_height * 2);
+    ASSERT ( usrbuf != NULL);
+
+    VASurfaceAttribExternalBuffers  vaSurfaceExternBuf;
+    VASurfaceAttrib attrib_list[2];
+
+    va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileH264Baseline, entrypoints, &num_entrypoints);
+    ASSERT( VA_STATUS_SUCCESS == va_status );
+
+    for	(slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) {
+        if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice)
+            break;
+    }
+    if (slice_entrypoint == num_entrypoints) {
+        /* not find Slice entry point */
+        status("VAEntrypointEncSlice doesn't support, exit.\n");
+        ASSERT(0);
+    }
+
+    /* find out the format for the render target, and rate control mode */
+    attrib[0].type = VAConfigAttribRTFormat;
+    attrib[1].type = VAConfigAttribRateControl;
+    va_status = vaGetConfigAttributes(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice, &attrib[0], 2);
+    ASSERT( VA_STATUS_SUCCESS == va_status );
+
+    if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) {
+        /* not find desired YUV420 RT format */
+        status("VA_RT_FORMAT_YUV420 doesn't support, exit\n");
+        ASSERT(0);
+    }
+    if ((attrib[1].value & VA_RC_VBR) == 0) {
+        /* Can't find matched RC mode */
+        status("VBR mode doesn't found, exit\n");
+        ASSERT(0);
+    }
+
+    attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */
+    attrib[1].value = VA_RC_VBR; /* set to desired RC mode */
+
+    va_status = vaCreateConfig(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice, &attrib[0], 2, &config_id);
+    ASSERT( VA_STATUS_SUCCESS == va_status );
+
+    attrib_list[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
+    attrib_list[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
+    va_status = vaGetSurfaceAttributes(va_dpy, config_id, attrib_list, 2);
+    ASSERT( VA_STATUS_SUCCESS == va_status );
+
+    if (attrib_list[0].flags != VA_SURFACE_ATTRIB_NOT_SUPPORTED) {
+        status("supported memory type:\n");
+        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_VA)
+            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_VA\n");
+        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_V4L2)
+            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_V4L2\n");
+        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR)
+            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR\n");
+        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC)
+           status("\tVA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC\n");
+        if (attrib_list[0].value.value.i &  VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION)
+            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION\n");
+        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
+            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM\n");
+    }
+
+    if ((attrib_list[1].flags != VA_SURFACE_ATTRIB_NOT_SUPPORTED) &&
+            (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR)) {
+        status("vaCreateSurfaces from external usr pointer\n");
+
+        vaSurfaceExternBuf.buffers = (unsigned long*)malloc(sizeof(unsigned int));
+        vaSurfaceExternBuf.buffers[0] = usrbuf;
+        vaSurfaceExternBuf.num_buffers = 1;
+        vaSurfaceExternBuf.width = frame_width;
+        vaSurfaceExternBuf.height = frame_height;
+        vaSurfaceExternBuf.pitches[0] = vaSurfaceExternBuf.pitches[1] = vaSurfaceExternBuf.pitches[2] = frame_width;
+        //vaSurfaceExternBuf.flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
+        vaSurfaceExternBuf.pixel_format = VA_FOURCC_NV12;
+        //vaSurfaceExternBuf.pitches[0] = attribute_tpi->luma_stride;
+
+        attrib_list[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
+        attrib_list[1].value.type = VAGenericValueTypePointer;
+        attrib_list[1].value.value.p = (void *)&vaSurfaceExternBuf;
+
+        attrib_list[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
+        attrib_list[0].value.type = VAGenericValueTypeInteger;
+        attrib_list[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR;
+
+        va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, frame_width, frame_height, &surface_id, 1, attrib_list, 2);
+        ASSERT( VA_STATUS_SUCCESS == va_status );
+
+        va_status = vaDeriveImage(va_dpy, surface_id, &image_id);
+        ASSERT( VA_STATUS_SUCCESS == va_status );
+
+        va_status = vaMapBuffer(va_dpy, image_id.buf, (void**)&p_buffer);
+        ASSERT( VA_STATUS_SUCCESS == va_status );
+
+        memset(p_buffer, 0x80, image_id.width * image_id.height);
+
+        va_status = vaUnmapBuffer(va_dpy, image_id.buf);
+        ASSERT( VA_STATUS_SUCCESS == va_status );
+
+        va_status = vaDestroyImage(va_dpy, image_id.image_id);
+        ASSERT( VA_STATUS_SUCCESS == va_status );
+
+        va_status = vaDestroySurfaces(va_dpy, &surface_id, 1);
+        ASSERT( VA_STATUS_SUCCESS == va_status );
+
+    }
+
+    va_status = vaDestroyConfig(va_dpy, config_id);
+    ASSERT( VA_STATUS_SUCCESS == va_status );
+
+    free(usrbuf);
+
+}
+
+void post()
+{
+    test_terminate();
+}
diff --git a/test/common/Makefile.am b/test/common/Makefile.am
new file mode 100644
index 0000000..763847d
--- /dev/null
+++ b/test/common/Makefile.am
@@ -0,0 +1,63 @@
+# Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sub license, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+# 
+# The above copyright notice and this permission notice (including the
+# next paragraph) shall be included in all copies or substantial portions
+# of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+noinst_LTLIBRARIES = libva-display.la
+
+libva_display_cflags = \
+	-I$(top_srcdir)				\
+	-I$(top_srcdir)/va			\
+	-I$(top_builddir)			\
+	-DIN_LIBVA				\
+	$(NULL)
+
+libva_display_libs = \
+	$(top_builddir)/va/libva.la		\
+	$(NULL)
+
+source_c		= va_display.c
+source_h		= va_display.h
+
+if USE_X11
+source_c		+= va_display_x11.c
+libva_display_cflags	+= $(X11_CFLAGS)
+libva_display_libs	+= $(top_builddir)/va/libva-x11.la $(X11_LIBS)
+endif
+
+if USE_DRM
+source_c		+= va_display_drm.c
+libva_display_cflags	+= $(DRM_CFLAGS)
+libva_display_libs	+= $(top_builddir)/va/libva-drm.la $(DRM_LIBS)
+endif
+
+if USE_WAYLAND
+source_c		+= va_display_wayland.c
+libva_display_cflags	+= $(WAYLAND_CFLAGS)
+libva_display_libs	+= $(top_builddir)/va/libva-wayland.la $(WAYLAND_LIBS)
+endif
+
+libva_display_la_SOURCES= $(source_c)
+noinst_HEADERS		= $(source_h)
+libva_display_la_CFLAGS	= $(libva_display_cflags)
+libva_display_la_LIBADD	= $(libva_display_libs)
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/test/common/va_display.c b/test/common/va_display.c
new file mode 100644
index 0000000..dd58dd2
--- /dev/null
+++ b/test/common/va_display.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "sysdeps.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <va/va.h>
+#include "va_display.h"
+
+extern const VADisplayHooks va_display_hooks_android;
+extern const VADisplayHooks va_display_hooks_wayland;
+extern const VADisplayHooks va_display_hooks_x11;
+extern const VADisplayHooks va_display_hooks_drm;
+
+static const VADisplayHooks *g_display_hooks;
+static const VADisplayHooks *g_display_hooks_available[] = {
+#ifdef ANDROID
+    &va_display_hooks_android,
+#else
+#ifdef HAVE_VA_WAYLAND
+    &va_display_hooks_wayland,
+#endif
+#ifdef HAVE_VA_X11
+    &va_display_hooks_x11,
+#endif
+#ifdef HAVE_VA_DRM
+    &va_display_hooks_drm,
+#endif
+#endif
+    NULL
+};
+
+static const char *g_display_name;
+
+static const char *
+get_display_name(int argc, char *argv[])
+{
+    const char *display_name = NULL;
+    int i;
+
+    for (i = 1; i < argc; i++) {
+        if (strcmp(argv[i], "--display") != 0)
+            continue;
+        argv[i] = NULL;
+
+        if (++i < argc) {
+            display_name = argv[i];
+            argv[i] = NULL;
+        }
+    }
+    return display_name;
+}
+
+static void
+print_display_names(void)
+{
+    const VADisplayHooks **h;
+
+    printf("Available displays:\n");
+    for (h = g_display_hooks_available; *h != NULL; h++)
+        printf("  %s\n", (*h)->name);
+}
+
+static void
+sanitize_args(int *argc, char *argv[])
+{
+    char **out_args = argv;
+    int i, n = *argc;
+
+    for (i = 0; i < n; i++) {
+        if (argv[i])
+            *out_args++ = argv[i];
+    }
+    *out_args = NULL;
+    *argc = out_args - argv;
+}
+
+void
+va_init_display_args(int *argc, char *argv[])
+{
+    const char *display_name;
+
+    display_name = get_display_name(*argc, argv);
+    if (display_name && strcmp(display_name, "help") == 0) {
+        print_display_names();
+        exit(0);
+    }
+    g_display_name = display_name;
+
+    sanitize_args(argc, argv);
+}
+
+VADisplay
+va_open_display(void)
+{
+    VADisplay va_dpy = NULL;
+    unsigned int i;
+
+    for (i = 0; !va_dpy && g_display_hooks_available[i]; i++) {
+        g_display_hooks = g_display_hooks_available[i];
+        if (g_display_name &&
+            strcmp(g_display_name, g_display_hooks->name) != 0)
+            continue;
+        if (!g_display_hooks->open_display)
+            continue;
+        va_dpy = g_display_hooks->open_display();
+    }
+
+    if (!va_dpy)  {
+        fprintf(stderr, "error: failed to initialize display");
+        if (g_display_name)
+            fprintf(stderr, " '%s'", g_display_name);
+        fprintf(stderr, "\n");
+        abort();
+    }
+    return va_dpy;
+}
+
+void
+va_close_display(VADisplay va_dpy)
+{
+    if (!va_dpy)
+        return;
+
+    if (g_display_hooks && g_display_hooks->close_display)
+        g_display_hooks->close_display(va_dpy);
+}
+
+VAStatus
+va_put_surface(
+    VADisplay          va_dpy,
+    VASurfaceID        surface,
+    const VARectangle *src_rect,
+    const VARectangle *dst_rect
+)
+{
+    if (!va_dpy)
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+
+    if (g_display_hooks && g_display_hooks->put_surface)
+        return g_display_hooks->put_surface(va_dpy, surface, src_rect, dst_rect);
+    return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
diff --git a/test/common/va_display.h b/test/common/va_display.h
new file mode 100644
index 0000000..4ed33e0
--- /dev/null
+++ b/test/common/va_display.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_DISPLAY_H
+#define VA_DISPLAY_H
+
+#include <va/va.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    const char *name;
+    VADisplay (*open_display)   (void);
+    void      (*close_display)  (VADisplay va_dpy);
+    VAStatus  (*put_surface)    (VADisplay va_dpy, VASurfaceID surface,
+                                 const VARectangle *src_rect,
+                                 const VARectangle *dst_rect);
+} VADisplayHooks;
+
+void
+va_init_display_args(int *argc, char *argv[]);
+
+VADisplay
+va_open_display(void);
+
+void
+va_close_display(VADisplay va_dpy);
+
+VAStatus
+va_put_surface(
+    VADisplay          va_dpy,
+    VASurfaceID        surface,
+    const VARectangle *src_rect,
+    const VARectangle *dst_rect
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_DISPLAY_H */
diff --git a/test/common/va_display_android.cpp b/test/common/va_display_android.cpp
new file mode 100644
index 0000000..b05a47a
--- /dev/null
+++ b/test/common/va_display_android.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <va/va_android.h>
+#include "va_display.h"
+
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/ISurfaceComposer.h>
+
+static unsigned int fake_display = 0xdeada01d;
+
+using namespace android;
+
+static sp<SurfaceComposerClient> client = NULL;
+static sp<SurfaceControl> surface_ctr = NULL;
+static sp<ANativeWindow> anw = NULL;
+
+static VADisplay
+va_open_display_android(void)
+{
+    return vaGetDisplay(&fake_display);
+}
+
+static void
+va_close_display_android(VADisplay va_dpy)
+{
+}
+
+static int create_window(int x, int y, int width, int height)
+{
+    client = new SurfaceComposerClient();
+    
+    surface_ctr = client->createSurface(
+        String8("Test Surface"),
+        width, height,
+        PIXEL_FORMAT_RGB_888, 0);
+
+    SurfaceComposerClient::openGlobalTransaction();
+    surface_ctr->setLayer(0x7FFFFFFF);
+    surface_ctr->show();
+    SurfaceComposerClient::closeGlobalTransaction();
+    
+    SurfaceComposerClient::openGlobalTransaction();
+    surface_ctr->setPosition(x, y);
+    SurfaceComposerClient::closeGlobalTransaction();
+    
+    SurfaceComposerClient::openGlobalTransaction();
+    surface_ctr->setSize(width, height);
+    SurfaceComposerClient::closeGlobalTransaction();
+    
+    anw = surface_ctr->getSurface();
+    
+    return 0;
+}
+
+
+static VAStatus
+va_put_surface_android(
+    VADisplay          va_dpy,
+    VASurfaceID        surface,
+    const VARectangle *src_rect,
+    const VARectangle *dst_rect
+)
+{
+    if (anw == NULL)
+        create_window(dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height);
+
+    return vaPutSurface(va_dpy, surface, anw,
+                        src_rect->x, src_rect->y,
+                        src_rect->width, src_rect->height,
+                        dst_rect->x, dst_rect->y,
+                        dst_rect->width, dst_rect->height,
+                        NULL, 0,
+                        VA_FRAME_PICTURE);
+}
+
+extern "C"
+const VADisplayHooks va_display_hooks_android = {
+    "android",
+    va_open_display_android,
+    va_close_display_android,
+    va_put_surface_android
+};
diff --git a/test/common/va_display_drm.c b/test/common/va_display_drm.c
new file mode 100644
index 0000000..aa9f60a
--- /dev/null
+++ b/test/common/va_display_drm.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef IN_LIBVA
+# include "va/drm/va_drm.h"
+#else
+# include <va/va_drm.h>
+#endif
+#include "va_display.h"
+
+static int drm_fd = -1;
+
+static VADisplay
+va_open_display_drm(void)
+{
+    drm_fd = open("/dev/dri/card0", O_RDWR);
+    if (drm_fd < 0) {
+        fprintf(stderr, "error: can't open DRM connection!\n");
+        return NULL;
+    }
+    return vaGetDisplayDRM(drm_fd);
+}
+
+static void
+va_close_display_drm(VADisplay va_dpy)
+{
+    if (drm_fd < 0)
+        return;
+
+    close(drm_fd);
+    drm_fd = -1;
+}
+
+
+static VAStatus
+va_put_surface_drm(
+    VADisplay          va_dpy,
+    VASurfaceID        surface,
+    const VARectangle *src_rect,
+    const VARectangle *dst_rect
+)
+{
+    return VA_STATUS_ERROR_OPERATION_FAILED;
+}
+
+const VADisplayHooks va_display_hooks_drm = {
+    "drm",
+    va_open_display_drm,
+    va_close_display_drm,
+    va_put_surface_drm,
+};
diff --git a/test/common/va_display_wayland.c b/test/common/va_display_wayland.c
new file mode 100644
index 0000000..abcb2b6
--- /dev/null
+++ b/test/common/va_display_wayland.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef IN_LIBVA
+# include "va/wayland/va_wayland.h"
+#else
+# include <va/va_wayland.h>
+#endif
+#include "va_display.h"
+
+struct display {
+    struct wl_display          *display;
+    struct wl_registry         *registry;
+    struct wl_compositor       *compositor;
+    struct wl_shell            *shell;
+    struct wl_shell_surface    *shell_surface;
+    struct wl_surface          *surface;
+    unsigned int                ref_count;
+    int                         event_fd;
+};
+
+static struct display *g_display;
+
+static void
+registry_handle_global(
+    void               *data,
+    struct wl_registry *registry,
+    uint32_t            id,
+    const char         *interface,
+    uint32_t            version
+)
+{
+    struct display * const d = data;
+
+    if (strcmp(interface, "wl_compositor") == 0)
+        d->compositor =
+            wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+    else if (strcmp(interface, "wl_shell") == 0)
+        d->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
+}
+
+static const struct wl_registry_listener registry_listener = {
+    registry_handle_global,
+    NULL,
+};
+
+static VADisplay
+va_open_display_wayland(void)
+{
+    struct display *d;
+
+    if (g_display) {
+        d = g_display;
+        d->ref_count++;
+    }
+    else {
+        d = calloc(1, sizeof(*d));
+        if (!d)
+            return NULL;
+        d->event_fd = -1;
+
+        d->display = wl_display_connect(NULL);
+        if (!d->display) {
+            free(d);
+            return NULL;
+        }
+        wl_display_set_user_data(d->display, d);
+        d->registry = wl_display_get_registry(d->display);
+        wl_registry_add_listener(d->registry, &registry_listener, d);
+        d->event_fd = wl_display_get_fd(d->display);
+        wl_display_dispatch(d->display);
+
+        d->ref_count = 1;
+        g_display = d;
+    }
+    return vaGetDisplayWl(d->display);
+}
+
+static void
+va_close_display_wayland(VADisplay va_dpy)
+{
+    struct display * const d = g_display;
+
+    if (!d || --d->ref_count > 0)
+        return;
+
+    if (d->surface) {
+        wl_surface_destroy(d->surface);
+        d->surface = NULL;
+    }
+
+    if (d->shell_surface) {
+        wl_shell_surface_destroy(d->shell_surface);
+        d->shell_surface = NULL;
+    }
+
+    if (d->shell) {
+        wl_shell_destroy(d->shell);
+        d->shell = NULL;
+    }
+
+    if (d->compositor) {
+        wl_compositor_destroy(d->compositor);
+        d->compositor = NULL;
+    }
+
+    if (d->display) {
+        wl_display_disconnect(d->display);
+        d->display = NULL;
+    }
+    free(g_display);
+    g_display = NULL;
+}
+
+static int
+ensure_window(VADisplay va_dpy, unsigned int width, unsigned int height)
+{
+    struct display * const d = g_display;
+
+    if (!d->surface) {
+        d->surface = wl_compositor_create_surface(d->compositor);
+        if (!d->surface)
+            return 0;
+    }
+
+    if (!d->shell_surface) {
+        d->shell_surface = wl_shell_get_shell_surface(d->shell, d->surface);
+        if (!d->shell_surface)
+            return 0;
+        wl_shell_surface_set_toplevel(d->shell_surface);
+    }
+    return 1;
+}
+
+static VAStatus
+va_put_surface_wayland(
+    VADisplay          va_dpy,
+    VASurfaceID        surface,
+    const VARectangle *src_rect,
+    const VARectangle *dst_rect
+)
+{
+    struct display * const d = g_display;
+    VAStatus va_status;
+    struct wl_buffer *buffer;
+
+    if (!ensure_window(va_dpy, dst_rect->width, dst_rect->height))
+        return VA_STATUS_ERROR_ALLOCATION_FAILED;
+
+    va_status = vaGetSurfaceBufferWl(va_dpy, surface, VA_FRAME_PICTURE, &buffer);
+    if (va_status != VA_STATUS_SUCCESS)
+        return va_status;
+
+    wl_surface_attach(d->surface, buffer, 0, 0);
+    wl_surface_damage(
+         d->surface,
+         dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height
+     );
+
+    wl_surface_commit(d->surface);
+    wl_display_flush(d->display);
+    return VA_STATUS_SUCCESS;
+}
+
+const VADisplayHooks va_display_hooks_wayland = {
+    "wayland",
+    va_open_display_wayland,
+    va_close_display_wayland,
+    va_put_surface_wayland,
+};
diff --git a/test/common/va_display_x11.c b/test/common/va_display_x11.c
new file mode 100644
index 0000000..336bf86
--- /dev/null
+++ b/test/common/va_display_x11.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <va/va_x11.h>
+#include "va_display.h"
+
+static Display *x11_display;
+static Window   x11_window;
+
+static VADisplay
+va_open_display_x11(void)
+{
+    x11_display = XOpenDisplay(NULL);
+    if (!x11_display) {
+        fprintf(stderr, "error: can't connect to X server!\n");
+        return NULL;
+    }
+    return vaGetDisplay(x11_display);
+}
+
+static void
+va_close_display_x11(VADisplay va_dpy)
+{
+    if (!x11_display)
+        return;
+
+    if (x11_window) {
+        XUnmapWindow(x11_display, x11_window);
+        XDestroyWindow(x11_display, x11_window);
+        x11_window = None;
+    }
+    XCloseDisplay(x11_display);
+    x11_display = NULL;
+}
+
+static int
+ensure_window(unsigned int width, unsigned int height)
+{
+    Window win, rootwin;
+    unsigned int black_pixel, white_pixel;
+    int screen;
+
+    if (!x11_display)
+        return 0;
+
+    if (x11_window) {
+        XResizeWindow(x11_display, x11_window, width, height);
+        return 1;
+    }
+
+    screen      = DefaultScreen(x11_display);
+    rootwin     = RootWindow(x11_display, screen);
+    black_pixel = BlackPixel(x11_display, screen);
+    white_pixel = WhitePixel(x11_display, screen);
+
+    win = XCreateSimpleWindow(
+        x11_display,
+        rootwin,
+        0, 0, width, height,
+        1, black_pixel, white_pixel
+    );
+    if (!win)
+        return 0;
+    x11_window = win;
+
+    XMapWindow(x11_display, x11_window);
+    XSync(x11_display, False);
+    return 1;
+}
+
+static inline bool
+validate_rect(const VARectangle *rect)
+{
+    return (rect            &&
+            rect->x >= 0    &&
+            rect->y >= 0    &&
+            rect->width > 0 &&
+            rect->height > 0);
+}
+
+static VAStatus
+va_put_surface_x11(
+    VADisplay          va_dpy,
+    VASurfaceID        surface,
+    const VARectangle *src_rect,
+    const VARectangle *dst_rect
+)
+{
+    unsigned int win_width, win_height;
+
+    if (!va_dpy)
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+    if (surface == VA_INVALID_SURFACE)
+        return VA_STATUS_ERROR_INVALID_SURFACE;
+    if (!validate_rect(src_rect) || !validate_rect(dst_rect))
+        return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+    win_width  = dst_rect->x + dst_rect->width;
+    win_height = dst_rect->y + dst_rect->height;
+    if (!ensure_window(win_width, win_height))
+        return VA_STATUS_ERROR_ALLOCATION_FAILED;
+    return vaPutSurface(va_dpy, surface, x11_window,
+                        src_rect->x, src_rect->y,
+                        src_rect->width, src_rect->height,
+                        dst_rect->x, dst_rect->y,
+                        dst_rect->width, dst_rect->height,
+                        NULL, 0,
+                        VA_FRAME_PICTURE);
+}
+
+const VADisplayHooks va_display_hooks_x11 = {
+    "x11",
+    va_open_display_x11,
+    va_close_display_x11,
+    va_put_surface_x11,
+};
diff --git a/test/decode/Android.mk b/test/decode/Android.mk
index 3541ee2..52f7bfd 100755
--- a/test/decode/Android.mk
+++ b/test/decode/Android.mk
@@ -6,20 +6,22 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-  mpeg2vldemo.cpp	\
+	mpeg2vldemo.cpp		\
+	../common/va_display.c	\
+	../common/va_display_android.cpp
 
 LOCAL_CFLAGS += \
-    -DANDROID  
+    -DANDROID
 
 LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/	\
-  $(TARGET_OUT_HEADERS)/X11	
+  $(LOCAL_PATH)/../../va \
+  $(LOCAL_PATH)/../common \
+  $(TARGET_OUT_HEADERS)/libva
 
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE :=	mpeg2vldemo
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := libva libva-android libdl libdrm libcutils libutils libgui
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/test/decode/Makefile.am b/test/decode/Makefile.am
index d0c5f39..6fffd31 100644
--- a/test/decode/Makefile.am
+++ b/test/decode/Makefile.am
@@ -20,17 +20,30 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-bin_PROGRAMS = mpeg2vldemo
+bin_PROGRAMS = mpeg2vldemo loadjpeg
 
-INCLUDES = -I$(top_srcdir)
+INCLUDES = \
+	-I$(top_srcdir)				\
+	-I$(top_srcdir)/test/common		\
+	$(NULL)
 
-TEST_LIBS = $(top_builddir)/va/$(libvabackendlib) $(top_builddir)/va/$(libvacorelib) -lX11
+TEST_LIBS = \
+	$(top_builddir)/va/libva.la		\
+	$(top_builddir)/test/common/libva-display.la	\
+	$(NULL)
 
-mpeg2vldemo_LDADD = $(TEST_LIBS)
-mpeg2vldemo_SOURCES = mpeg2vldemo.cpp
+mpeg2vldemo_LDADD	= $(TEST_LIBS)
+mpeg2vldemo_SOURCES	= mpeg2vldemo.cpp
 
+loadjpeg_LDADD		= $(TEST_LIBS)
+loadjpeg_SOURCES	= loadjpeg.c tinyjpeg.c
 
 valgrind:	$(bin_PROGRAMS)
 	for a in $(bin_PROGRAMS); do \
 		valgrind --leak-check=full --show-reachable=yes .libs/$$a; \
 	done
+
+EXTRA_DIST = \
+	tinyjpeg.h		\
+	tinyjpeg-internal.h	\
+	$(NULL)
diff --git a/test/decode/loadjpeg.c b/test/decode/loadjpeg.c
new file mode 100644
index 0000000..7a9a235
--- /dev/null
+++ b/test/decode/loadjpeg.c
@@ -0,0 +1,137 @@
+/*
+ * Small jpeg decoder library - testing application
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * Copyright (c) 2012 Intel Corporation.
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "tinyjpeg.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "va_display.h"
+
+static void exitmessage(const char *message) __attribute__((noreturn));
+static void exitmessage(const char *message)
+{
+  printf("%s\n", message);
+  exit(0);
+}
+
+static int filesize(FILE *fp)
+{
+  long pos;
+  fseek(fp, 0, SEEK_END);
+  pos = ftell(fp);
+  fseek(fp, 0, SEEK_SET);
+  return pos;
+}
+
+/**
+ * Load one jpeg image, and decompress it, and save the result.
+ */
+int convert_one_image(const char *infilename)
+{
+  FILE *fp;
+  unsigned int length_of_file;
+  unsigned int width, height;
+  unsigned char *buf;
+  struct jdec_private *jdec;
+
+  /* Load the Jpeg into memory */
+  fp = fopen(infilename, "rb");
+  if (fp == NULL)
+    exitmessage("Cannot open filename\n");
+  length_of_file = filesize(fp);
+  buf = (unsigned char *)malloc(length_of_file + 4);
+  if (buf == NULL)
+    exitmessage("Not enough memory for loading file\n");
+  fread(buf, length_of_file, 1, fp);
+  fclose(fp);
+
+  /* Decompress it */
+  jdec = tinyjpeg_init();
+  if (jdec == NULL)
+    exitmessage("Not enough memory to alloc the structure need for decompressing\n");
+
+  if (tinyjpeg_parse_header(jdec, buf, length_of_file)<0)
+    exitmessage(tinyjpeg_get_errorstring(jdec));
+
+  /* Get the size of the image */
+  tinyjpeg_get_size(jdec, &width, &height);
+
+  printf("Decoding JPEG image %dx%d...\n", width, height);
+  if (tinyjpeg_decode(jdec) < 0)
+    exitmessage(tinyjpeg_get_errorstring(jdec));
+
+  tinyjpeg_free(jdec);
+
+  free(buf);
+  return 0;
+}
+
+static void usage(void)
+{
+    fprintf(stderr, "Usage: loadjpeg <input_filename.jpeg> \n");
+    exit(1);
+}
+
+/**
+ * main
+ *
+ */
+int main(int argc, char *argv[])
+{
+  char *input_filename;
+  clock_t start_time, finish_time;
+  unsigned int duration;
+  int current_argument;
+
+  va_init_display_args(&argc, argv);
+
+  if (argc < 2)
+    usage();
+
+  current_argument = 1;
+  input_filename = argv[current_argument];
+
+  start_time = clock();
+  convert_one_image(input_filename);
+  finish_time = clock();
+  duration = finish_time - start_time;
+  printf("Decoding finished in %u ticks\n", duration);
+
+  return 0;
+}
+
+
+
+
diff --git a/test/decode/mpeg2vldemo.cpp b/test/decode/mpeg2vldemo.cpp
index 9246dfe..715ea49 100644
--- a/test/decode/mpeg2vldemo.cpp
+++ b/test/decode/mpeg2vldemo.cpp
@@ -43,30 +43,7 @@
 #include <fcntl.h>
 #include <assert.h>
 #include <va/va.h>
-
-#ifdef ANDROID
-#include <va/va_android.h>
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <binder/MemoryHeapBase.h>
-#define Display unsigned int
-
-using namespace android;
-sp<SurfaceComposerClient> client;
-sp<Surface> android_surface;
-sp<ISurface> android_isurface;
-sp<SurfaceControl> surface_ctrl;
-#include "../android_winsys.cpp"
-#else
-#include <va/va_x11.h>
-#include <X11/Xlib.h>
-#endif
+#include "va_display.h"
 
 #define CHECK_VASTATUS(va_status,func)                                  \
 if (va_status != VA_STATUS_SUCCESS) {                                   \
@@ -169,28 +146,16 @@
     VAContextID context_id;
     VABufferID pic_param_buf,iqmatrix_buf,slice_param_buf,slice_data_buf;
     int major_ver, minor_ver;
-    Display *x11_display;
     VADisplay	va_dpy;
     VAStatus va_status;
     int putsurface=0;
 
+    va_init_display_args(&argc, argv);
+
     if (argc > 1)
         putsurface=1;
-#ifdef ANDROID 
-    x11_display = (Display*)malloc(sizeof(Display));
-    *(x11_display ) = 0x18c34078;
-#else
-    x11_display = XOpenDisplay(":0.0");
-#endif
-
-    if (x11_display == NULL) {
-      fprintf(stderr, "Can't connect X server!\n");
-      exit(-1);
-    }
-
-    assert(x11_display);
     
-    va_dpy = vaGetDisplay(x11_display);
+    va_dpy = va_open_display();
     va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
     assert(va_status == VA_STATUS_SUCCESS);
     
@@ -289,29 +254,20 @@
     CHECK_VASTATUS(va_status, "vaSyncSurface");
 
     if (putsurface) {
-#ifdef ANDROID 
-        sp<ProcessState> proc(ProcessState::self());
-        ProcessState::self()->startThreadPool();
+        VARectangle src_rect, dst_rect;
 
-        printf("Create window0 for thread0\n");
-        SURFACE_CREATE(client,surface_ctrl,android_surface, android_isurface, 0, 0, WIN_WIDTH, WIN_HEIGHT);
+        src_rect.x      = 0;
+        src_rect.y      = 0;
+        src_rect.width  = CLIP_WIDTH;
+        src_rect.height = CLIP_HEIGHT;
 
-        va_status = vaPutSurface(va_dpy, surface_id, android_isurface,
-                0,0,CLIP_WIDTH,CLIP_HEIGHT,
-                0,0,WIN_WIDTH,WIN_HEIGHT,
-                NULL,0,0);
-#else
-        Window  win;
-        win = XCreateSimpleWindow(x11_display, RootWindow(x11_display, 0), 0, 0,
-                WIN_WIDTH,WIN_HEIGHT, 0, 0, WhitePixel(x11_display, 0));
-        XMapWindow(x11_display, win);
-        XSync(x11_display, False);
-        va_status = vaPutSurface(va_dpy, surface_id, win,
-                                0,0,CLIP_WIDTH,CLIP_HEIGHT,
-                                0,0,WIN_WIDTH,WIN_HEIGHT,
-                                NULL,0,0);
-#endif
-       CHECK_VASTATUS(va_status, "vaPutSurface");
+        dst_rect.x      = 0;
+        dst_rect.y      = 0;
+        dst_rect.width  = WIN_WIDTH;
+        dst_rect.height = WIN_HEIGHT;
+
+        va_status = va_put_surface(va_dpy, surface_id, &src_rect, &dst_rect);
+        CHECK_VASTATUS(va_status, "vaPutSurface");
     }
     printf("press any key to exit\n");
     getchar();
@@ -321,11 +277,6 @@
     vaDestroyContext(va_dpy,context_id);
 
     vaTerminate(va_dpy);
-#ifdef ANDROID
-    free(x11_display);
-#else
-    XCloseDisplay(x11_display);
-#endif
-    
+    va_close_display(va_dpy);
     return 0;
 }
diff --git a/test/decode/tinyjpeg-internal.h b/test/decode/tinyjpeg-internal.h
new file mode 100644
index 0000000..6801c31
--- /dev/null
+++ b/test/decode/tinyjpeg-internal.h
@@ -0,0 +1,121 @@
+/*
+ * Small jpeg decoder library (Internal header)
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * Copyright (c) 2012 Intel Corporation.
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#ifndef __TINYJPEG_INTERNAL_H_
+#define __TINYJPEG_INTERNAL_H_
+
+#include <setjmp.h>
+
+#define SANITY_CHECK 1
+
+struct jdec_private;
+
+#define HUFFMAN_BITS_SIZE  256
+
+#define HUFFMAN_TABLES	   4
+#define COMPONENTS	   4
+#define JPEG_MAX_WIDTH	   2048
+#define JPEG_MAX_HEIGHT	   2048
+#define JPEG_SCAN_MAX	   4
+
+enum std_markers {
+   DQT  = 0xDB, /* Define Quantization Table */
+   SOF  = 0xC0, /* Start of Frame (size information) */
+   DHT  = 0xC4, /* Huffman Table */
+   SOI  = 0xD8, /* Start of Image */
+   SOS  = 0xDA, /* Start of Scan */
+   RST  = 0xD0, /* Reset Marker d0 -> .. */
+   RST7 = 0xD7, /* Reset Marker .. -> d7 */
+   EOI  = 0xD9, /* End of Image */
+   DRI  = 0xDD, /* Define Restart Interval */
+   APP0 = 0xE0,
+};
+
+
+struct huffman_table
+{
+  /*bits and values*/
+	unsigned char bits[16];
+	unsigned char values[256];
+};
+
+struct component 
+{
+  unsigned int Hfactor;
+  unsigned int Vfactor;
+  unsigned char quant_table_index;
+  unsigned int cid;
+};
+
+
+typedef void (*decode_MCU_fct) (struct jdec_private *priv);
+typedef void (*convert_colorspace_fct) (struct jdec_private *priv);
+
+struct jpeg_sos
+{
+  unsigned int nr_components;
+  struct {
+    unsigned int component_id;
+    unsigned int dc_selector;
+    unsigned int ac_selector;
+  }components[4];
+};
+
+struct jdec_private
+{
+  /* Public variables */
+  unsigned int width[JPEG_SCAN_MAX], height[JPEG_SCAN_MAX];	/* Size of the image */
+
+  /* Private variables */
+  const unsigned char *stream_begin, *stream_end,*stream_scan;
+  unsigned int stream_length;
+
+  const unsigned char *stream;	/* Pointer to the current stream */
+
+  struct component component_infos[COMPONENTS];
+  unsigned int nf_components;
+  unsigned char Q_tables[COMPONENTS][64];		/* quantization tables, zigzag*/
+  unsigned char Q_tables_valid[COMPONENTS];
+  struct huffman_table HTDC[HUFFMAN_TABLES];	/* DC huffman tables   */
+  unsigned char HTDC_valid[HUFFMAN_TABLES];
+  struct huffman_table HTAC[HUFFMAN_TABLES];	/* AC huffman tables   */
+  unsigned char HTAC_valid[HUFFMAN_TABLES];
+  struct jpeg_sos cur_sos;  /* current sos values*/
+  int default_huffman_table_initialized;
+  int restart_interval;
+};
+
+#endif
+
diff --git a/test/decode/tinyjpeg.c b/test/decode/tinyjpeg.c
new file mode 100644
index 0000000..10ff99b
--- /dev/null
+++ b/test/decode/tinyjpeg.c
@@ -0,0 +1,870 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * Copyright (c) 2012 Intel Corporation.
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+// for libva
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <va/va.h>
+#include <va/va_dec_jpeg.h>
+#include "va_display.h"
+
+
+#define cY	0
+#define cCb	1
+#define cCr	2
+
+#define BLACK_Y 0
+#define BLACK_U 127
+#define BLACK_V 127
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
+
+#if DEBUG
+#define trace(fmt, args...) do { \
+   fprintf(stderr, fmt, ## args); \
+   fflush(stderr); \
+} while(0)
+#else
+#define trace(fmt, args...) do { } while (0)
+#endif
+#define error(fmt, args...) do { \
+   snprintf(error_string, sizeof(error_string), fmt, ## args); \
+   return -1; \
+} while(0)
+/* The variables for different image scans */
+static int scan_num=0;
+static int next_image_found=0;
+/* Global variable to return the last error found while deconding */
+static char error_string[256];
+static VAHuffmanTableBufferJPEGBaseline default_huffman_table_param={
+    huffman_table:
+    {
+        // lumiance component
+        {
+            num_dc_codes:{0,1,5,1,1,1,1,1,1,0,0,0}, // 12 bits is ok for baseline profile
+            dc_values:{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b},
+            num_ac_codes:{0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,125},
+            ac_values:{
+              0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+              0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+              0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+              0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+              0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+              0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+              0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+              0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+              0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+              0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+              0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+              0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+              0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+              0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+              0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+              0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+              0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+              0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+              0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+              0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+              0xf9, 0xfa
+           },/*,0xonly,0xthe,0xfirst,0x162,0xbytes,0xare,0xavailable,0x*/
+        },
+        // chrom component
+        {
+            num_dc_codes:{0,3,1,1,1,1,1,1,1,1,1,0}, // 12 bits is ok for baseline profile
+            dc_values:{0,1,2,3,4,5,6,7,8,9,0xa,0xb},
+            num_ac_codes:{0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,119},
+            ac_values:{
+              0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+              0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+              0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+              0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+              0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+              0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+              0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+              0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+              0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+              0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+              0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+              0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+              0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+              0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+              0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+              0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+              0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+              0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+              0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+              0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+              0xf9, 0xfa
+            },/*,0xonly,0xthe,0xfirst,0x162,0xbytes,0xare,0xavailable,0x*/
+        },
+    }
+};
+
+#define be16_to_cpu(x) (((x)[0]<<8)|(x)[1])
+
+
+static int build_default_huffman_tables(struct jdec_private *priv)
+{
+    int i = 0;
+	if (priv->default_huffman_table_initialized)
+		return 0;
+
+    for (i = 0; i < 4; i++) {
+        priv->HTDC_valid[i] = 1;
+        memcpy(priv->HTDC[i].bits, default_huffman_table_param.huffman_table[i].num_dc_codes, 16);
+        memcpy(priv->HTDC[i].values, default_huffman_table_param.huffman_table[i].dc_values, 16);
+        priv->HTAC_valid[i] = 1;
+        memcpy(priv->HTAC[i].bits, default_huffman_table_param.huffman_table[i].num_ac_codes, 16);
+        memcpy(priv->HTAC[i].values, default_huffman_table_param.huffman_table[i].ac_values, 256);
+    }
+	priv->default_huffman_table_initialized = 1;
+	return 0;
+}
+
+
+static void print_SOF(const unsigned char *stream)
+{
+  int width, height, nr_components, precision;
+#if DEBUG
+  const char *nr_components_to_string[] = {
+     "????",
+     "Grayscale",
+     "????",
+     "YCbCr",
+     "CYMK"
+  };
+#endif
+
+  precision = stream[2];
+  height = be16_to_cpu(stream+3);
+  width  = be16_to_cpu(stream+5);
+  nr_components = stream[7];
+
+  trace("> SOF marker\n");
+  trace("Size:%dx%d nr_components:%d (%s)  precision:%d\n", 
+      width, height,
+      nr_components, nr_components_to_string[nr_components],
+      precision);
+}
+
+static int parse_DQT(struct jdec_private *priv, const unsigned char *stream)
+{
+  int qi;
+  const unsigned char *dqt_block_end;
+
+  trace("> DQT marker\n");
+  dqt_block_end = stream + be16_to_cpu(stream);
+  stream += 2;	/* Skip length */
+
+  while (stream < dqt_block_end)
+   {
+     qi = *stream++;
+#if SANITY_CHECK
+     if (qi>>4)
+       error("16 bits quantization table is not supported\n");
+     if (qi>4)
+       error("No more 4 quantization table is supported (got %d)\n", qi);
+#endif
+     memcpy(priv->Q_tables[qi&0x0F], stream, 64);
+     priv->Q_tables_valid[qi & 0x0f] = 1;
+     stream += 64;
+   }
+  trace("< DQT marker\n");
+  return 0;
+}
+
+static int parse_SOF(struct jdec_private *priv, const unsigned char *stream)
+{
+  int i, width, height, nr_components, cid, sampling_factor;
+  unsigned char Q_table;
+  struct component *c;
+
+  trace("> SOF marker\n");
+  print_SOF(stream);
+
+  height = be16_to_cpu(stream+3);
+  width  = be16_to_cpu(stream+5);
+  nr_components = stream[7];
+  priv->nf_components = nr_components;
+#if SANITY_CHECK
+  if (stream[2] != 8)
+    error("Precision other than 8 is not supported\n");
+  if (width>JPEG_MAX_WIDTH || height>JPEG_MAX_HEIGHT)
+    printf("WARNING:Width and Height (%dx%d) seems suspicious\n", width, height);
+  if (nr_components != 3)
+    printf("ERROR:We only support YUV images\n");
+  if (height%16)
+    printf("WARNING:Height need to be a multiple of 16 (current height is %d)\n", height);
+  if (width%16)
+    printf("WARNING:Width need to be a multiple of 16 (current Width is %d)\n", width);
+#endif
+  stream += 8;
+  for (i=0; i<nr_components; i++) {
+     cid = *stream++;
+     sampling_factor = *stream++;
+     Q_table = *stream++;
+     c = &priv->component_infos[i];
+     c->cid = cid;
+     if (Q_table >= COMPONENTS)
+       error("Bad Quantization table index (got %d, max allowed %d)\n", Q_table, COMPONENTS-1);
+     c->Vfactor = sampling_factor&0xf;
+     c->Hfactor = sampling_factor>>4;
+     c->quant_table_index = Q_table;
+     trace("Component:%d  factor:%dx%d  Quantization table:%d\n",
+           cid, c->Hfactor, c->Vfactor, Q_table );
+
+  }
+  priv->width[scan_num] = width;
+  priv->height[scan_num] = height;
+
+  trace("< SOF marker\n");
+
+  return 0;
+}
+
+static int parse_SOS(struct jdec_private *priv, const unsigned char *stream)
+{
+  unsigned int i, cid, table;
+  unsigned int nr_components = stream[2];
+
+  trace("> SOS marker\n");
+
+  priv->cur_sos.nr_components= nr_components;
+
+  stream += 3;
+  for (i=0;i<nr_components;i++) {
+     cid = *stream++;
+     table = *stream++;
+     priv->cur_sos.components[i].component_id = cid;
+     priv->cur_sos.components[i].dc_selector = ((table>>4)&0x0F);
+     priv->cur_sos.components[i].ac_selector = (table&0x0F);
+#if SANITY_CHECK
+     if ((table&0xf)>=4)
+	error("We do not support more than 2 AC Huffman table\n");
+     if ((table>>4)>=4)
+	error("We do not support more than 2 DC Huffman table\n");
+     if (cid != priv->component_infos[i].cid)
+        error("SOS cid order (%d:%d) isn't compatible with the SOF marker (%d:%d)\n",
+	      i, cid, i, priv->component_infos[i].cid);
+     trace("ComponentId:%d  tableAC:%d tableDC:%d\n", cid, table&0xf, table>>4);
+#endif
+  }
+  priv->stream = stream+3;
+  trace("< SOS marker\n");
+  return 0;
+}
+
+int tinyjpeg_parse_SOS(struct jdec_private *priv, const unsigned char *stream)
+{
+    return parse_SOS(priv, stream);
+}
+
+
+static int parse_DHT(struct jdec_private *priv, const unsigned char *stream)
+{
+  unsigned int count, i;
+  int length, index;
+  unsigned char Tc, Th;
+
+  length = be16_to_cpu(stream) - 2;
+  stream += 2;	/* Skip length */
+
+  trace("> DHT marker (length=%d)\n", length);
+
+  while (length>0) {
+     index = *stream++;
+
+     Tc = index & 0xf0; // it is not important to <<4
+     Th = index & 0x0f;
+     if (Tc) {
+        memcpy(priv->HTAC[index & 0xf].bits, stream, 16);
+     }
+     else {
+         memcpy(priv->HTDC[index & 0xf].bits, stream, 16);
+     }
+
+     count = 0;
+     for (i=0; i<16; i++) {
+        count += *stream++;
+     }
+
+#if SANITY_CHECK
+     if (count >= HUFFMAN_BITS_SIZE)
+       error("No more than %d bytes is allowed to describe a huffman table", HUFFMAN_BITS_SIZE);
+     if ( (index &0xf) >= HUFFMAN_TABLES)
+       error("No more than %d Huffman tables is supported (got %d)\n", HUFFMAN_TABLES, index&0xf);
+     trace("Huffman table %s[%d] length=%d\n", (index&0xf0)?"AC":"DC", index&0xf, count);
+#endif
+
+     if (Tc) {
+        memcpy(priv->HTAC[index & 0xf].values, stream, count);
+        priv->HTAC_valid[index & 0xf] = 1;
+     }
+     else {
+        memcpy(priv->HTDC[index & 0xf].values, stream, count);
+        priv->HTDC_valid[index & 0xf] = 1;
+     }
+
+     length -= 1;
+     length -= 16;
+     length -= count;
+     stream += count;
+  }
+  trace("< DHT marker\n");
+  return 0;
+}
+static int parse_DRI(struct jdec_private *priv, const unsigned char *stream)
+{
+  unsigned int length;
+
+  trace("> DRI marker\n");
+
+  length = be16_to_cpu(stream);
+
+#if SANITY_CHECK
+  if (length != 4)
+    error("Length of DRI marker need to be 4\n");
+#endif
+
+  priv->restart_interval = be16_to_cpu(stream+2);
+
+#if DEBUG
+  trace("Restart interval = %d\n", priv->restart_interval);
+#endif
+
+  trace("< DRI marker\n");
+
+  return 0;
+}
+
+static int findEOI(struct jdec_private *priv,const unsigned char *stream)
+{
+   while (!(*stream == 0xff  && *(stream+1) == 0xd9 )&& stream<=priv->stream_end) //searching for the end of image marker
+   {
+      stream++;
+      continue;
+   }
+  priv->stream_scan=stream;
+  return 0;
+}
+
+static int findSOI(struct jdec_private *priv,const unsigned char *stream)
+{
+   while (!(*stream == 0xff  && *(stream+1) == 0xd8 ) ) //searching for the start of image marker
+   {
+      if(stream<=priv->stream_end)
+        {
+           stream++;
+           continue;
+         }
+      else
+         return 0;  // No more images in the file.
+   }
+   priv->stream=stream+2;
+   return 1;
+}
+
+static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream)
+{
+  int chuck_len;
+  int marker;
+  int sos_marker_found = 0;
+  int dht_marker_found = 0;
+  int dqt_marker_found = 0;
+  const unsigned char *next_chunck;
+
+  next_image_found = findSOI(priv,stream);
+  stream=priv->stream;
+
+   while (!sos_marker_found  && stream<=priv->stream_end)
+   {
+     while((*stream == 0xff))
+        stream++;    
+            	    
+     marker = *stream++;
+     chuck_len = be16_to_cpu(stream);
+     next_chunck = stream + chuck_len;
+     switch (marker)
+      {
+       case SOF:
+	 if (parse_SOF(priv, stream) < 0)
+	   return -1;
+	 break;
+       case DQT:
+	 if (parse_DQT(priv, stream) < 0)
+	   return -1;
+	 dqt_marker_found = 1;
+	 break;
+       case SOS:
+	 if (parse_SOS(priv, stream) < 0)
+	   return -1;
+	 sos_marker_found = 1;
+	 break;
+       case DHT:
+	 if (parse_DHT(priv, stream) < 0)
+	   return -1;
+	 dht_marker_found = 1;
+	 break;
+       case DRI:
+	 if (parse_DRI(priv, stream) < 0)
+	   return -1;
+	 break;
+       default:
+	 trace("> Unknown marker %2.2x\n", marker);
+	 break;
+      }
+
+     stream = next_chunck;
+   }
+
+   if(next_image_found){
+      if (!dht_marker_found) {
+        trace("No Huffman table loaded, using the default one\n");
+        build_default_huffman_tables(priv);
+      }
+      if (!dqt_marker_found) {
+        error("ERROR:No Quantization table loaded, using the default one\n");
+      }
+   } 
+#ifdef SANITY_CHECK
+  if (   (priv->component_infos[cY].Hfactor < priv->component_infos[cCb].Hfactor)
+      || (priv->component_infos[cY].Hfactor < priv->component_infos[cCr].Hfactor))
+    error("Horizontal sampling factor for Y should be greater than horitontal sampling factor for Cb or Cr\n");
+  if (   (priv->component_infos[cY].Vfactor < priv->component_infos[cCb].Vfactor)
+      || (priv->component_infos[cY].Vfactor < priv->component_infos[cCr].Vfactor))
+    error("Vertical sampling factor for Y should be greater than vertical sampling factor for Cb or Cr\n");
+  if (   (priv->component_infos[cCb].Hfactor!=1) 
+      || (priv->component_infos[cCr].Hfactor!=1)
+      || (priv->component_infos[cCb].Vfactor!=1)
+      || (priv->component_infos[cCr].Vfactor!=1))
+    printf("ERROR:Sampling other than 1x1 for Cr and Cb is not supported");
+#endif
+  findEOI(priv,stream);
+  return next_image_found;
+}
+
+/*******************************************************************************
+ *
+ * Functions exported of the library.
+ *
+ * Note: Some applications can access directly to internal pointer of the
+ * structure. It's is not recommended, but if you have many images to
+ * uncompress with the same parameters, some functions can be called to speedup
+ * the decoding.
+ *
+ ******************************************************************************/
+
+/**
+ * Allocate a new tinyjpeg decoder object.
+ *
+ * Before calling any other functions, an object need to be called.
+ */
+struct jdec_private *tinyjpeg_init(void)
+{
+  struct jdec_private *priv;
+ 
+  priv = (struct jdec_private *)calloc(1, sizeof(struct jdec_private));
+  if (priv == NULL)
+    return NULL;
+  return priv;
+}
+
+/**
+ * Free a tinyjpeg object.
+ *
+ * No others function can be called after this one.
+ */
+void tinyjpeg_free(struct jdec_private *priv)
+{
+  free(priv);
+}
+
+/**
+ * Initialize the tinyjpeg object and prepare the decoding of the stream.
+ *
+ * Check if the jpeg can be decoded with this jpeg decoder.
+ * Fill some table used for preprocessing.
+ */
+int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size)
+{
+  int ret;
+
+  /* Identify the file */
+  if ((buf[0] != 0xFF) || (buf[1] != SOI))
+    error("Not a JPG file ?\n");
+
+  priv->stream_begin = buf;
+  priv->stream_length = size;
+  priv->stream_end = priv->stream_begin + priv->stream_length;
+
+  priv->stream = priv->stream_begin;
+  ret = parse_JFIF(priv, priv->stream);
+  return ret;
+}
+
+
+int tinyjpeg_decode(struct jdec_private *priv)
+{
+#define CHECK_VASTATUS(va_status,func)                                  \
+    if (va_status != VA_STATUS_SUCCESS) {                                   \
+        fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
+        exit(1);                                                            \
+    }
+
+    VAEntrypoint entrypoints[5];
+    int num_entrypoints,vld_entrypoint;
+    VAConfigAttrib attrib;
+    VAConfigID config_id;
+    VASurfaceID surface_id;
+    VAContextID context_id;
+    VABufferID pic_param_buf,iqmatrix_buf,huffmantable_buf,slice_param_buf,slice_data_buf;
+    int major_ver, minor_ver;
+    VADisplay	va_dpy;
+    VAStatus va_status;
+    int max_h_factor, max_v_factor;
+    int putsurface=1;
+    unsigned int i, j;
+
+    int surface_type;
+    char *type;
+    int ChromaTypeIndex;
+
+    VASurfaceAttrib forcc;
+    forcc.type =VASurfaceAttribPixelFormat;
+    forcc.flags=VA_SURFACE_ATTRIB_SETTABLE;
+    forcc.value.type=VAGenericValueTypeInteger;
+     
+
+    va_dpy = va_open_display();
+    va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
+    assert(va_status == VA_STATUS_SUCCESS);
+    
+    va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileJPEGBaseline, entrypoints, 
+                             &num_entrypoints);
+    CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
+
+    for	(vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) {
+        if (entrypoints[vld_entrypoint] == VAEntrypointVLD)
+            break;
+    }
+    if (vld_entrypoint == num_entrypoints) {
+        /* not find VLD entry point */
+        assert(0);
+    }
+
+    /* Assuming finding VLD, find out the format for the render target */
+    attrib.type = VAConfigAttribRTFormat;
+    vaGetConfigAttributes(va_dpy, VAProfileJPEGBaseline, VAEntrypointVLD,
+                          &attrib, 1);
+    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) {
+        /* not find desired YUV420 RT format */
+        assert(0);
+    }
+    
+    va_status = vaCreateConfig(va_dpy, VAProfileJPEGBaseline, VAEntrypointVLD,
+                              &attrib, 1,&config_id);
+    CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
+
+    while (next_image_found){  
+       VAPictureParameterBufferJPEGBaseline pic_param;
+       memset(&pic_param, 0, sizeof(pic_param));
+       pic_param.picture_width = priv->width[scan_num];
+       pic_param.picture_height = priv->height[scan_num];
+       pic_param.num_components = priv->nf_components;
+
+
+       for (i=0; i<pic_param.num_components; i++) { // tinyjpeg support 3 components only, does it match va?
+           pic_param.components[i].component_id = priv->component_infos[i].cid;
+           pic_param.components[i].h_sampling_factor = priv->component_infos[i].Hfactor;
+           pic_param.components[i].v_sampling_factor = priv->component_infos[i].Vfactor;
+           pic_param.components[i].quantiser_table_selector = priv->component_infos[i].quant_table_index;
+       }
+       int h1, h2, h3, v1, v2, v3;
+       h1 = pic_param.components[0].h_sampling_factor;
+       h2 = pic_param.components[1].h_sampling_factor;
+       h3 = pic_param.components[2].h_sampling_factor;
+       v1 = pic_param.components[0].v_sampling_factor;
+       v2 = pic_param.components[1].v_sampling_factor;
+       v3 = pic_param.components[2].v_sampling_factor;
+
+       if (h1 == 2 && h2 == 1 && h3 == 1 &&
+               v1 == 2 && v2 == 1 && v3 == 1) {
+           //surface_type = VA_RT_FORMAT_IMC3;
+           surface_type = VA_RT_FORMAT_YUV420;
+           forcc.value.value.i = VA_FOURCC_IMC3;
+           ChromaTypeIndex = 1;
+           type = "VA_FOURCC_IMC3";
+       }
+       else if (h1 == 2 && h2 == 1 && h3 == 1 &&
+               v1 == 1 && v2 == 1 && v3 == 1) {
+           //surface_type = VA_RT_FORMAT_YUV422H;
+           surface_type = VA_RT_FORMAT_YUV422;
+           forcc.value.value.i = VA_FOURCC_422H;
+           ChromaTypeIndex = 2;
+           type = "VA_FOURCC_422H";
+       }
+       else if (h1 == 1 && h2 == 1 && h3 == 1 &&
+               v1 == 1 && v2 == 1 && v3 == 1) {
+           surface_type = VA_RT_FORMAT_YUV444;
+           forcc.value.value.i = VA_FOURCC_444P;
+           //forcc.value.value.i = VA_FOURCC_RGBP;
+           ChromaTypeIndex = 3;
+           type = "VA_FOURCC_444P";
+       }
+       else if (h1 == 4 && h2 == 1 && h3 == 1 &&
+               v1 == 1 && v2 == 1 && v3 == 1) {
+           surface_type = VA_RT_FORMAT_YUV411;
+           forcc.value.value.i = VA_FOURCC_411P;
+           ChromaTypeIndex = 4;
+           type = "VA_FOURCC_411P";
+       }
+       else if (h1 == 1 && h2 == 1 && h3 == 1 &&
+               v1 == 2 && v2 == 1 && v3 == 1) {
+           //surface_type = VA_RT_FORMAT_YUV422V;
+           surface_type = VA_RT_FORMAT_YUV422;
+           forcc.value.value.i = VA_FOURCC_422V;
+           ChromaTypeIndex = 5;
+           type = "VA_FOURCC_422V";
+       }
+       else if (h1 == 2 && h2 == 1 && h3 == 1 &&
+               v1 == 2 && v2 == 2 && v3 == 2) {
+           //surface_type = VA_RT_FORMAT_YUV422H;
+           surface_type = VA_RT_FORMAT_YUV422;
+           forcc.value.value.i = VA_FOURCC_422H;
+           ChromaTypeIndex = 6;
+           type = "VA_FOURCC_422H";
+       }
+       else if (h2 == 2 && h2 == 2 && h3 == 2 &&
+               v1 == 2 && v2 == 1 && v3 == 1) {
+           //surface_type = VA_RT_FORMAT_YUV422V;
+           surface_type = VA_RT_FORMAT_YUV422;
+           forcc.value.value.i = VA_FOURCC_422V;
+           ChromaTypeIndex = 7;
+           type = "VA_FOURCC_422V";
+       }
+       else
+       {
+           surface_type = VA_RT_FORMAT_YUV400;
+           forcc.value.value.i = VA_FOURCC('Y','8','0','0');
+           ChromaTypeIndex = 0;
+           type = "Format_400P";
+       }
+
+       va_status = vaCreateSurfaces(va_dpy,surface_type,
+                                    priv->width[scan_num],priv->height[scan_num], //alignment?
+                                    &surface_id, 1, &forcc, 1);
+       CHECK_VASTATUS(va_status, "vaCreateSurfaces");
+  
+       /* Create a context for this decode pipe */
+       va_status = vaCreateContext(va_dpy, config_id,
+                                  priv->width[scan_num], priv->height[scan_num], // alignment?
+                                  VA_PROGRESSIVE,
+                                  &surface_id,
+                                  1,
+                                  &context_id);
+       CHECK_VASTATUS(va_status, "vaCreateContext");
+
+       va_status = vaCreateBuffer(va_dpy, context_id,
+                                 VAPictureParameterBufferType, // VAPictureParameterBufferJPEGBaseline?
+                                 sizeof(VAPictureParameterBufferJPEGBaseline),
+                                 1, &pic_param,
+                                 &pic_param_buf);
+       CHECK_VASTATUS(va_status, "vaCreateBuffer");
+
+       VAIQMatrixBufferJPEGBaseline iq_matrix;
+       const unsigned int num_quant_tables =
+           MIN(COMPONENTS, ARRAY_ELEMS(iq_matrix.load_quantiser_table));
+       // todo, only mask it if non-default quant matrix is used. do we need build default quant matrix?
+       memset(&iq_matrix, 0, sizeof(VAIQMatrixBufferJPEGBaseline));
+       for (i = 0; i < num_quant_tables; i++) {
+           if (!priv->Q_tables_valid[i])
+               continue;
+           iq_matrix.load_quantiser_table[i] = 1;
+           for (j = 0; j < 64; j++)
+               iq_matrix.quantiser_table[i][j] = priv->Q_tables[i][j];
+       }
+       va_status = vaCreateBuffer(va_dpy, context_id,
+                                 VAIQMatrixBufferType, // VAIQMatrixBufferJPEGBaseline?
+                                 sizeof(VAIQMatrixBufferJPEGBaseline),
+                                 1, &iq_matrix,
+                                 &iqmatrix_buf );
+       CHECK_VASTATUS(va_status, "vaCreateBuffer");
+
+       VAHuffmanTableBufferJPEGBaseline huffman_table;
+       const unsigned int num_huffman_tables =
+           MIN(COMPONENTS, ARRAY_ELEMS(huffman_table.load_huffman_table));
+       memset(&huffman_table, 0, sizeof(VAHuffmanTableBufferJPEGBaseline));
+       assert(sizeof(huffman_table.huffman_table[0].num_dc_codes) ==
+           sizeof(priv->HTDC[0].bits));
+          assert(sizeof(huffman_table.huffman_table[0].dc_values[0]) ==
+           sizeof(priv->HTDC[0].values[0]));
+       for (i = 0; i < num_huffman_tables; i++) {
+           if (!priv->HTDC_valid[i] || !priv->HTAC_valid[i])
+               continue;
+           huffman_table.load_huffman_table[i] = 1;
+           memcpy(huffman_table.huffman_table[i].num_dc_codes, priv->HTDC[i].bits,
+                  sizeof(huffman_table.huffman_table[i].num_dc_codes));
+           memcpy(huffman_table.huffman_table[i].dc_values, priv->HTDC[i].values,
+                  sizeof(huffman_table.huffman_table[i].dc_values));
+           memcpy(huffman_table.huffman_table[i].num_ac_codes, priv->HTAC[i].bits,
+                  sizeof(huffman_table.huffman_table[i].num_ac_codes));   
+           memcpy(huffman_table.huffman_table[i].ac_values, priv->HTAC[i].values,
+                  sizeof(huffman_table.huffman_table[i].ac_values));
+           memset(huffman_table.huffman_table[i].pad, 0,
+                  sizeof(huffman_table.huffman_table[i].pad));
+       }
+       va_status = vaCreateBuffer(va_dpy, context_id,
+                                 VAHuffmanTableBufferType, // VAHuffmanTableBufferJPEGBaseline?
+                                 sizeof(VAHuffmanTableBufferJPEGBaseline),
+                                 1, &huffman_table,
+                                 &huffmantable_buf );
+       CHECK_VASTATUS(va_status, "vaCreateBuffer");
+    
+       // one slice for whole image?
+       max_h_factor = priv->component_infos[0].Hfactor;
+       max_v_factor = priv->component_infos[0].Vfactor;
+       static VASliceParameterBufferJPEGBaseline slice_param;
+       slice_param.slice_data_size = (priv->stream_scan - priv->stream);
+       slice_param.slice_data_offset = 0;
+       slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
+       slice_param.slice_horizontal_position = 0;    
+       slice_param.slice_vertical_position = 0;    
+       slice_param.num_components = priv->cur_sos.nr_components;
+       for (i = 0; i < slice_param.num_components; i++) {
+           slice_param.components[i].component_selector = priv->cur_sos.components[i].component_id; /* FIXME: set to values specified in SOS  */
+           slice_param.components[i].dc_table_selector = priv->cur_sos.components[i].dc_selector;  /* FIXME: set to values specified in SOS  */
+           slice_param.components[i].ac_table_selector = priv->cur_sos.components[i].ac_selector;  /* FIXME: set to values specified in SOS  */
+       }
+       slice_param.restart_interval = priv->restart_interval;
+       slice_param.num_mcus = ((priv->width[scan_num]+max_h_factor*8-1)/(max_h_factor*8))*
+                             ((priv->height[scan_num]+max_v_factor*8-1)/(max_v_factor*8)); // ?? 720/16? 
+ 
+       va_status = vaCreateBuffer(va_dpy, context_id,
+                                 VASliceParameterBufferType, // VASliceParameterBufferJPEGBaseline?
+                                 sizeof(VASliceParameterBufferJPEGBaseline),
+                                 1,
+                                 &slice_param, &slice_param_buf);
+       CHECK_VASTATUS(va_status, "vaCreateBuffer");
+
+       va_status = vaCreateBuffer(va_dpy, context_id,
+                                 VASliceDataBufferType,
+                                 priv->stream_scan - priv->stream,
+                                 1,
+                                 (void*)priv->stream, // jpeg_clip,
+                                 &slice_data_buf);
+       CHECK_VASTATUS(va_status, "vaCreateBuffer");
+
+       va_status = vaBeginPicture(va_dpy, context_id, surface_id);
+       CHECK_VASTATUS(va_status, "vaBeginPicture");   
+
+       va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1);
+       CHECK_VASTATUS(va_status, "vaRenderPicture");
+   
+       va_status = vaRenderPicture(va_dpy,context_id, &iqmatrix_buf, 1);
+       CHECK_VASTATUS(va_status, "vaRenderPicture");
+
+       va_status = vaRenderPicture(va_dpy,context_id, &huffmantable_buf, 1);
+       CHECK_VASTATUS(va_status, "vaRenderPicture");
+   
+       va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1);
+       CHECK_VASTATUS(va_status, "vaRenderPicture");
+    
+       va_status = vaRenderPicture(va_dpy,context_id, &slice_data_buf, 1);
+       CHECK_VASTATUS(va_status, "vaRenderPicture");
+    
+       va_status = vaEndPicture(va_dpy,context_id);
+       CHECK_VASTATUS(va_status, "vaEndPicture");
+
+       va_status = vaSyncSurface(va_dpy, surface_id);
+       CHECK_VASTATUS(va_status, "vaSyncSurface");
+
+       if (putsurface) {
+           VARectangle src_rect, dst_rect;
+
+           src_rect.x      = 0;
+           src_rect.y      = 0;
+           src_rect.width  = priv->width[scan_num];
+           src_rect.height = priv->height[scan_num];
+           dst_rect        = src_rect;
+
+           va_status = va_put_surface(va_dpy, surface_id, &src_rect, &dst_rect);
+           CHECK_VASTATUS(va_status, "vaPutSurface");
+       }
+       scan_num++;
+
+       vaDestroySurfaces(va_dpy,&surface_id,1);
+       vaDestroyConfig(va_dpy,config_id);
+       vaDestroyContext(va_dpy,context_id);
+    
+       parse_JFIF(priv,priv->stream);
+       if(priv->width[scan_num] == 0 && priv->height[scan_num] == 0)
+          break;
+    }
+   // va_close_display(va_dpy);
+    vaTerminate(va_dpy);
+    printf("press any key to exit23\n");
+    getchar();
+    return 0;
+}
+const char *tinyjpeg_get_errorstring(struct jdec_private *priv)
+{
+  /* FIXME: the error string must be store in the context */
+  priv = priv;
+  return error_string;
+}
+void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height)
+{
+  *width = priv->width[scan_num];
+  *height = priv->height[scan_num];
+}
+
+
diff --git a/test/decode/tinyjpeg.h b/test/decode/tinyjpeg.h
new file mode 100644
index 0000000..5a76e41
--- /dev/null
+++ b/test/decode/tinyjpeg.h
@@ -0,0 +1,71 @@
+/*
+ * Small jpeg decoder library (header file)
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * Copyright (c) 2012 Intel Corporation.
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#ifndef __JPEGDEC_H__
+#define __JPEGDEC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct jdec_private;
+
+/* Flags that can be set by any applications */
+#define TINYJPEG_FLAGS_MJPEG_TABLE	(1<<1)
+
+/* Format accepted in outout */
+enum tinyjpeg_fmt {
+   TINYJPEG_FMT_GREY = 1,
+   TINYJPEG_FMT_BGR24,
+   TINYJPEG_FMT_RGB24,
+   TINYJPEG_FMT_YUV420P,
+};
+
+struct jdec_private *tinyjpeg_init(void);
+void tinyjpeg_free(struct jdec_private *priv);
+
+int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size);
+int tinyjpeg_decode(struct jdec_private *priv);
+const char *tinyjpeg_get_errorstring(struct jdec_private *priv);
+void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/test/encode/Android.mk b/test/encode/Android.mk
index 8395cdd..4cba3c3 100755
--- a/test/encode/Android.mk
+++ b/test/encode/Android.mk
@@ -6,21 +6,45 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-  h264encode_android.cpp	\
-  #h264encode_x11.c	\
+  ../common/va_display.c \
+  ../common/va_display_android.cpp \
+  h264encode.c
 
 LOCAL_CFLAGS += \
-    -DANDROID  
+    -DANDROID
 
 LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva	\
-  $(TOPDIR)/hardware/intel/libva/va/	\
-  $(TARGET_OUT_HEADERS)/X11	
+  $(LOCAL_PATH)/../../va \
+  $(LOCAL_PATH)/../common \
+  $(TARGET_OUT_HEADERS)/libva
 
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE :=	h264encode
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm  libcutils libutils libgui libm
+
+include $(BUILD_EXECUTABLE)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	../common/va_display.c			\
+	../common/va_display_android.cpp	\
+	avcenc.c
+
+LOCAL_CFLAGS += \
+    -DANDROID
+
+LOCAL_C_INCLUDES += \
+  $(LOCAL_PATH)/../../va \
+  $(LOCAL_PATH)/../common \
+  $(TARGET_OUT_HEADERS)/libva
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE :=	avcenc
+
+LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libgui
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/test/encode/Makefile.am b/test/encode/Makefile.am
index de42d31..5ddabd1 100644
--- a/test/encode/Makefile.am
+++ b/test/encode/Makefile.am
@@ -20,19 +20,34 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-bin_PROGRAMS = h264encode avcenc
+bin_PROGRAMS = avcenc mpeg2vaenc h264encode
 
-INCLUDES = -I$(top_srcdir)
+INCLUDES = \
+       -Wall                           \
+       -I$(top_srcdir)                 \
+       -I$(top_srcdir)/va              \
+       $(NULL)
 
-TEST_LIBS = $(top_builddir)/va/$(libvabackendlib) $(top_builddir)/va/$(libvacorelib) -lpthread -lX11
+h264encode_SOURCES	= h264encode.c
+h264encode_CFLAGS	= -I$(top_srcdir)/test/common -g
+h264encode_LDADD	= \
+	$(top_builddir)/va/libva.la \
+	$(top_builddir)/test/common/libva-display.la \
+	-lpthread -lm
 
-h264encode_LDADD = $(TEST_LIBS)
-h264encode_SOURCES = h264encode_x11.c
+avcenc_SOURCES		= avcenc.c
+avcenc_CFLAGS		= -I$(top_srcdir)/test/common -g
+avcenc_LDADD		= \
+	$(top_builddir)/va/libva.la \
+	$(top_builddir)/test/common/libva-display.la \
+	-lpthread
 
-avcenc_LDADD= $(TEST_LIBS)
-avcenc_SOURCES= avcenc.c
-
-EXTRA_DIST = h264encode_common.c
+mpeg2vaenc_SOURCES	= mpeg2vaenc.c
+mpeg2vaenc_CFLAGS	= -I$(top_srcdir)/test/common
+mpeg2vaenc_LDADD	= \
+	$(top_builddir)/va/libva.la \
+	$(top_builddir)/test/common/libva-display.la \
+	-lpthread
 
 valgrind:	$(bin_PROGRAMS)
 	for a in $(bin_PROGRAMS); do \
diff --git a/test/encode/avcenc.c b/test/encode/avcenc.c
index 71c0644..b734300 100644
--- a/test/encode/avcenc.c
+++ b/test/encode/avcenc.c
@@ -1,16 +1,38 @@
 /*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
  * Simple AVC encoder based on libVA.
  *
  * Usage:
  * ./avcenc <width> <height> <input file> <output file> [qp]
  */  
 
+#include "sysdeps.h"
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <getopt.h>
-#include <X11/Xlib.h>
-
 #include <unistd.h>
 
 #include <sys/time.h>
@@ -24,7 +46,7 @@
 
 #include <va/va.h>
 #include <va/va_enc_h264.h>
-#include <va/va_x11.h>
+#include "va_display.h"
 
 #define NAL_REF_IDC_NONE        0
 #define NAL_REF_IDC_LOW         1
@@ -35,6 +57,7 @@
 #define NAL_IDR                 5
 #define NAL_SPS                 7
 #define NAL_PPS                 8
+#define NAL_SEI			6
 
 #define SLICE_TYPE_P            0
 #define SLICE_TYPE_B            1
@@ -53,7 +76,6 @@
         exit(1);                                                        \
     }
 
-static Display *x11_display;
 static VADisplay va_dpy;
 
 static int picture_width, picture_width_in_mbs;
@@ -75,6 +97,16 @@
 static int
 build_packed_seq_buffer(unsigned char **header_buffer);
 
+static int 
+build_packed_sei_buffer_timing(unsigned int init_cpb_removal_length,
+				unsigned int init_cpb_removal_delay,
+				unsigned int init_cpb_removal_delay_offset,
+				unsigned int cpb_removal_length,
+				unsigned int cpb_removal_delay,
+				unsigned int dpb_output_length,
+				unsigned int dpb_output_delay,
+				unsigned char **sei_buffer);
+
 struct upload_thread_param
 {
     FILE *yuv_fp;
@@ -86,6 +118,7 @@
 
 static struct {
     VAProfile profile;
+    int constraint_set_flag;
     VAEncSequenceParameterBufferH264 seq_param;
     VAEncPictureParameterBufferH264 pic_param;
     VAEncSliceParameterBufferH264 slice_param[MAX_SLICES];
@@ -99,6 +132,8 @@
     VABufferID packed_seq_buf_id;
     VABufferID packed_pic_header_param_buf_id;
     VABufferID packed_pic_buf_id;
+    VABufferID packed_sei_header_param_buf_id;   /* the SEI buffer */
+    VABufferID packed_sei_buf_id;
     VABufferID misc_parameter_hrd_buf_id;
 
     int num_slices;
@@ -109,8 +144,15 @@
     struct upload_thread_param upload_thread_param;
     pthread_t upload_thread_id;
     int upload_thread_value;
+    int i_initial_cpb_removal_delay;
+    int i_initial_cpb_removal_delay_length;
+    int i_cpb_removal_delay;
+    int i_cpb_removal_delay_length;
+    int i_dpb_output_delay_length;
 } avcenc_context;
 
+static  VAPictureH264 ReferenceFrames[16], RefPicList0[32], RefPicList1[32];
+
 static void create_encode_pipe()
 {
     VAEntrypoint entrypoints[5];
@@ -119,10 +161,7 @@
     int major_ver, minor_ver;
     VAStatus va_status;
 
-    x11_display = XOpenDisplay(":0.0");
-    assert(x11_display);
-
-    va_dpy = vaGetDisplay(x11_display);
+    va_dpy = va_open_display();
     va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
     CHECK_VASTATUS(va_status, "vaInitialize");
 
@@ -177,7 +216,7 @@
     vaDestroyContext(va_dpy,avcenc_context.context_id);
     vaDestroyConfig(va_dpy,avcenc_context.config_id);
     vaTerminate(va_dpy);
-    XCloseDisplay(x11_display);
+    va_close_display(va_dpy);
 }
 
 /***************************************************
@@ -243,6 +282,45 @@
     vaDestroySurfaces(va_dpy, &surface_ids[0], SID_NUMBER);	
 }
 
+static void avcenc_update_sei_param(int frame_num)
+{
+	VAEncPackedHeaderParameterBuffer packed_header_param_buffer;
+	unsigned int length_in_bits, offset_in_bytes;
+	unsigned char *packed_sei_buffer = NULL;
+	VAStatus va_status;
+
+	length_in_bits = build_packed_sei_buffer_timing(
+				avcenc_context.i_initial_cpb_removal_delay_length,
+				avcenc_context.i_initial_cpb_removal_delay,
+				0,
+				avcenc_context.i_cpb_removal_delay_length,
+				avcenc_context.i_cpb_removal_delay * frame_num,
+				avcenc_context.i_dpb_output_delay_length,
+				0,
+				&packed_sei_buffer);
+
+	offset_in_bytes = 0;
+	packed_header_param_buffer.type = VAEncPackedHeaderH264_SEI;
+	packed_header_param_buffer.bit_length = length_in_bits;
+	packed_header_param_buffer.has_emulation_bytes = 0;
+
+	va_status = vaCreateBuffer(va_dpy,
+				avcenc_context.context_id,
+				VAEncPackedHeaderParameterBufferType,
+				sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer,
+				&avcenc_context.packed_sei_header_param_buf_id);
+	CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+	va_status = vaCreateBuffer(va_dpy,
+				avcenc_context.context_id,
+				VAEncPackedHeaderDataBufferType,
+				(length_in_bits + 7) / 8, 1, packed_sei_buffer,
+				&avcenc_context.packed_sei_buf_id);
+	CHECK_VASTATUS(va_status,"vaCreateBuffer");
+	free(packed_sei_buffer);
+	return;
+}
+
 static void avcenc_update_picture_parameter(int slice_type, int frame_num, int display_num, int is_idr)
 {
     VAEncPictureParameterBufferH264 *pic_param;
@@ -367,6 +445,23 @@
     slice_param->idr_pic_id = 0;
 
     /* FIXME: fill other fields */
+    if ((slice_type == SLICE_TYPE_P) || (slice_type == SLICE_TYPE_B)) {
+	int j;
+	slice_param->RefPicList0[0].picture_id = surface_ids[SID_REFERENCE_PICTURE_L0];
+	for (j = 1; j < 32; j++) {
+	    slice_param->RefPicList0[j].picture_id = VA_INVALID_SURFACE;
+	    slice_param->RefPicList0[j].flags = VA_PICTURE_H264_INVALID;
+	}
+    }
+
+    if ((slice_type == SLICE_TYPE_B)) {
+	int j;
+	slice_param->RefPicList1[0].picture_id = surface_ids[SID_REFERENCE_PICTURE_L1];
+	for (j = 1; j < 32; j++) {
+	    slice_param->RefPicList1[j].picture_id = VA_INVALID_SURFACE;
+	    slice_param->RefPicList1[j].flags = VA_PICTURE_H264_INVALID;
+	}
+    }
 
     va_status = vaCreateBuffer(va_dpy,
                                avcenc_context.context_id,
@@ -520,7 +615,7 @@
 int avcenc_render_picture()
 {
     VAStatus va_status;
-    VABufferID va_buffers[8];
+    VABufferID va_buffers[10];
     unsigned int num_va_buffers = 0;
     int i;
 
@@ -539,6 +634,12 @@
     if (avcenc_context.packed_pic_buf_id != VA_INVALID_ID)
         va_buffers[num_va_buffers++] = avcenc_context.packed_pic_buf_id;
 
+    if (avcenc_context.packed_sei_header_param_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = avcenc_context.packed_sei_header_param_buf_id;
+
+    if (avcenc_context.packed_sei_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = avcenc_context.packed_sei_buf_id;
+
     if (avcenc_context.misc_parameter_hrd_buf_id != VA_INVALID_ID)
         va_buffers[num_va_buffers++] =  avcenc_context.misc_parameter_hrd_buf_id;
 
@@ -612,6 +713,8 @@
     avcenc_destroy_buffers(&avcenc_context.packed_seq_buf_id, 1);
     avcenc_destroy_buffers(&avcenc_context.packed_pic_header_param_buf_id, 1);
     avcenc_destroy_buffers(&avcenc_context.packed_pic_buf_id, 1);
+    avcenc_destroy_buffers(&avcenc_context.packed_sei_header_param_buf_id, 1);
+    avcenc_destroy_buffers(&avcenc_context.packed_sei_buf_id, 1);
     avcenc_destroy_buffers(&avcenc_context.slice_param_buf_id[0], avcenc_context.num_slices);
     avcenc_destroy_buffers(&avcenc_context.codedbuf_buf_id, 1);
     avcenc_destroy_buffers(&avcenc_context.misc_parameter_hrd_buf_id, 1);
@@ -649,7 +752,7 @@
 #endif
 
 static unsigned int 
-swap32(unsigned int val)
+va_swap32(unsigned int val)
 {
     unsigned char *pval = (unsigned char *)&val;
 
@@ -675,7 +778,7 @@
     int bit_left = 32 - bit_offset;
 
     if (bit_offset) {
-        bs->buffer[pos] = swap32((bs->buffer[pos] << bit_left));
+        bs->buffer[pos] = va_swap32((bs->buffer[pos] << bit_left));
     }
 }
  
@@ -696,7 +799,7 @@
     } else {
         size_in_bits -= bit_left;
         bs->buffer[pos] = (bs->buffer[pos] << bit_left) | (val >> size_in_bits);
-        bs->buffer[pos] = swap32(bs->buffer[pos]);
+        bs->buffer[pos] = va_swap32(bs->buffer[pos]);
 
         if (pos + 1 == bs->max_size_in_dword) {
             bs->max_size_in_dword += BITSTREAM_ALLOCATE_STEPPING;
@@ -785,10 +888,10 @@
         profile_idc = PROFILE_IDC_MAIN;
 
     bitstream_put_ui(bs, profile_idc, 8);               /* profile_idc */
-    bitstream_put_ui(bs, 0, 1);                         /* constraint_set0_flag */
-    bitstream_put_ui(bs, 1, 1);                         /* constraint_set1_flag */
-    bitstream_put_ui(bs, 0, 1);                         /* constraint_set2_flag */
-    bitstream_put_ui(bs, 0, 1);                         /* constraint_set3_flag */
+    bitstream_put_ui(bs, !!(avcenc_context.constraint_set_flag & 1), 1);                         /* constraint_set0_flag */
+    bitstream_put_ui(bs, !!(avcenc_context.constraint_set_flag & 2), 1);                         /* constraint_set1_flag */
+    bitstream_put_ui(bs, !!(avcenc_context.constraint_set_flag & 4), 1);                         /* constraint_set2_flag */
+    bitstream_put_ui(bs, !!(avcenc_context.constraint_set_flag & 8), 1);                         /* constraint_set3_flag */
     bitstream_put_ui(bs, 0, 4);                         /* reserved_zero_4bits */
     bitstream_put_ui(bs, seq_param->level_idc, 8);      /* level_idc */
     bitstream_put_ue(bs, seq_param->seq_parameter_set_id);      /* seq_parameter_set_id */
@@ -969,6 +1072,71 @@
     return bs.bit_offset;
 }
 
+static int 
+build_packed_sei_buffer_timing(unsigned int init_cpb_removal_length,
+				unsigned int init_cpb_removal_delay,
+				unsigned int init_cpb_removal_delay_offset,
+				unsigned int cpb_removal_length,
+				unsigned int cpb_removal_delay,
+				unsigned int dpb_output_length,
+				unsigned int dpb_output_delay,
+				unsigned char **sei_buffer)
+{
+    unsigned char *byte_buf;
+    int bp_byte_size, i, pic_byte_size;
+
+    bitstream nal_bs;
+    bitstream sei_bp_bs, sei_pic_bs;
+
+    bitstream_start(&sei_bp_bs);
+    bitstream_put_ue(&sei_bp_bs, 0);       /*seq_parameter_set_id*/
+    bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay, cpb_removal_length); 
+    bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay_offset, cpb_removal_length); 
+    if ( sei_bp_bs.bit_offset & 0x7) {
+        bitstream_put_ui(&sei_bp_bs, 1, 1);
+    }
+    bitstream_end(&sei_bp_bs);
+    bp_byte_size = (sei_bp_bs.bit_offset + 7) / 8;
+    
+    bitstream_start(&sei_pic_bs);
+    bitstream_put_ui(&sei_pic_bs, cpb_removal_delay, cpb_removal_length); 
+    bitstream_put_ui(&sei_pic_bs, dpb_output_delay, dpb_output_length); 
+    if ( sei_pic_bs.bit_offset & 0x7) {
+        bitstream_put_ui(&sei_pic_bs, 1, 1);
+    }
+    bitstream_end(&sei_pic_bs);
+    pic_byte_size = (sei_pic_bs.bit_offset + 7) / 8;
+    
+    bitstream_start(&nal_bs);
+    nal_start_code_prefix(&nal_bs);
+    nal_header(&nal_bs, NAL_REF_IDC_NONE, NAL_SEI);
+
+	/* Write the SEI buffer period data */    
+    bitstream_put_ui(&nal_bs, 0, 8);
+    bitstream_put_ui(&nal_bs, bp_byte_size, 8);
+    
+    byte_buf = (unsigned char *)sei_bp_bs.buffer;
+    for(i = 0; i < bp_byte_size; i++) {
+        bitstream_put_ui(&nal_bs, byte_buf[i], 8);
+    }
+    free(byte_buf);
+	/* write the SEI timing data */
+    bitstream_put_ui(&nal_bs, 0x01, 8);
+    bitstream_put_ui(&nal_bs, pic_byte_size, 8);
+    
+    byte_buf = (unsigned char *)sei_pic_bs.buffer;
+    for(i = 0; i < pic_byte_size; i++) {
+        bitstream_put_ui(&nal_bs, byte_buf[i], 8);
+    }
+    free(byte_buf);
+
+    rbsp_trailing_bits(&nal_bs);
+    bitstream_end(&nal_bs);
+
+    *sei_buffer = (unsigned char *)nal_bs.buffer; 
+   
+    return nal_bs.bit_offset;
+}
 
 #if 0
 static void 
@@ -1160,7 +1328,7 @@
             index = SID_INPUT_PICTURE_0;
         if ( next_display_num >= frame_number )
             next_display_num = frame_number - 1;
-        fseek(yuv_fp, frame_size * next_display_num, SEEK_SET);
+        fseeko(yuv_fp, (off_t)frame_size * next_display_num, SEEK_SET);
 
         avcenc_context.upload_thread_param.yuv_fp = yuv_fp;
         avcenc_context.upload_thread_param.surface_id = surface_ids[index];
@@ -1193,6 +1361,9 @@
         /* picture parameter set */
         avcenc_update_picture_parameter(slice_type, frame_num, display_num, is_idr);
 
+	if (avcenc_context.rate_control_method == VA_RC_CBR)
+		avcenc_update_sei_param(frame_num);
+
         avcenc_render_picture();
 
         ret = store_coded_buffer(avc_fp, slice_type);
@@ -1294,15 +1465,54 @@
     pic_param->pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_CABAC;
     pic_param->pic_fields.bits.weighted_pred_flag = 0;
     pic_param->pic_fields.bits.weighted_bipred_idc = 0;
-    pic_param->pic_fields.bits.transform_8x8_mode_flag = 1;
+    
+    if (avcenc_context.constraint_set_flag & 0x7)
+        pic_param->pic_fields.bits.transform_8x8_mode_flag = 0;
+    else
+        pic_param->pic_fields.bits.transform_8x8_mode_flag = 1;
+
     pic_param->pic_fields.bits.deblocking_filter_control_present_flag = 1;
 }
 
+static void avcenc_context_sei_init()
+{
+	int init_cpb_size;
+	int target_bit_rate;
+
+	/* it comes for the bps defined in SPS */
+	target_bit_rate = avcenc_context.seq_param.bits_per_second;
+	init_cpb_size = (target_bit_rate * 8) >> 10;
+	avcenc_context.i_initial_cpb_removal_delay = init_cpb_size * 0.5 * 1024 / target_bit_rate * 90000;
+
+	avcenc_context.i_cpb_removal_delay = 2;
+	avcenc_context.i_initial_cpb_removal_delay_length = 24;
+	avcenc_context.i_cpb_removal_delay_length = 24;
+	avcenc_context.i_dpb_output_delay_length = 24;
+}
+
 static void avcenc_context_init(int width, int height)
 {
     int i;
     memset(&avcenc_context, 0, sizeof(avcenc_context));
     avcenc_context.profile = VAProfileH264Main;
+
+    switch (avcenc_context.profile) {
+    case VAProfileH264Baseline:
+        avcenc_context.constraint_set_flag |= (1 << 0); /* Annex A.2.1 */
+        break;
+
+    case VAProfileH264Main:
+        avcenc_context.constraint_set_flag |= (1 << 1); /* Annex A.2.2 */
+        break;
+
+    case VAProfileH264High:
+        avcenc_context.constraint_set_flag |= (1 << 3); /* Annex A.2.4 */
+        break;
+        
+    default:
+        break;
+    }
+        
     avcenc_context.seq_param_buf_id = VA_INVALID_ID;
     avcenc_context.pic_param_buf_id = VA_INVALID_ID;
     avcenc_context.packed_seq_header_param_buf_id = VA_INVALID_ID;
@@ -1315,6 +1525,8 @@
     avcenc_context.codedbuf_pb_size = 0;
     avcenc_context.current_input_surface = SID_INPUT_PICTURE_0;
     avcenc_context.upload_thread_value = -1;
+    avcenc_context.packed_sei_header_param_buf_id = VA_INVALID_ID;
+    avcenc_context.packed_sei_buf_id = VA_INVALID_ID;
 
     if (qp_value == -1)
         avcenc_context.rate_control_method = VA_RC_CBR;
@@ -1331,6 +1543,8 @@
 
     avcenc_context_seq_param_init(&avcenc_context.seq_param, width, height);
     avcenc_context_pic_param_init(&avcenc_context.pic_param);
+    if (avcenc_context.rate_control_method == VA_RC_CBR)
+	avcenc_context_sei_init();
 }
 
 int main(int argc, char *argv[])
@@ -1338,11 +1552,14 @@
     int f;
     FILE *yuv_fp;
     FILE *avc_fp;
-    long file_size;
+    off_t file_size;
     int i_frame_only=0,i_p_frame_only=1;
     int mode_value;
     struct timeval tpstart,tpend; 
     float  timeuse;
+
+    va_init_display_args(&argc, argv);
+
     //TODO may be we should using option analytics library
     if(argc != 5 && argc != 6 && argc != 7) {
         show_help();
@@ -1398,8 +1615,8 @@
         printf("Can't open input YUV file\n");
         return -1;
     }
-    fseek(yuv_fp,0l, SEEK_END);
-    file_size = ftell(yuv_fp);
+    fseeko(yuv_fp, (off_t)0, SEEK_END);
+    file_size = ftello(yuv_fp);
     frame_size = picture_width * picture_height +  ((picture_width * picture_height) >> 1) ;
 
     if ( (file_size < frame_size) || (file_size % frame_size) ) {
@@ -1408,7 +1625,7 @@
         return -1;
     }
     frame_number = file_size / frame_size;
-    fseek(yuv_fp, 0l, SEEK_SET);
+    fseeko(yuv_fp, (off_t)0, SEEK_SET);
 
     avc_fp = fopen(argv[4], "wb");	
     if ( avc_fp == NULL) {
diff --git a/test/encode/h264encode.c b/test/encode/h264encode.c
new file mode 100644
index 0000000..7da2154
--- /dev/null
+++ b/test/encode/h264encode.c
@@ -0,0 +1,2201 @@
+/*
+ * Copyright (c) 2007-2013 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "sysdeps.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <pthread.h>
+#include <errno.h>
+#include <math.h>
+#include <va/va.h>
+#include <va/va_enc_h264.h>
+#include "va_display.h"
+
+#define CHECK_VASTATUS(va_status,func)                                  \
+    if (va_status != VA_STATUS_SUCCESS) {                               \
+        fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
+        exit(1);                                                        \
+    }
+
+#include "../loadsurface.h"
+
+#define NAL_REF_IDC_NONE        0
+#define NAL_REF_IDC_LOW         1
+#define NAL_REF_IDC_MEDIUM      2
+#define NAL_REF_IDC_HIGH        3
+
+#define NAL_NON_IDR             1
+#define NAL_IDR                 5
+#define NAL_SPS                 7
+#define NAL_PPS                 8
+#define NAL_SEI			6
+
+#define SLICE_TYPE_P            0
+#define SLICE_TYPE_B            1
+#define SLICE_TYPE_I            2
+
+#define ENTROPY_MODE_CAVLC      0
+#define ENTROPY_MODE_CABAC      1
+
+#define PROFILE_IDC_BASELINE    66
+#define PROFILE_IDC_MAIN        77
+#define PROFILE_IDC_HIGH        100
+   
+#define BITSTREAM_ALLOCATE_STEPPING     4096
+
+#define SURFACE_NUM 16 /* 16 surfaces for source YUV */
+#define SURFACE_NUM 16 /* 16 surfaces for reference */
+static  VADisplay va_dpy;
+static  VAProfile h264_profile = ~0;
+static  VAConfigAttrib attrib[VAConfigAttribTypeMax];
+static  VAConfigAttrib config_attrib[VAConfigAttribTypeMax];
+static  int config_attrib_num = 0;
+static  VASurfaceID src_surface[SURFACE_NUM];
+static  VABufferID  coded_buf[SURFACE_NUM];
+static  VASurfaceID ref_surface[SURFACE_NUM];
+static  VAConfigID config_id;
+static  VAContextID context_id;
+static  VAEncSequenceParameterBufferH264 seq_param;
+static  VAEncPictureParameterBufferH264 pic_param;
+static  VAEncSliceParameterBufferH264 slice_param;
+static  VAPictureH264 CurrentCurrPic;
+static  VAPictureH264 ReferenceFrames[16], RefPicList0_P[32], RefPicList0_B[32], RefPicList1_B[32];
+
+static  unsigned int MaxFrameNum = (2<<16);
+static  unsigned int MaxPicOrderCntLsb = (2<<8);
+static  unsigned int Log2MaxFrameNum = 16;
+static  unsigned int Log2MaxPicOrderCntLsb = 8;
+
+static  unsigned int num_ref_frames = 2;
+static  unsigned int numShortTerm = 0;
+static  int constraint_set_flag = 0;
+static  int h264_packedheader = 0; /* support pack header? */
+static  int h264_maxref = (1<<16|1);
+static  int h264_entropy_mode = 1; /* cabac */
+
+static  char *coded_fn = NULL, *srcyuv_fn = NULL, *recyuv_fn = NULL;
+static  FILE *coded_fp = NULL, *srcyuv_fp = NULL, *recyuv_fp = NULL;
+static  unsigned long long srcyuv_frames = 0;
+static  int srcyuv_fourcc = VA_FOURCC_NV12;
+static  int calc_psnr = 0;
+
+static  int frame_width = 176;
+static  int frame_height = 144;
+static  int frame_width_mbaligned;
+static  int frame_height_mbaligned;
+static  int frame_rate = 30;
+static  unsigned int frame_count = 60;
+static  unsigned int frame_coded = 0;
+static  unsigned int frame_bitrate = 0;
+static  unsigned int frame_slices = 1;
+static  double frame_size = 0;
+static  int initial_qp = 26;
+static  int minimal_qp = 0;
+static  int intra_period = 30;
+static  int intra_idr_period = 60;
+static  int ip_period = 1;
+static  int rc_mode = VA_RC_VBR;
+static  unsigned long long current_frame_encoding = 0;
+static  unsigned long long current_frame_display = 0;
+static  unsigned long long current_IDR_display = 0;
+static  unsigned int current_frame_num = 0;
+static  int current_frame_type;
+#define current_slot (current_frame_display % SURFACE_NUM)
+
+static  int misc_priv_type = 0;
+static  int misc_priv_value = 0;
+
+#define MIN(a, b) ((a)>(b)?(b):(a))
+#define MAX(a, b) ((a)>(b)?(a):(b))
+
+/* thread to save coded data/upload source YUV */
+struct storage_task_t {
+    void *next;
+    unsigned long long display_order;
+    unsigned long long encode_order;
+};
+static  struct storage_task_t *storage_task_header = NULL, *storage_task_tail = NULL;
+#define SRC_SURFACE_IN_ENCODING 0
+#define SRC_SURFACE_IN_STORAGE  1
+static  int srcsurface_status[SURFACE_NUM];
+static  int encode_syncmode = 0;
+static  pthread_mutex_t encode_mutex = PTHREAD_MUTEX_INITIALIZER;
+static  pthread_cond_t  encode_cond = PTHREAD_COND_INITIALIZER;
+static  pthread_t encode_thread;
+    
+/* for performance profiling */
+static unsigned int UploadPictureTicks=0;
+static unsigned int BeginPictureTicks=0;
+static unsigned int RenderPictureTicks=0;
+static unsigned int EndPictureTicks=0;
+static unsigned int SyncPictureTicks=0;
+static unsigned int SavePictureTicks=0;
+static unsigned int TotalTicks=0;
+
+struct __bitstream {
+    unsigned int *buffer;
+    int bit_offset;
+    int max_size_in_dword;
+};
+typedef struct __bitstream bitstream;
+
+
+static unsigned int 
+va_swap32(unsigned int val)
+{
+    unsigned char *pval = (unsigned char *)&val;
+
+    return ((pval[0] << 24)     |
+            (pval[1] << 16)     |
+            (pval[2] << 8)      |
+            (pval[3] << 0));
+}
+
+static void
+bitstream_start(bitstream *bs)
+{
+    bs->max_size_in_dword = BITSTREAM_ALLOCATE_STEPPING;
+    bs->buffer = calloc(bs->max_size_in_dword * sizeof(int), 1);
+    bs->bit_offset = 0;
+}
+
+static void
+bitstream_end(bitstream *bs)
+{
+    int pos = (bs->bit_offset >> 5);
+    int bit_offset = (bs->bit_offset & 0x1f);
+    int bit_left = 32 - bit_offset;
+
+    if (bit_offset) {
+        bs->buffer[pos] = va_swap32((bs->buffer[pos] << bit_left));
+    }
+}
+ 
+static void
+bitstream_put_ui(bitstream *bs, unsigned int val, int size_in_bits)
+{
+    int pos = (bs->bit_offset >> 5);
+    int bit_offset = (bs->bit_offset & 0x1f);
+    int bit_left = 32 - bit_offset;
+
+    if (!size_in_bits)
+        return;
+
+    bs->bit_offset += size_in_bits;
+
+    if (bit_left > size_in_bits) {
+        bs->buffer[pos] = (bs->buffer[pos] << size_in_bits | val);
+    } else {
+        size_in_bits -= bit_left;
+        bs->buffer[pos] = (bs->buffer[pos] << bit_left) | (val >> size_in_bits);
+        bs->buffer[pos] = va_swap32(bs->buffer[pos]);
+
+        if (pos + 1 == bs->max_size_in_dword) {
+            bs->max_size_in_dword += BITSTREAM_ALLOCATE_STEPPING;
+            bs->buffer = realloc(bs->buffer, bs->max_size_in_dword * sizeof(unsigned int));
+        }
+
+        bs->buffer[pos + 1] = val;
+    }
+}
+
+static void
+bitstream_put_ue(bitstream *bs, unsigned int val)
+{
+    int size_in_bits = 0;
+    int tmp_val = ++val;
+
+    while (tmp_val) {
+        tmp_val >>= 1;
+        size_in_bits++;
+    }
+
+    bitstream_put_ui(bs, 0, size_in_bits - 1); // leading zero
+    bitstream_put_ui(bs, val, size_in_bits);
+}
+
+static void
+bitstream_put_se(bitstream *bs, int val)
+{
+    unsigned int new_val;
+
+    if (val <= 0)
+        new_val = -2 * val;
+    else
+        new_val = 2 * val - 1;
+
+    bitstream_put_ue(bs, new_val);
+}
+
+static void
+bitstream_byte_aligning(bitstream *bs, int bit)
+{
+    int bit_offset = (bs->bit_offset & 0x7);
+    int bit_left = 8 - bit_offset;
+    int new_val;
+
+    if (!bit_offset)
+        return;
+
+    assert(bit == 0 || bit == 1);
+
+    if (bit)
+        new_val = (1 << bit_left) - 1;
+    else
+        new_val = 0;
+
+    bitstream_put_ui(bs, new_val, bit_left);
+}
+
+static void 
+rbsp_trailing_bits(bitstream *bs)
+{
+    bitstream_put_ui(bs, 1, 1);
+    bitstream_byte_aligning(bs, 0);
+}
+
+static void nal_start_code_prefix(bitstream *bs)
+{
+    bitstream_put_ui(bs, 0x00000001, 32);
+}
+
+static void nal_header(bitstream *bs, int nal_ref_idc, int nal_unit_type)
+{
+    bitstream_put_ui(bs, 0, 1);                /* forbidden_zero_bit: 0 */
+    bitstream_put_ui(bs, nal_ref_idc, 2);
+    bitstream_put_ui(bs, nal_unit_type, 5);
+}
+
+static void sps_rbsp(bitstream *bs)
+{
+    int profile_idc = PROFILE_IDC_BASELINE;
+
+    if (h264_profile  == VAProfileH264High)
+        profile_idc = PROFILE_IDC_HIGH;
+    else if (h264_profile  == VAProfileH264Main)
+        profile_idc = PROFILE_IDC_MAIN;
+
+    bitstream_put_ui(bs, profile_idc, 8);               /* profile_idc */
+    bitstream_put_ui(bs, !!(constraint_set_flag & 1), 1);                         /* constraint_set0_flag */
+    bitstream_put_ui(bs, !!(constraint_set_flag & 2), 1);                         /* constraint_set1_flag */
+    bitstream_put_ui(bs, !!(constraint_set_flag & 4), 1);                         /* constraint_set2_flag */
+    bitstream_put_ui(bs, !!(constraint_set_flag & 8), 1);                         /* constraint_set3_flag */
+    bitstream_put_ui(bs, 0, 4);                         /* reserved_zero_4bits */
+    bitstream_put_ui(bs, seq_param.level_idc, 8);      /* level_idc */
+    bitstream_put_ue(bs, seq_param.seq_parameter_set_id);      /* seq_parameter_set_id */
+
+    if ( profile_idc == PROFILE_IDC_HIGH) {
+        bitstream_put_ue(bs, 1);        /* chroma_format_idc = 1, 4:2:0 */ 
+        bitstream_put_ue(bs, 0);        /* bit_depth_luma_minus8 */
+        bitstream_put_ue(bs, 0);        /* bit_depth_chroma_minus8 */
+        bitstream_put_ui(bs, 0, 1);     /* qpprime_y_zero_transform_bypass_flag */
+        bitstream_put_ui(bs, 0, 1);     /* seq_scaling_matrix_present_flag */
+    }
+
+    bitstream_put_ue(bs, seq_param.seq_fields.bits.log2_max_frame_num_minus4); /* log2_max_frame_num_minus4 */
+    bitstream_put_ue(bs, seq_param.seq_fields.bits.pic_order_cnt_type);        /* pic_order_cnt_type */
+
+    if (seq_param.seq_fields.bits.pic_order_cnt_type == 0)
+        bitstream_put_ue(bs, seq_param.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);     /* log2_max_pic_order_cnt_lsb_minus4 */
+    else {
+        assert(0);
+    }
+
+    bitstream_put_ue(bs, seq_param.max_num_ref_frames);        /* num_ref_frames */
+    bitstream_put_ui(bs, 0, 1);                                 /* gaps_in_frame_num_value_allowed_flag */
+
+    bitstream_put_ue(bs, seq_param.picture_width_in_mbs - 1);  /* pic_width_in_mbs_minus1 */
+    bitstream_put_ue(bs, seq_param.picture_height_in_mbs - 1); /* pic_height_in_map_units_minus1 */
+    bitstream_put_ui(bs, seq_param.seq_fields.bits.frame_mbs_only_flag, 1);    /* frame_mbs_only_flag */
+
+    if (!seq_param.seq_fields.bits.frame_mbs_only_flag) {
+        assert(0);
+    }
+
+    bitstream_put_ui(bs, seq_param.seq_fields.bits.direct_8x8_inference_flag, 1);      /* direct_8x8_inference_flag */
+    bitstream_put_ui(bs, seq_param.frame_cropping_flag, 1);            /* frame_cropping_flag */
+
+    if (seq_param.frame_cropping_flag) {
+        bitstream_put_ue(bs, seq_param.frame_crop_left_offset);        /* frame_crop_left_offset */
+        bitstream_put_ue(bs, seq_param.frame_crop_right_offset);       /* frame_crop_right_offset */
+        bitstream_put_ue(bs, seq_param.frame_crop_top_offset);         /* frame_crop_top_offset */
+        bitstream_put_ue(bs, seq_param.frame_crop_bottom_offset);      /* frame_crop_bottom_offset */
+    }
+    
+    //if ( frame_bit_rate < 0 ) { //TODO EW: the vui header isn't correct
+    if ( 1 ) {
+        bitstream_put_ui(bs, 0, 1); /* vui_parameters_present_flag */
+    } else {
+        bitstream_put_ui(bs, 1, 1); /* vui_parameters_present_flag */
+        bitstream_put_ui(bs, 0, 1); /* aspect_ratio_info_present_flag */
+        bitstream_put_ui(bs, 0, 1); /* overscan_info_present_flag */
+        bitstream_put_ui(bs, 0, 1); /* video_signal_type_present_flag */
+        bitstream_put_ui(bs, 0, 1); /* chroma_loc_info_present_flag */
+        bitstream_put_ui(bs, 1, 1); /* timing_info_present_flag */
+        {
+            bitstream_put_ui(bs, 15, 32);
+            bitstream_put_ui(bs, 900, 32);
+            bitstream_put_ui(bs, 1, 1);
+        }
+        bitstream_put_ui(bs, 1, 1); /* nal_hrd_parameters_present_flag */
+        {
+            // hrd_parameters 
+            bitstream_put_ue(bs, 0);    /* cpb_cnt_minus1 */
+            bitstream_put_ui(bs, 4, 4); /* bit_rate_scale */
+            bitstream_put_ui(bs, 6, 4); /* cpb_size_scale */
+           
+            bitstream_put_ue(bs, frame_bitrate - 1); /* bit_rate_value_minus1[0] */
+            bitstream_put_ue(bs, frame_bitrate*8 - 1); /* cpb_size_value_minus1[0] */
+            bitstream_put_ui(bs, 1, 1);  /* cbr_flag[0] */
+
+            bitstream_put_ui(bs, 23, 5);   /* initial_cpb_removal_delay_length_minus1 */
+            bitstream_put_ui(bs, 23, 5);   /* cpb_removal_delay_length_minus1 */
+            bitstream_put_ui(bs, 23, 5);   /* dpb_output_delay_length_minus1 */
+            bitstream_put_ui(bs, 23, 5);   /* time_offset_length  */
+        }
+        bitstream_put_ui(bs, 0, 1);   /* vcl_hrd_parameters_present_flag */
+        bitstream_put_ui(bs, 0, 1);   /* low_delay_hrd_flag */ 
+
+        bitstream_put_ui(bs, 0, 1); /* pic_struct_present_flag */
+        bitstream_put_ui(bs, 0, 1); /* bitstream_restriction_flag */
+    }
+
+    rbsp_trailing_bits(bs);     /* rbsp_trailing_bits */
+}
+
+
+static void pps_rbsp(bitstream *bs)
+{
+    bitstream_put_ue(bs, pic_param.pic_parameter_set_id);      /* pic_parameter_set_id */
+    bitstream_put_ue(bs, pic_param.seq_parameter_set_id);      /* seq_parameter_set_id */
+
+    bitstream_put_ui(bs, pic_param.pic_fields.bits.entropy_coding_mode_flag, 1);  /* entropy_coding_mode_flag */
+
+    bitstream_put_ui(bs, 0, 1);                         /* pic_order_present_flag: 0 */
+
+    bitstream_put_ue(bs, 0);                            /* num_slice_groups_minus1 */
+
+    bitstream_put_ue(bs, pic_param.num_ref_idx_l0_active_minus1);      /* num_ref_idx_l0_active_minus1 */
+    bitstream_put_ue(bs, pic_param.num_ref_idx_l1_active_minus1);      /* num_ref_idx_l1_active_minus1 1 */
+
+    bitstream_put_ui(bs, pic_param.pic_fields.bits.weighted_pred_flag, 1);     /* weighted_pred_flag: 0 */
+    bitstream_put_ui(bs, pic_param.pic_fields.bits.weighted_bipred_idc, 2);	/* weighted_bipred_idc: 0 */
+
+    bitstream_put_se(bs, pic_param.pic_init_qp - 26);  /* pic_init_qp_minus26 */
+    bitstream_put_se(bs, 0);                            /* pic_init_qs_minus26 */
+    bitstream_put_se(bs, 0);                            /* chroma_qp_index_offset */
+
+    bitstream_put_ui(bs, pic_param.pic_fields.bits.deblocking_filter_control_present_flag, 1); /* deblocking_filter_control_present_flag */
+    bitstream_put_ui(bs, 0, 1);                         /* constrained_intra_pred_flag */
+    bitstream_put_ui(bs, 0, 1);                         /* redundant_pic_cnt_present_flag */
+    
+    /* more_rbsp_data */
+    bitstream_put_ui(bs, pic_param.pic_fields.bits.transform_8x8_mode_flag, 1);    /*transform_8x8_mode_flag */
+    bitstream_put_ui(bs, 0, 1);                         /* pic_scaling_matrix_present_flag */
+    bitstream_put_se(bs, pic_param.second_chroma_qp_index_offset );    /*second_chroma_qp_index_offset */
+
+    rbsp_trailing_bits(bs);
+}
+
+
+static int
+build_packed_pic_buffer(unsigned char **header_buffer)
+{
+    bitstream bs;
+
+    bitstream_start(&bs);
+    nal_start_code_prefix(&bs);
+    nal_header(&bs, NAL_REF_IDC_HIGH, NAL_PPS);
+    pps_rbsp(&bs);
+    bitstream_end(&bs);
+
+    *header_buffer = (unsigned char *)bs.buffer;
+    return bs.bit_offset;
+}
+
+static int
+build_packed_seq_buffer(unsigned char **header_buffer)
+{
+    bitstream bs;
+
+    bitstream_start(&bs);
+    nal_start_code_prefix(&bs);
+    nal_header(&bs, NAL_REF_IDC_HIGH, NAL_SPS);
+    sps_rbsp(&bs);
+    bitstream_end(&bs);
+
+    *header_buffer = (unsigned char *)bs.buffer;
+    return bs.bit_offset;
+}
+
+static int 
+build_packed_sei_buffer_timing(unsigned int init_cpb_removal_length,
+				unsigned int init_cpb_removal_delay,
+				unsigned int init_cpb_removal_delay_offset,
+				unsigned int cpb_removal_length,
+				unsigned int cpb_removal_delay,
+				unsigned int dpb_output_length,
+				unsigned int dpb_output_delay,
+				unsigned char **sei_buffer)
+{
+    unsigned char *byte_buf;
+    int bp_byte_size, i, pic_byte_size;
+
+    bitstream nal_bs;
+    bitstream sei_bp_bs, sei_pic_bs;
+
+    bitstream_start(&sei_bp_bs);
+    bitstream_put_ue(&sei_bp_bs, 0);       /*seq_parameter_set_id*/
+    bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay, cpb_removal_length); 
+    bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay_offset, cpb_removal_length); 
+    if ( sei_bp_bs.bit_offset & 0x7) {
+        bitstream_put_ui(&sei_bp_bs, 1, 1);
+    }
+    bitstream_end(&sei_bp_bs);
+    bp_byte_size = (sei_bp_bs.bit_offset + 7) / 8;
+    
+    bitstream_start(&sei_pic_bs);
+    bitstream_put_ui(&sei_pic_bs, cpb_removal_delay, cpb_removal_length); 
+    bitstream_put_ui(&sei_pic_bs, dpb_output_delay, dpb_output_length); 
+    if ( sei_pic_bs.bit_offset & 0x7) {
+        bitstream_put_ui(&sei_pic_bs, 1, 1);
+    }
+    bitstream_end(&sei_pic_bs);
+    pic_byte_size = (sei_pic_bs.bit_offset + 7) / 8;
+    
+    bitstream_start(&nal_bs);
+    nal_start_code_prefix(&nal_bs);
+    nal_header(&nal_bs, NAL_REF_IDC_NONE, NAL_SEI);
+
+	/* Write the SEI buffer period data */    
+    bitstream_put_ui(&nal_bs, 0, 8);
+    bitstream_put_ui(&nal_bs, bp_byte_size, 8);
+    
+    byte_buf = (unsigned char *)sei_bp_bs.buffer;
+    for(i = 0; i < bp_byte_size; i++) {
+        bitstream_put_ui(&nal_bs, byte_buf[i], 8);
+    }
+    free(byte_buf);
+	/* write the SEI timing data */
+    bitstream_put_ui(&nal_bs, 0x01, 8);
+    bitstream_put_ui(&nal_bs, pic_byte_size, 8);
+    
+    byte_buf = (unsigned char *)sei_pic_bs.buffer;
+    for(i = 0; i < pic_byte_size; i++) {
+        bitstream_put_ui(&nal_bs, byte_buf[i], 8);
+    }
+    free(byte_buf);
+
+    rbsp_trailing_bits(&nal_bs);
+    bitstream_end(&nal_bs);
+
+    *sei_buffer = (unsigned char *)nal_bs.buffer; 
+   
+    return nal_bs.bit_offset;
+}
+
+
+
+/*
+ * Helper function for profiling purposes
+ */
+static unsigned int GetTickCount()
+{
+    struct timeval tv;
+    if (gettimeofday(&tv, NULL))
+        return 0;
+    return tv.tv_usec/1000+tv.tv_sec*1000;
+}
+
+/*
+  Assume frame sequence is: Frame#0,#1,#2,...,#M,...,#X,... (encoding order)
+  1) period between Frame #X and Frame #N = #X - #N
+  2) 0 means infinite for intra_period/intra_idr_period, and 0 is invalid for ip_period
+  3) intra_idr_period % intra_period (intra_period > 0) and intra_period % ip_period must be 0
+  4) intra_period and intra_idr_period take precedence over ip_period
+  5) if ip_period > 1, intra_period and intra_idr_period are not  the strict periods 
+     of I/IDR frames, see bellow examples
+  -------------------------------------------------------------------
+  intra_period intra_idr_period ip_period frame sequence (intra_period/intra_idr_period/ip_period)
+  0            ignored          1          IDRPPPPPPP ...     (No IDR/I any more)
+  0            ignored        >=2          IDR(PBB)(PBB)...   (No IDR/I any more)
+  1            0                ignored    IDRIIIIIII...      (No IDR any more)
+  1            1                ignored    IDR IDR IDR IDR...
+  1            >=2              ignored    IDRII IDRII IDR... (1/3/ignore)
+  >=2          0                1          IDRPPP IPPP I...   (3/0/1)
+  >=2          0              >=2          IDR(PBB)(PBB)(IBB) (6/0/3)
+                                              (PBB)(IBB)(PBB)(IBB)... 
+  >=2          >=2              1          IDRPPPPP IPPPPP IPPPPP (6/18/1)
+                                           IDRPPPPP IPPPPP IPPPPP...
+  >=2          >=2              >=2        {IDR(PBB)(PBB)(IBB)(PBB)(IBB)(PBB)} (6/18/3)
+                                           {IDR(PBB)(PBB)(IBB)(PBB)(IBB)(PBB)}...
+                                           {IDR(PBB)(PBB)(IBB)(PBB)}           (6/12/3)
+                                           {IDR(PBB)(PBB)(IBB)(PBB)}...
+                                           {IDR(PBB)(PBB)}                     (6/6/3)
+                                           {IDR(PBB)(PBB)}.
+*/
+
+/*
+ * Return displaying order with specified periods and encoding order
+ * displaying_order: displaying order
+ * frame_type: frame type 
+ */
+#define FRAME_P 0
+#define FRAME_B 1
+#define FRAME_I 2
+#define FRAME_IDR 7
+void encoding2display_order(
+    unsigned long long encoding_order,int intra_period,
+    int intra_idr_period,int ip_period,
+    unsigned long long *displaying_order,
+    int *frame_type)
+{
+    int encoding_order_gop = 0;
+
+    if (intra_period == 1) { /* all are I/IDR frames */
+        *displaying_order = encoding_order;
+        if (intra_idr_period == 0)
+            *frame_type = (encoding_order == 0)?FRAME_IDR:FRAME_I;
+        else
+            *frame_type = (encoding_order % intra_idr_period == 0)?FRAME_IDR:FRAME_I;
+        return;
+    }
+
+    if (intra_period == 0)
+        intra_idr_period = 0;
+
+    /* new sequence like
+     * IDR PPPPP IPPPPP
+     * IDR (PBB)(PBB)(IBB)(PBB)
+     */
+    encoding_order_gop = (intra_idr_period == 0)? encoding_order:
+        (encoding_order % (intra_idr_period + ((ip_period == 1)?0:1)));
+         
+    if (encoding_order_gop == 0) { /* the first frame */
+        *frame_type = FRAME_IDR;
+        *displaying_order = encoding_order;
+    } else if (((encoding_order_gop - 1) % ip_period) != 0) { /* B frames */
+	*frame_type = FRAME_B;
+        *displaying_order = encoding_order - 1;
+    } else if ((intra_period != 0) && /* have I frames */
+               (encoding_order_gop >= 2) &&
+               ((ip_period == 1 && encoding_order_gop % intra_period == 0) || /* for IDR PPPPP IPPPP */
+                /* for IDR (PBB)(PBB)(IBB) */
+                (ip_period >= 2 && ((encoding_order_gop - 1) / ip_period % (intra_period / ip_period)) == 0))) {
+	*frame_type = FRAME_I;
+	*displaying_order = encoding_order + ip_period - 1;
+    } else {
+	*frame_type = FRAME_P;
+	*displaying_order = encoding_order + ip_period - 1;
+    }
+}
+
+
+static char *fourcc_to_string(int fourcc)
+{
+    switch (fourcc) {
+    case VA_FOURCC_NV12:
+        return "NV12";
+    case VA_FOURCC_IYUV:
+        return "IYUV";
+    case VA_FOURCC_YV12:
+        return "YV12";
+    case VA_FOURCC_UYVY:
+        return "UYVY";
+    default:
+        return "Unknown";
+    }
+}
+
+static int string_to_fourcc(char *str)
+{
+    int fourcc;
+    
+    if (!strncmp(str, "NV12", 4))
+        fourcc = VA_FOURCC_NV12;
+    else if (!strncmp(str, "IYUV", 4))
+        fourcc = VA_FOURCC_IYUV;
+    else if (!strncmp(str, "YV12", 4))
+        fourcc = VA_FOURCC_YV12;
+    else if (!strncmp(str, "UYVY", 4))
+        fourcc = VA_FOURCC_UYVY;
+    else {
+        printf("Unknow FOURCC\n");
+        fourcc = -1;
+    }
+    return fourcc;
+}
+
+
+static char *rc_to_string(int rcmode)
+{
+    switch (rc_mode) {
+    case VA_RC_NONE:
+        return "NONE";
+    case VA_RC_CBR:
+        return "CBR";
+    case VA_RC_VBR:
+        return "VBR";
+    case VA_RC_VCM:
+        return "VCM";
+    case VA_RC_CQP:
+        return "CQP";
+    case VA_RC_VBR_CONSTRAINED:
+        return "VBR_CONSTRAINED";
+    default:
+        return "Unknown";
+    }
+}
+
+static int string_to_rc(char *str)
+{
+    int rc_mode;
+    
+    if (!strncmp(str, "NONE", 4))
+        rc_mode = VA_RC_NONE;
+    else if (!strncmp(str, "CBR", 3))
+        rc_mode = VA_RC_CBR;
+    else if (!strncmp(str, "VBR", 3))
+        rc_mode = VA_RC_VBR;
+    else if (!strncmp(str, "VCM", 3))
+        rc_mode = VA_RC_VCM;
+    else if (!strncmp(str, "CQP", 3))
+        rc_mode = VA_RC_CQP;
+    else if (!strncmp(str, "VBR_CONSTRAINED", 15))
+        rc_mode = VA_RC_VBR_CONSTRAINED;
+    else {
+        printf("Unknown RC mode\n");
+        rc_mode = -1;
+    }
+    return rc_mode;
+}
+
+
+static int print_help(void)
+{
+    printf("./h264encode <options>\n");
+    printf("   -w <width> -h <height>\n");
+    printf("   -framecount <frame number>\n");
+    printf("   -n <frame number>\n");
+    printf("      if set to 0 and srcyuv is set, the frame count is from srcuv file\n");
+    printf("   -o <coded file>\n");
+    printf("   -f <frame rate>\n");
+    printf("   --intra_period <number>\n");
+    printf("   --idr_period <number>\n");
+    printf("   --ip_period <number>\n");
+    printf("   --bitrate <bitrate>\n");
+    printf("   --initialqp <number>\n");
+    printf("   --minqp <number>\n");
+    printf("   --rcmode <NONE|CBR|VBR|VCM|CQP|VBR_CONTRAINED>\n");
+    printf("   --syncmode: sequentially upload source, encoding, save result, no multi-thread\n");
+    printf("   --srcyuv <filename> load YUV from a file\n");
+    printf("   --fourcc <NV12|IYUV|YV12> source YUV fourcc\n");
+    printf("   --recyuv <filename> save reconstructed YUV into a file\n");
+    printf("   --enablePSNR calculate PSNR of recyuv vs. srcyuv\n");
+    printf("   --entropy <0|1>, 1 means cabac, 0 cavlc\n");
+    printf("   --profile <BP|MP|HP>\n");
+    return 0;
+}
+
+static int process_cmdline(int argc, char *argv[])
+{
+    char c;
+    const struct option long_opts[] = {
+        {"help", no_argument, NULL, 0 },
+        {"bitrate", required_argument, NULL, 1 },
+        {"minqp", required_argument, NULL, 2 },
+        {"initialqp", required_argument, NULL, 3 },
+        {"intra_period", required_argument, NULL, 4 },
+        {"idr_period", required_argument, NULL, 5 },
+        {"ip_period", required_argument, NULL, 6 },
+        {"rcmode", required_argument, NULL, 7 },
+        {"srcyuv", required_argument, NULL, 9 },
+        {"recyuv", required_argument, NULL, 10 },
+        {"fourcc", required_argument, NULL, 11 },
+        {"syncmode", no_argument, NULL, 12 },
+        {"enablePSNR", no_argument, NULL, 13 },
+        {"prit", required_argument, NULL, 14 },
+        {"priv", required_argument, NULL, 15 },
+        {"framecount", required_argument, NULL, 16 },
+        {"entropy", required_argument, NULL, 17 },
+        {"profile", required_argument, NULL, 18 },
+        {NULL, no_argument, NULL, 0 }};
+    int long_index;
+    
+    while ((c =getopt_long_only(argc,argv,"w:h:n:f:o:?",long_opts,&long_index)) != EOF) {
+        switch (c) {
+        case 'w':
+            frame_width = atoi(optarg);
+            break;
+        case 'h':
+            frame_height = atoi(optarg);
+            break;
+        case 'n':
+        case 16:
+            frame_count = atoi(optarg);
+            break;
+        case 'f':
+            frame_rate = atoi(optarg);
+            break;
+        case 'o':
+            coded_fn = strdup(optarg);
+            break;
+        case 0:
+            print_help();
+            exit(0);
+        case 1:
+            frame_bitrate = atoi(optarg);
+            break;
+        case 2:
+            minimal_qp = atoi(optarg);
+            break;
+        case 3:
+            initial_qp = atoi(optarg);
+            break;
+        case 4:
+            intra_period = atoi(optarg);
+            break;
+        case 5:
+            intra_idr_period = atoi(optarg);
+            break;
+        case 6:
+            ip_period = atoi(optarg);
+            break;
+        case 7:
+            rc_mode = string_to_rc(optarg);
+            if (rc_mode < 0) {
+                print_help();
+                exit(1);
+            }
+            break;
+        case 9:
+            srcyuv_fn = strdup(optarg);
+            break;
+        case 10:
+            recyuv_fn = strdup(optarg);
+            break;
+        case 11:
+            srcyuv_fourcc = string_to_fourcc(optarg);
+            if (srcyuv_fourcc <= 0) {
+                print_help();
+                exit(1);
+            }
+            break;
+        case 12:
+            encode_syncmode = 1;
+            break;
+        case 13:
+            calc_psnr = 1;
+            break;
+        case 14:
+            misc_priv_type = strtol(optarg, NULL, 0);
+            break;
+        case 15:
+            misc_priv_value = strtol(optarg, NULL, 0);
+            break;
+        case 17:
+            h264_entropy_mode = atoi(optarg) ? 1: 0;
+            break;
+        case 18:
+            if (strncmp(optarg, "BP", 2) == 0)
+                h264_profile = VAProfileH264Baseline;
+            else if (strncmp(optarg, "MP", 2) == 0)
+                h264_profile = VAProfileH264Main;
+            else if (strncmp(optarg, "HP", 2) == 0)
+                h264_profile = VAProfileH264High;
+            else
+                h264_profile = 0;
+            break;
+        case ':':
+        case '?':
+            print_help();
+            exit(0);
+        }
+    }
+
+    if (ip_period < 1) {
+	printf(" ip_period must be greater than 0\n");
+        exit(0);
+    }
+    if (intra_period != 1 && intra_period % ip_period != 0) {
+	printf(" intra_period must be a multiplier of ip_period\n");
+        exit(0);        
+    }
+    if (intra_period != 0 && intra_idr_period % intra_period != 0) {
+	printf(" intra_idr_period must be a multiplier of intra_period\n");
+        exit(0);        
+    }
+
+    if (frame_bitrate == 0)
+        frame_bitrate = frame_width * frame_height * 12 * frame_rate / 50;
+        
+    /* open source file */
+    if (srcyuv_fn) {
+        srcyuv_fp = fopen(srcyuv_fn,"r");
+    
+        if (srcyuv_fp == NULL)
+            printf("Open source YUV file %s failed, use auto-generated YUV data\n", srcyuv_fn);
+        else {
+            struct stat tmp;
+
+            fstat(fileno(srcyuv_fp), &tmp);
+            srcyuv_frames = tmp.st_size / (frame_width * frame_height * 1.5);
+            printf("Source YUV file %s with %llu frames\n", srcyuv_fn, srcyuv_frames);
+
+            if (frame_count == 0)
+                frame_count = srcyuv_frames;
+        }
+    }
+
+    /* open source file */
+    if (recyuv_fn) {
+        recyuv_fp = fopen(recyuv_fn,"w+");
+    
+        if (recyuv_fp == NULL)
+            printf("Open reconstructed YUV file %s failed\n", recyuv_fn);
+    }
+    
+    if (coded_fn == NULL) {
+        struct stat buf;
+        if (stat("/tmp", &buf) == 0)
+            coded_fn = strdup("/tmp/test.264");
+        else if (stat("/sdcard", &buf) == 0)
+            coded_fn = strdup("/sdcard/test.264");
+        else
+            coded_fn = strdup("./test.264");
+    }
+    
+    /* store coded data into a file */
+    coded_fp = fopen(coded_fn,"w+");
+    if (coded_fp == NULL) {
+        printf("Open file %s failed, exit\n", coded_fn);
+        exit(1);
+    }
+
+    frame_width_mbaligned = (frame_width + 15) & (~15);
+    frame_height_mbaligned = (frame_height + 15) & (~15);
+    if (frame_width != frame_width_mbaligned ||
+        frame_height != frame_height_mbaligned) {
+        printf("Source frame is %dx%d and will code clip to %dx%d with crop\n",
+               frame_width, frame_height,
+               frame_width_mbaligned, frame_height_mbaligned
+               );
+    }
+    
+    return 0;
+}
+
+static int init_va(void)
+{
+    VAProfile profile_list[]={VAProfileH264High,VAProfileH264Main,VAProfileH264Baseline,VAProfileH264ConstrainedBaseline};
+    VAEntrypoint *entrypoints;
+    int num_entrypoints, slice_entrypoint;
+    int support_encode = 0;    
+    int major_ver, minor_ver;
+    VAStatus va_status;
+    unsigned int i;
+
+    va_dpy = va_open_display();
+    va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
+    CHECK_VASTATUS(va_status, "vaInitialize");
+
+    num_entrypoints = vaMaxNumEntrypoints(va_dpy);
+    entrypoints = malloc(num_entrypoints * sizeof(*entrypoints));
+    if (!entrypoints) {
+        fprintf(stderr, "error: failed to initialize VA entrypoints array\n");
+        exit(1);
+    }
+
+    /* use the highest profile */
+    for (i = 0; i < sizeof(profile_list)/sizeof(profile_list[0]); i++) {
+        if ((h264_profile != ~0) && h264_profile != profile_list[i])
+            continue;
+        
+        h264_profile = profile_list[i];
+        vaQueryConfigEntrypoints(va_dpy, h264_profile, entrypoints, &num_entrypoints);
+        for (slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) {
+            if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice) {
+                support_encode = 1;
+                break;
+            }
+        }
+        if (support_encode == 1)
+            break;
+    }
+    
+    if (support_encode == 0) {
+        printf("Can't find VAEntrypointEncSlice for H264 profiles\n");
+        exit(1);
+    } else {
+        switch (h264_profile) {
+            case VAProfileH264Baseline:
+                printf("Use profile VAProfileH264Baseline\n");
+                ip_period = 1;
+                constraint_set_flag |= (1 << 0); /* Annex A.2.1 */
+                h264_entropy_mode = 0;
+                break;
+            case VAProfileH264ConstrainedBaseline:
+                printf("Use profile VAProfileH264ConstrainedBaseline\n");
+                constraint_set_flag |= (1 << 0 | 1 << 1); /* Annex A.2.2 */
+                ip_period = 1;
+                break;
+
+            case VAProfileH264Main:
+                printf("Use profile VAProfileH264Main\n");
+                constraint_set_flag |= (1 << 1); /* Annex A.2.2 */
+                break;
+
+            case VAProfileH264High:
+                constraint_set_flag |= (1 << 3); /* Annex A.2.4 */
+                printf("Use profile VAProfileH264High\n");
+                break;
+            default:
+                printf("unknow profile. Set to Baseline");
+                h264_profile = VAProfileH264Baseline;
+                ip_period = 1;
+                constraint_set_flag |= (1 << 0); /* Annex A.2.1 */
+                break;
+        }
+    }
+
+    /* find out the format for the render target, and rate control mode */
+    for (i = 0; i < VAConfigAttribTypeMax; i++)
+        attrib[i].type = i;
+
+    va_status = vaGetConfigAttributes(va_dpy, h264_profile, VAEntrypointEncSlice,
+                                      &attrib[0], VAConfigAttribTypeMax);
+    CHECK_VASTATUS(va_status, "vaGetConfigAttributes");
+    /* check the interested configattrib */
+    if ((attrib[VAConfigAttribRTFormat].value & VA_RT_FORMAT_YUV420) == 0) {
+        printf("Not find desired YUV420 RT format\n");
+        exit(1);
+    } else {
+        config_attrib[config_attrib_num].type = VAConfigAttribRTFormat;
+        config_attrib[config_attrib_num].value = VA_RT_FORMAT_YUV420;
+        config_attrib_num++;
+    }
+    
+    if (attrib[VAConfigAttribRateControl].value != VA_ATTRIB_NOT_SUPPORTED) {
+        int tmp = attrib[VAConfigAttribRateControl].value;
+
+        printf("Support rate control mode (0x%x):", tmp);
+        
+        if (tmp & VA_RC_NONE)
+            printf("NONE ");
+        if (tmp & VA_RC_CBR)
+            printf("CBR ");
+        if (tmp & VA_RC_VBR)
+            printf("VBR ");
+        if (tmp & VA_RC_VCM)
+            printf("VCM ");
+        if (tmp & VA_RC_CQP)
+            printf("CQP ");
+        if (tmp & VA_RC_VBR_CONSTRAINED)
+            printf("VBR_CONSTRAINED ");
+
+        printf("\n");
+
+        /* need to check if support rc_mode */
+        config_attrib[config_attrib_num].type = VAConfigAttribRateControl;
+        config_attrib[config_attrib_num].value = rc_mode;
+        config_attrib_num++;
+    }
+    
+
+    if (attrib[VAConfigAttribEncPackedHeaders].value != VA_ATTRIB_NOT_SUPPORTED) {
+        int tmp = attrib[VAConfigAttribEncPackedHeaders].value;
+
+        printf("Support VAConfigAttribEncPackedHeaders\n");
+        
+        h264_packedheader = 1;
+        config_attrib[config_attrib_num].type = VAConfigAttribEncPackedHeaders;
+        config_attrib[config_attrib_num].value = VA_ENC_PACKED_HEADER_NONE;
+        
+        if (tmp & VA_ENC_PACKED_HEADER_SEQUENCE) {
+            printf("Support packed sequence headers\n");
+            config_attrib[config_attrib_num].value |= VA_ENC_PACKED_HEADER_SEQUENCE;
+        }
+        
+        if (tmp & VA_ENC_PACKED_HEADER_PICTURE) {
+            printf("Support packed picture headers\n");
+            config_attrib[config_attrib_num].value |= VA_ENC_PACKED_HEADER_PICTURE;
+        }
+        
+        if (tmp & VA_ENC_PACKED_HEADER_SLICE) {
+            printf("Support packed slice headers\n");
+            config_attrib[config_attrib_num].value |= VA_ENC_PACKED_HEADER_SLICE;
+        }
+        
+        if (tmp & VA_ENC_PACKED_HEADER_MISC) {
+            printf("Support packed misc headers\n");
+            config_attrib[config_attrib_num].value |= VA_ENC_PACKED_HEADER_MISC;
+        }
+        
+        config_attrib_num++;
+    }
+
+    if (attrib[VAConfigAttribEncInterlaced].value != VA_ATTRIB_NOT_SUPPORTED) {
+        int tmp = attrib[VAConfigAttribEncInterlaced].value;
+        
+        printf("Support VAConfigAttribEncInterlaced\n");
+
+        if (tmp & VA_ENC_INTERLACED_FRAME)
+            printf("support VA_ENC_INTERLACED_FRAME\n");
+        if (tmp & VA_ENC_INTERLACED_FIELD)
+            printf("Support VA_ENC_INTERLACED_FIELD\n");
+        if (tmp & VA_ENC_INTERLACED_MBAFF)
+            printf("Support VA_ENC_INTERLACED_MBAFF\n");
+        if (tmp & VA_ENC_INTERLACED_PAFF)
+            printf("Support VA_ENC_INTERLACED_PAFF\n");
+        
+        config_attrib[config_attrib_num].type = VAConfigAttribEncInterlaced;
+        config_attrib[config_attrib_num].value = VA_ENC_PACKED_HEADER_NONE;
+        config_attrib_num++;
+    }
+    
+    if (attrib[VAConfigAttribEncMaxRefFrames].value != VA_ATTRIB_NOT_SUPPORTED) {
+        h264_maxref = attrib[VAConfigAttribEncMaxRefFrames].value;
+        
+        printf("Support %d RefPicList0 and %d RefPicList1\n",
+               h264_maxref & 0xffff, (h264_maxref >> 16) & 0xffff );
+    }
+
+    if (attrib[VAConfigAttribEncMaxSlices].value != VA_ATTRIB_NOT_SUPPORTED)
+        printf("Support %d slices\n", attrib[VAConfigAttribEncMaxSlices].value);
+
+    if (attrib[VAConfigAttribEncSliceStructure].value != VA_ATTRIB_NOT_SUPPORTED) {
+        int tmp = attrib[VAConfigAttribEncSliceStructure].value;
+        
+        printf("Support VAConfigAttribEncSliceStructure\n");
+
+        if (tmp & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS)
+            printf("Support VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS\n");
+        if (tmp & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS)
+            printf("Support VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS\n");
+        if (tmp & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS)
+            printf("Support VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS\n");
+    }
+    if (attrib[VAConfigAttribEncMacroblockInfo].value != VA_ATTRIB_NOT_SUPPORTED) {
+        printf("Support VAConfigAttribEncMacroblockInfo\n");
+    }
+
+    free(entrypoints);
+    return 0;
+}
+
+static int setup_encode()
+{
+    VAStatus va_status;
+    VASurfaceID *tmp_surfaceid;
+    int codedbuf_size, i;
+    
+    va_status = vaCreateConfig(va_dpy, h264_profile, VAEntrypointEncSlice,
+            &config_attrib[0], config_attrib_num, &config_id);
+    CHECK_VASTATUS(va_status, "vaCreateConfig");
+
+    /* create source surfaces */
+    va_status = vaCreateSurfaces(va_dpy,
+                                 VA_RT_FORMAT_YUV420, frame_width_mbaligned, frame_height_mbaligned,
+                                 &src_surface[0], SURFACE_NUM,
+                                 NULL, 0);
+    CHECK_VASTATUS(va_status, "vaCreateSurfaces");
+
+    /* create reference surfaces */
+    va_status = vaCreateSurfaces(
+            va_dpy,
+            VA_RT_FORMAT_YUV420, frame_width_mbaligned, frame_height_mbaligned,
+            &ref_surface[0], SURFACE_NUM,
+            NULL, 0
+            );
+    CHECK_VASTATUS(va_status, "vaCreateSurfaces");
+
+    tmp_surfaceid = calloc(2 * SURFACE_NUM, sizeof(VASurfaceID));
+    memcpy(tmp_surfaceid, src_surface, SURFACE_NUM * sizeof(VASurfaceID));
+    memcpy(tmp_surfaceid + SURFACE_NUM, ref_surface, SURFACE_NUM * sizeof(VASurfaceID));
+    
+    /* Create a context for this encode pipe */
+    va_status = vaCreateContext(va_dpy, config_id,
+                                frame_width_mbaligned, frame_height_mbaligned,
+                                VA_PROGRESSIVE,
+                                tmp_surfaceid, 2 * SURFACE_NUM,
+                                &context_id);
+    CHECK_VASTATUS(va_status, "vaCreateContext");
+    free(tmp_surfaceid);
+
+    codedbuf_size = (frame_width_mbaligned * frame_height_mbaligned * 400) / (16*16);
+
+    for (i = 0; i < SURFACE_NUM; i++) {
+        /* create coded buffer once for all
+         * other VA buffers which won't be used again after vaRenderPicture.
+         * so APP can always vaCreateBuffer for every frame
+         * but coded buffer need to be mapped and accessed after vaRenderPicture/vaEndPicture
+         * so VA won't maintain the coded buffer
+         */
+        va_status = vaCreateBuffer(va_dpy,context_id,VAEncCodedBufferType,
+                codedbuf_size, 1, NULL, &coded_buf[i]);
+        CHECK_VASTATUS(va_status,"vaCreateBuffer");
+    }
+    
+    return 0;
+}
+
+
+
+#define partition(ref, field, key, ascending)   \
+    while (i <= j) {                            \
+        if (ascending) {                        \
+            while (ref[i].field < key)          \
+                i++;                            \
+            while (ref[j].field > key)          \
+                j--;                            \
+        } else {                                \
+            while (ref[i].field > key)          \
+                i++;                            \
+            while (ref[j].field < key)          \
+                j--;                            \
+        }                                       \
+        if (i <= j) {                           \
+            tmp = ref[i];                       \
+            ref[i] = ref[j];                    \
+            ref[j] = tmp;                       \
+            i++;                                \
+            j--;                                \
+        }                                       \
+    }                                           \
+
+static void sort_one(VAPictureH264 ref[], int left, int right,
+                     int ascending, int frame_idx)
+{
+    int i = left, j = right;
+    unsigned int key;
+    VAPictureH264 tmp;
+
+    if (frame_idx) {
+        key = ref[(left + right) / 2].frame_idx;
+        partition(ref, frame_idx, key, ascending);
+    } else {
+        key = ref[(left + right) / 2].TopFieldOrderCnt;
+        partition(ref, TopFieldOrderCnt, (signed int)key, ascending);
+    }
+    
+    /* recursion */
+    if (left < j)
+        sort_one(ref, left, j, ascending, frame_idx);
+    
+    if (i < right)
+        sort_one(ref, i, right, ascending, frame_idx);
+}
+
+static void sort_two(VAPictureH264 ref[], int left, int right, unsigned int key, unsigned int frame_idx,
+                     int partition_ascending, int list0_ascending, int list1_ascending)
+{
+    int i = left, j = right;
+    VAPictureH264 tmp;
+
+    if (frame_idx) {
+        partition(ref, frame_idx, key, partition_ascending);
+    } else {
+        partition(ref, TopFieldOrderCnt, (signed int)key, partition_ascending);
+    }
+    
+
+    sort_one(ref, left, i-1, list0_ascending, frame_idx);
+    sort_one(ref, j+1, right, list1_ascending, frame_idx);
+}
+
+static int update_ReferenceFrames(void)
+{
+    int i;
+    
+    if (current_frame_type == FRAME_B)
+        return 0;
+
+    CurrentCurrPic.flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
+    numShortTerm++;
+    if (numShortTerm > num_ref_frames)
+        numShortTerm = num_ref_frames;
+    for (i=numShortTerm-1; i>0; i--)
+        ReferenceFrames[i] = ReferenceFrames[i-1];
+    ReferenceFrames[0] = CurrentCurrPic;
+    
+    if (current_frame_type != FRAME_B)
+        current_frame_num++;
+    if (current_frame_num > MaxFrameNum)
+        current_frame_num = 0;
+    
+    return 0;
+}
+
+
+static int update_RefPicList(void)
+{
+    unsigned int current_poc = CurrentCurrPic.TopFieldOrderCnt;
+    
+    if (current_frame_type == FRAME_P) {
+        memcpy(RefPicList0_P, ReferenceFrames, numShortTerm * sizeof(VAPictureH264));
+        sort_one(RefPicList0_P, 0, numShortTerm-1, 0, 1);
+    }
+    
+    if (current_frame_type == FRAME_B) {
+        memcpy(RefPicList0_B, ReferenceFrames, numShortTerm * sizeof(VAPictureH264));
+        sort_two(RefPicList0_B, 0, numShortTerm-1, current_poc, 0,
+                 1, 0, 1);
+
+        memcpy(RefPicList1_B, ReferenceFrames, numShortTerm * sizeof(VAPictureH264));
+        sort_two(RefPicList1_B, 0, numShortTerm-1, current_poc, 0,
+                 0, 1, 0);
+    }
+    
+    return 0;
+}
+
+
+static int render_sequence(void)
+{
+    VABufferID seq_param_buf, rc_param_buf, misc_param_tmpbuf, render_id[2];
+    VAStatus va_status;
+    VAEncMiscParameterBuffer *misc_param, *misc_param_tmp;
+    VAEncMiscParameterRateControl *misc_rate_ctrl;
+    
+    seq_param.level_idc = 41 /*SH_LEVEL_3*/;
+    seq_param.picture_width_in_mbs = frame_width_mbaligned / 16;
+    seq_param.picture_height_in_mbs = frame_height_mbaligned / 16;
+    seq_param.bits_per_second = frame_bitrate;
+
+    seq_param.intra_period = intra_period;
+    seq_param.intra_idr_period = intra_idr_period;
+    seq_param.ip_period = ip_period;
+
+    seq_param.max_num_ref_frames = num_ref_frames;
+    seq_param.seq_fields.bits.frame_mbs_only_flag = 1;
+    seq_param.time_scale = 900;
+    seq_param.num_units_in_tick = 15; /* Tc = num_units_in_tick / time_sacle */
+    seq_param.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = Log2MaxPicOrderCntLsb - 4;
+    seq_param.seq_fields.bits.log2_max_frame_num_minus4 = Log2MaxFrameNum - 4;;
+    seq_param.seq_fields.bits.frame_mbs_only_flag = 1;
+    seq_param.seq_fields.bits.chroma_format_idc = 1;
+    seq_param.seq_fields.bits.direct_8x8_inference_flag = 1;
+    
+    if (frame_width != frame_width_mbaligned ||
+        frame_height != frame_height_mbaligned) {
+        seq_param.frame_cropping_flag = 1;
+        seq_param.frame_crop_left_offset = 0;
+        seq_param.frame_crop_right_offset = (frame_width_mbaligned - frame_width)/2;
+        seq_param.frame_crop_top_offset = 0;
+        seq_param.frame_crop_bottom_offset = (frame_height_mbaligned - frame_height)/2;
+    }
+    
+    va_status = vaCreateBuffer(va_dpy, context_id,
+                               VAEncSequenceParameterBufferType,
+                               sizeof(seq_param),1,&seq_param,&seq_param_buf);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+    
+    va_status = vaCreateBuffer(va_dpy, context_id,
+                               VAEncMiscParameterBufferType,
+                               sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterRateControl),
+                               1,NULL,&rc_param_buf);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+    
+    vaMapBuffer(va_dpy, rc_param_buf,(void **)&misc_param);
+    misc_param->type = VAEncMiscParameterTypeRateControl;
+    misc_rate_ctrl = (VAEncMiscParameterRateControl *)misc_param->data;
+    memset(misc_rate_ctrl, 0, sizeof(*misc_rate_ctrl));
+    misc_rate_ctrl->bits_per_second = frame_bitrate;
+    misc_rate_ctrl->target_percentage = 66;
+    misc_rate_ctrl->window_size = 1000;
+    misc_rate_ctrl->initial_qp = initial_qp;
+    misc_rate_ctrl->min_qp = minimal_qp;
+    misc_rate_ctrl->basic_unit_size = 0;
+    vaUnmapBuffer(va_dpy, rc_param_buf);
+
+    render_id[0] = seq_param_buf;
+    render_id[1] = rc_param_buf;
+    
+    va_status = vaRenderPicture(va_dpy,context_id, &render_id[0], 2);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");;
+
+    if (misc_priv_type != 0) {
+        va_status = vaCreateBuffer(va_dpy, context_id,
+                                   VAEncMiscParameterBufferType,
+                                   sizeof(VAEncMiscParameterBuffer),
+                                   1, NULL, &misc_param_tmpbuf);
+        CHECK_VASTATUS(va_status,"vaCreateBuffer");
+        vaMapBuffer(va_dpy, misc_param_tmpbuf,(void **)&misc_param_tmp);
+        misc_param_tmp->type = misc_priv_type;
+        misc_param_tmp->data[0] = misc_priv_value;
+        vaUnmapBuffer(va_dpy, misc_param_tmpbuf);
+    
+        va_status = vaRenderPicture(va_dpy,context_id, &misc_param_tmpbuf, 1);
+    }
+    
+    return 0;
+}
+
+static int calc_poc(int pic_order_cnt_lsb)
+{
+    static int PicOrderCntMsb_ref = 0, pic_order_cnt_lsb_ref = 0;
+    int prevPicOrderCntMsb, prevPicOrderCntLsb;
+    int PicOrderCntMsb, TopFieldOrderCnt;
+    
+    if (current_frame_type == FRAME_IDR)
+        prevPicOrderCntMsb = prevPicOrderCntLsb = 0;
+    else {
+        prevPicOrderCntMsb = PicOrderCntMsb_ref;
+        prevPicOrderCntLsb = pic_order_cnt_lsb_ref;
+    }
+    
+    if ((pic_order_cnt_lsb < prevPicOrderCntLsb) &&
+        ((prevPicOrderCntLsb - pic_order_cnt_lsb) >= (int)(MaxPicOrderCntLsb / 2)))
+        PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
+    else if ((pic_order_cnt_lsb > prevPicOrderCntLsb) &&
+             ((pic_order_cnt_lsb - prevPicOrderCntLsb) > (int)(MaxPicOrderCntLsb / 2)))
+        PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
+    else
+        PicOrderCntMsb = prevPicOrderCntMsb;
+    
+    TopFieldOrderCnt = PicOrderCntMsb + pic_order_cnt_lsb;
+
+    if (current_frame_type != FRAME_B) {
+        PicOrderCntMsb_ref = PicOrderCntMsb;
+        pic_order_cnt_lsb_ref = pic_order_cnt_lsb;
+    }
+    
+    return TopFieldOrderCnt;
+}
+
+static int render_picture(void)
+{
+    VABufferID pic_param_buf;
+    VAStatus va_status;
+    int i = 0;
+
+    pic_param.CurrPic.picture_id = ref_surface[current_slot];
+    pic_param.CurrPic.frame_idx = current_frame_num;
+    pic_param.CurrPic.flags = 0;
+    pic_param.CurrPic.TopFieldOrderCnt = calc_poc((current_frame_display - current_IDR_display) % MaxPicOrderCntLsb);
+    pic_param.CurrPic.BottomFieldOrderCnt = pic_param.CurrPic.TopFieldOrderCnt;
+    CurrentCurrPic = pic_param.CurrPic;
+
+    if (getenv("TO_DEL")) { /* set RefPicList into ReferenceFrames */
+        update_RefPicList(); /* calc RefPicList */
+        memset(pic_param.ReferenceFrames, 0xff, 16 * sizeof(VAPictureH264)); /* invalid all */
+        if (current_frame_type == FRAME_P) {
+            pic_param.ReferenceFrames[0] = RefPicList0_P[0];
+        } else if (current_frame_type == FRAME_B) {
+            pic_param.ReferenceFrames[0] = RefPicList0_B[0];
+            pic_param.ReferenceFrames[1] = RefPicList1_B[0];
+        }
+    } else {
+        memcpy(pic_param.ReferenceFrames, ReferenceFrames, numShortTerm*sizeof(VAPictureH264));
+        for (i = numShortTerm; i < SURFACE_NUM; i++) {
+            pic_param.ReferenceFrames[i].picture_id = VA_INVALID_SURFACE;
+            pic_param.ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
+        }
+    }
+    
+    pic_param.pic_fields.bits.idr_pic_flag = (current_frame_type == FRAME_IDR);
+    pic_param.pic_fields.bits.reference_pic_flag = (current_frame_type != FRAME_B);
+    pic_param.pic_fields.bits.entropy_coding_mode_flag = h264_entropy_mode;
+    pic_param.pic_fields.bits.deblocking_filter_control_present_flag = 1;
+    pic_param.frame_num = current_frame_num;
+    pic_param.coded_buf = coded_buf[current_slot];
+    pic_param.last_picture = (current_frame_encoding == frame_count);
+    pic_param.pic_init_qp = initial_qp;
+
+    va_status = vaCreateBuffer(va_dpy, context_id,VAEncPictureParameterBufferType,
+                               sizeof(pic_param),1,&pic_param, &pic_param_buf);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");;
+
+    va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+
+    return 0;
+}
+
+static int render_packedsequence(void)
+{
+    VAEncPackedHeaderParameterBuffer packedheader_param_buffer;
+    VABufferID packedseq_para_bufid, packedseq_data_bufid, render_id[2];
+    unsigned int length_in_bits;
+    unsigned char *packedseq_buffer = NULL;
+    VAStatus va_status;
+
+    length_in_bits = build_packed_seq_buffer(&packedseq_buffer); 
+    
+    packedheader_param_buffer.type = VAEncPackedHeaderSequence;
+    
+    packedheader_param_buffer.bit_length = length_in_bits; /*length_in_bits*/
+    packedheader_param_buffer.has_emulation_bytes = 0;
+    va_status = vaCreateBuffer(va_dpy,
+                               context_id,
+                               VAEncPackedHeaderParameterBufferType,
+                               sizeof(packedheader_param_buffer), 1, &packedheader_param_buffer,
+                               &packedseq_para_bufid);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    va_status = vaCreateBuffer(va_dpy,
+                               context_id,
+                               VAEncPackedHeaderDataBufferType,
+                               (length_in_bits + 7) / 8, 1, packedseq_buffer,
+                               &packedseq_data_bufid);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    render_id[0] = packedseq_para_bufid;
+    render_id[1] = packedseq_data_bufid;
+    va_status = vaRenderPicture(va_dpy,context_id, render_id, 2);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+
+    free(packedseq_buffer);
+    
+    return 0;
+}
+
+
+static int render_packedpicture(void)
+{
+    VAEncPackedHeaderParameterBuffer packedheader_param_buffer;
+    VABufferID packedpic_para_bufid, packedpic_data_bufid, render_id[2];
+    unsigned int length_in_bits;
+    unsigned char *packedpic_buffer = NULL;
+    VAStatus va_status;
+
+    length_in_bits = build_packed_pic_buffer(&packedpic_buffer); 
+    packedheader_param_buffer.type = VAEncPackedHeaderPicture;
+    packedheader_param_buffer.bit_length = length_in_bits;
+    packedheader_param_buffer.has_emulation_bytes = 0;
+
+    va_status = vaCreateBuffer(va_dpy,
+                               context_id,
+                               VAEncPackedHeaderParameterBufferType,
+                               sizeof(packedheader_param_buffer), 1, &packedheader_param_buffer,
+                               &packedpic_para_bufid);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    va_status = vaCreateBuffer(va_dpy,
+                               context_id,
+                               VAEncPackedHeaderDataBufferType,
+                               (length_in_bits + 7) / 8, 1, packedpic_buffer,
+                               &packedpic_data_bufid);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    render_id[0] = packedpic_para_bufid;
+    render_id[1] = packedpic_data_bufid;
+    va_status = vaRenderPicture(va_dpy,context_id, render_id, 2);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+
+    free(packedpic_buffer);
+    
+    return 0;
+}
+
+static void render_packedsei(void)
+{
+    VAEncPackedHeaderParameterBuffer packed_header_param_buffer;
+    VABufferID packed_sei_header_param_buf_id, packed_sei_buf_id, render_id[2];
+    unsigned int length_in_bits /*offset_in_bytes*/;
+    unsigned char *packed_sei_buffer = NULL;
+    VAStatus va_status;
+    int init_cpb_size, target_bit_rate, i_initial_cpb_removal_delay_length, i_initial_cpb_removal_delay;
+    int i_cpb_removal_delay, i_dpb_output_delay_length, i_cpb_removal_delay_length;
+
+    /* it comes for the bps defined in SPS */
+    target_bit_rate = frame_bitrate;
+    init_cpb_size = (target_bit_rate * 8) >> 10;
+    i_initial_cpb_removal_delay = init_cpb_size * 0.5 * 1024 / target_bit_rate * 90000;
+
+    i_cpb_removal_delay = 2;
+    i_initial_cpb_removal_delay_length = 24;
+    i_cpb_removal_delay_length = 24;
+    i_dpb_output_delay_length = 24;
+    
+
+    length_in_bits = build_packed_sei_buffer_timing(
+        i_initial_cpb_removal_delay_length,
+        i_initial_cpb_removal_delay,
+        0,
+        i_cpb_removal_delay_length,
+        i_cpb_removal_delay * current_frame_encoding,
+        i_dpb_output_delay_length,
+        0,
+        &packed_sei_buffer);
+
+    //offset_in_bytes = 0;
+    packed_header_param_buffer.type = VAEncPackedHeaderH264_SEI;
+    packed_header_param_buffer.bit_length = length_in_bits;
+    packed_header_param_buffer.has_emulation_bytes = 0;
+
+    va_status = vaCreateBuffer(va_dpy,
+                               context_id,
+                               VAEncPackedHeaderParameterBufferType,
+                               sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer,
+                               &packed_sei_header_param_buf_id);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    va_status = vaCreateBuffer(va_dpy,
+                               context_id,
+                               VAEncPackedHeaderDataBufferType,
+                               (length_in_bits + 7) / 8, 1, packed_sei_buffer,
+                               &packed_sei_buf_id);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+
+    render_id[0] = packed_sei_header_param_buf_id;
+    render_id[1] = packed_sei_buf_id;
+    va_status = vaRenderPicture(va_dpy,context_id, render_id, 2);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+
+    
+    free(packed_sei_buffer);
+        
+    return;
+}
+
+
+static int render_hrd(void)
+{
+    VABufferID misc_parameter_hrd_buf_id;
+    VAStatus va_status;
+    VAEncMiscParameterBuffer *misc_param;
+    VAEncMiscParameterHRD *misc_hrd_param;
+    
+    va_status = vaCreateBuffer(va_dpy, context_id,
+                   VAEncMiscParameterBufferType,
+                   sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterHRD),
+                   1,
+                   NULL, 
+                   &misc_parameter_hrd_buf_id);
+    CHECK_VASTATUS(va_status, "vaCreateBuffer");
+
+    vaMapBuffer(va_dpy,
+                misc_parameter_hrd_buf_id,
+                (void **)&misc_param);
+    misc_param->type = VAEncMiscParameterTypeHRD;
+    misc_hrd_param = (VAEncMiscParameterHRD *)misc_param->data;
+
+    if (frame_bitrate > 0) {
+        misc_hrd_param->initial_buffer_fullness = frame_bitrate * 1024 * 4;
+        misc_hrd_param->buffer_size = frame_bitrate * 1024 * 8;
+    } else {
+        misc_hrd_param->initial_buffer_fullness = 0;
+        misc_hrd_param->buffer_size = 0;
+    }
+    vaUnmapBuffer(va_dpy, misc_parameter_hrd_buf_id);
+
+    va_status = vaRenderPicture(va_dpy,context_id, &misc_parameter_hrd_buf_id, 1);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");;
+
+    return 0;
+}
+
+static int render_slice(void)
+{
+    VABufferID slice_param_buf;
+    VAStatus va_status;
+    int i;
+
+    update_RefPicList();
+    
+    /* one frame, one slice */
+    slice_param.macroblock_address = 0;
+    slice_param.num_macroblocks = frame_width_mbaligned * frame_height_mbaligned/(16*16); /* Measured by MB */
+    slice_param.slice_type = (current_frame_type == FRAME_IDR)?2:current_frame_type;
+    if (current_frame_type == FRAME_IDR) {
+        if (current_frame_encoding != 0)
+            ++slice_param.idr_pic_id;
+    } else if (current_frame_type == FRAME_P) {
+        int refpiclist0_max = h264_maxref & 0xffff;
+        memcpy(slice_param.RefPicList0, RefPicList0_P, refpiclist0_max*sizeof(VAPictureH264));
+
+        for (i = refpiclist0_max; i < 32; i++) {
+            slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE;
+            slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
+        }
+    } else if (current_frame_type == FRAME_B) {
+        int refpiclist0_max = h264_maxref & 0xffff;
+        int refpiclist1_max = (h264_maxref >> 16) & 0xffff;
+
+        memcpy(slice_param.RefPicList0, RefPicList0_B, refpiclist0_max*sizeof(VAPictureH264));
+        for (i = refpiclist0_max; i < 32; i++) {
+            slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE;
+            slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
+        }
+
+        memcpy(slice_param.RefPicList1, RefPicList1_B, refpiclist1_max*sizeof(VAPictureH264));
+        for (i = refpiclist1_max; i < 32; i++) {
+            slice_param.RefPicList1[i].picture_id = VA_INVALID_SURFACE;
+            slice_param.RefPicList1[i].flags = VA_PICTURE_H264_INVALID;
+        }
+    }
+
+    slice_param.slice_alpha_c0_offset_div2 = 0;
+    slice_param.slice_beta_offset_div2 = 0;
+    slice_param.direct_spatial_mv_pred_flag = 1;
+    slice_param.pic_order_cnt_lsb = (current_frame_display - current_IDR_display) % MaxPicOrderCntLsb;
+    
+    va_status = vaCreateBuffer(va_dpy,context_id,VAEncSliceParameterBufferType,
+                               sizeof(slice_param),1,&slice_param,&slice_param_buf);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");;
+
+    va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+    
+    return 0;
+}
+
+
+static int upload_source_YUV_once_for_all()
+{
+    int box_width=8;
+    int row_shift=0;
+    int i;
+
+    for (i = 0; i < SURFACE_NUM; i++) {
+        printf("\rLoading data into surface %d.....", i);
+        upload_surface(va_dpy, src_surface[i], box_width, row_shift, 0);
+
+        row_shift++;
+        if (row_shift==(2*box_width)) row_shift= 0;
+    }
+    printf("Complete surface loading\n");
+
+    return 0;
+}
+
+static int load_surface(VASurfaceID surface_id, unsigned long long display_order)
+{
+    unsigned char *srcyuv_ptr = NULL, *src_Y = NULL, *src_U = NULL, *src_V = NULL;
+    unsigned long long frame_start, mmap_start;
+    char *mmap_ptr = NULL;
+    int frame_size, mmap_size;
+    
+    if (srcyuv_fp == NULL)
+        return 0;
+    
+    /* allow encoding more than srcyuv_frames */    
+    display_order = display_order % srcyuv_frames;
+    frame_size = frame_width * frame_height * 3 / 2; /* for YUV420 */
+    frame_start = display_order * frame_size;
+    
+    mmap_start = frame_start & (~0xfff);
+    mmap_size = (frame_size + (frame_start & 0xfff) + 0xfff) & (~0xfff);
+    mmap_ptr = mmap(0, mmap_size, PROT_READ, MAP_SHARED,
+                    fileno(srcyuv_fp), mmap_start);
+    if (mmap_ptr == MAP_FAILED) {
+        printf("Failed to mmap YUV file (%s)\n", strerror(errno));
+        return 1;
+    }
+    srcyuv_ptr = (unsigned char *)mmap_ptr +  (frame_start & 0xfff);
+    if (srcyuv_fourcc == VA_FOURCC_NV12) {
+        src_Y = srcyuv_ptr;
+        src_U = src_Y + frame_width * frame_height;
+        src_V = NULL;
+    } else if (srcyuv_fourcc == VA_FOURCC_IYUV ||
+        srcyuv_fourcc == VA_FOURCC_YV12) {
+        src_Y = srcyuv_ptr;
+        if (srcyuv_fourcc == VA_FOURCC_IYUV) {
+            src_U = src_Y + frame_width * frame_height;
+            src_V = src_U + (frame_width/2) * (frame_height/2);
+        } else { /* YV12 */
+            src_V = src_Y + frame_width * frame_height;
+            src_U = src_V + (frame_width/2) * (frame_height/2);
+        } 
+    } else {
+        printf("Unsupported source YUV format\n");
+        exit(1);
+    }
+    
+    upload_surface_yuv(va_dpy, surface_id,
+                       srcyuv_fourcc, frame_width, frame_height,
+                       src_Y, src_U, src_V);
+    if (mmap_ptr)
+        munmap(mmap_ptr, mmap_size);
+
+    return 0;
+}
+
+
+static int save_recyuv(VASurfaceID surface_id,
+                       unsigned long long display_order,
+                       unsigned long long encode_order)
+{
+    unsigned char *dst_Y = NULL, *dst_U = NULL, *dst_V = NULL;
+
+    if (recyuv_fp == NULL)
+        return 0;
+
+    if (srcyuv_fourcc == VA_FOURCC_NV12) {
+        int uv_size = 2 * (frame_width/2) * (frame_height/2);
+        dst_Y = malloc(2*uv_size);
+        dst_U = malloc(uv_size);
+    } else if (srcyuv_fourcc == VA_FOURCC_IYUV ||
+               srcyuv_fourcc == VA_FOURCC_YV12) {
+        int uv_size = (frame_width/2) * (frame_height/2);
+        dst_Y = malloc(4*uv_size);
+        dst_U = malloc(uv_size);
+        dst_V = malloc(uv_size);
+    } else {
+        printf("Unsupported source YUV format\n");
+        exit(1);
+    }
+    
+    download_surface_yuv(va_dpy, surface_id,
+                         srcyuv_fourcc, frame_width, frame_height,
+                         dst_Y, dst_U, dst_V);
+    fseek(recyuv_fp, display_order * frame_width * frame_height * 1.5, SEEK_SET);
+
+    if (srcyuv_fourcc == VA_FOURCC_NV12) {
+        int uv_size = 2 * (frame_width/2) * (frame_height/2);
+        fwrite(dst_Y, uv_size * 2, 1, recyuv_fp);
+        fwrite(dst_U, uv_size, 1, recyuv_fp);
+    } else if (srcyuv_fourcc == VA_FOURCC_IYUV ||
+               srcyuv_fourcc == VA_FOURCC_YV12) {
+        int uv_size = (frame_width/2) * (frame_height/2);
+        fwrite(dst_Y, uv_size * 4, 1, recyuv_fp);
+        
+        if (srcyuv_fourcc == VA_FOURCC_IYUV) {
+            fwrite(dst_U, uv_size, 1, recyuv_fp);
+            fwrite(dst_V, uv_size, 1, recyuv_fp);
+        } else {
+            fwrite(dst_V, uv_size, 1, recyuv_fp);
+            fwrite(dst_U, uv_size, 1, recyuv_fp);
+        }
+    } else {
+        printf("Unsupported YUV format\n");
+        exit(1);
+    }
+    
+    if (dst_Y)
+        free(dst_Y);
+    if (dst_U)
+        free(dst_U);
+    if (dst_V)
+        free(dst_V);
+
+    fflush(recyuv_fp);
+
+    return 0;
+}
+
+
+static int save_codeddata(unsigned long long display_order, unsigned long long encode_order)
+{    
+    VACodedBufferSegment *buf_list = NULL;
+    VAStatus va_status;
+    unsigned int coded_size = 0;
+
+    va_status = vaMapBuffer(va_dpy,coded_buf[display_order % SURFACE_NUM],(void **)(&buf_list));
+    CHECK_VASTATUS(va_status,"vaMapBuffer");
+    while (buf_list != NULL) {
+        coded_size += fwrite(buf_list->buf, 1, buf_list->size, coded_fp);
+        buf_list = (VACodedBufferSegment *) buf_list->next;
+
+        frame_size += coded_size;
+    }
+    vaUnmapBuffer(va_dpy,coded_buf[display_order % SURFACE_NUM]);
+
+    printf("\r      "); /* return back to startpoint */
+    switch (encode_order % 4) {
+        case 0:
+            printf("|");
+            break;
+        case 1:
+            printf("/");
+            break;
+        case 2:
+            printf("-");
+            break;
+        case 3:
+            printf("\\");
+            break;
+    }
+    printf("%08lld", encode_order);
+    printf("(%06d bytes coded)",coded_size);
+
+    fflush(coded_fp);
+    
+    return 0;
+}
+
+
+static struct storage_task_t * storage_task_dequeue(void)
+{
+    struct storage_task_t *header;
+
+    pthread_mutex_lock(&encode_mutex);
+
+    header = storage_task_header;    
+    if (storage_task_header != NULL) {
+        if (storage_task_tail == storage_task_header)
+            storage_task_tail = NULL;
+        storage_task_header = header->next;
+    }
+    
+    pthread_mutex_unlock(&encode_mutex);
+    
+    return header;
+}
+
+static int storage_task_queue(unsigned long long display_order, unsigned long long encode_order)
+{
+    struct storage_task_t *tmp;
+
+    tmp = calloc(1, sizeof(struct storage_task_t));
+    tmp->display_order = display_order;
+    tmp->encode_order = encode_order;
+
+    pthread_mutex_lock(&encode_mutex);
+    
+    if (storage_task_header == NULL) {
+        storage_task_header = tmp;
+        storage_task_tail = tmp;
+    } else {
+        storage_task_tail->next = tmp;
+        storage_task_tail = tmp;
+    }
+
+    srcsurface_status[display_order % SURFACE_NUM] = SRC_SURFACE_IN_STORAGE;
+    pthread_cond_signal(&encode_cond);
+    
+    pthread_mutex_unlock(&encode_mutex);
+    
+    return 0;
+}
+
+static void storage_task(unsigned long long display_order, unsigned long long encode_order)
+{
+    unsigned int tmp;
+    VAStatus va_status;
+    
+    tmp = GetTickCount();
+    va_status = vaSyncSurface(va_dpy, src_surface[display_order % SURFACE_NUM]);
+    CHECK_VASTATUS(va_status,"vaSyncSurface");
+    SyncPictureTicks += GetTickCount() - tmp;
+    tmp = GetTickCount();
+    save_codeddata(display_order, encode_order);
+    SavePictureTicks += GetTickCount() - tmp;
+
+    save_recyuv(ref_surface[display_order % SURFACE_NUM], display_order, encode_order);
+
+    /* reload a new frame data */
+    tmp = GetTickCount();
+    if (srcyuv_fp != NULL)
+        load_surface(src_surface[display_order % SURFACE_NUM], display_order + SURFACE_NUM);
+    UploadPictureTicks += GetTickCount() - tmp;
+
+    pthread_mutex_lock(&encode_mutex);
+    srcsurface_status[display_order % SURFACE_NUM] = SRC_SURFACE_IN_ENCODING;
+    pthread_mutex_unlock(&encode_mutex);
+}
+
+        
+static void * storage_task_thread(void *t)
+{
+    while (1) {
+        struct storage_task_t *current;
+        
+        current = storage_task_dequeue();
+        if (current == NULL) {
+            pthread_mutex_lock(&encode_mutex);
+            pthread_cond_wait(&encode_cond, &encode_mutex);
+            pthread_mutex_unlock(&encode_mutex);
+            continue;
+        }
+        
+        storage_task(current->display_order, current->encode_order);
+        
+        free(current);
+
+        /* all frames are saved, exit the thread */
+        if (++frame_coded >= frame_count)
+            break;
+    }
+
+    return 0;
+}
+
+
+static int encode_frames(void)
+{
+    unsigned int i, tmp;
+    VAStatus va_status;
+    //VASurfaceStatus surface_status;
+
+    /* upload RAW YUV data into all surfaces */
+    tmp = GetTickCount();
+    if (srcyuv_fp != NULL) {
+        for (i = 0; i < SURFACE_NUM; i++)
+            load_surface(src_surface[i], i);
+    } else
+        upload_source_YUV_once_for_all();
+    UploadPictureTicks += GetTickCount() - tmp;
+    
+    /* ready for encoding */
+    memset(srcsurface_status, SRC_SURFACE_IN_ENCODING, sizeof(srcsurface_status));
+    
+    memset(&seq_param, 0, sizeof(seq_param));
+    memset(&pic_param, 0, sizeof(pic_param));
+    memset(&slice_param, 0, sizeof(slice_param));
+
+    if (encode_syncmode == 0)
+        pthread_create(&encode_thread, NULL, storage_task_thread, NULL);
+    
+    for (current_frame_encoding = 0; current_frame_encoding < frame_count; current_frame_encoding++) {
+        encoding2display_order(current_frame_encoding, intra_period, intra_idr_period, ip_period,
+                               &current_frame_display, &current_frame_type);
+        if (current_frame_type == FRAME_IDR) {
+            numShortTerm = 0;
+            current_frame_num = 0;
+            current_IDR_display = current_frame_display;
+        }
+
+        /* check if the source frame is ready */
+        while (srcsurface_status[current_slot] != SRC_SURFACE_IN_ENCODING) {
+            usleep(1);
+        }
+        
+        tmp = GetTickCount();
+        va_status = vaBeginPicture(va_dpy, context_id, src_surface[current_slot]);
+        CHECK_VASTATUS(va_status,"vaBeginPicture");
+        BeginPictureTicks += GetTickCount() - tmp;
+        
+        tmp = GetTickCount();
+        if (current_frame_type == FRAME_IDR) {
+            render_sequence();
+            render_picture();            
+            if (h264_packedheader) {
+                render_packedsequence();
+                render_packedpicture();
+            }
+            //if (rc_mode == VA_RC_CBR)
+            //    render_packedsei();
+            //render_hrd();
+        } else {
+            //render_sequence();
+            render_picture();
+            //if (rc_mode == VA_RC_CBR)
+            //    render_packedsei();
+            //render_hrd();
+        }
+        render_slice();
+        RenderPictureTicks += GetTickCount() - tmp;
+        
+        tmp = GetTickCount();
+        va_status = vaEndPicture(va_dpy,context_id);
+        CHECK_VASTATUS(va_status,"vaEndPicture");;
+        EndPictureTicks += GetTickCount() - tmp;
+
+        if (encode_syncmode)
+            storage_task(current_frame_display, current_frame_encoding);
+        else /* queue the storage task queue */
+            storage_task_queue(current_frame_display, current_frame_encoding);
+        
+        update_ReferenceFrames();        
+    }
+
+    if (encode_syncmode == 0) {
+        int ret;
+        pthread_join(encode_thread, (void **)&ret);
+    }
+    
+    return 0;
+}
+
+
+static int release_encode()
+{
+    int i;
+    
+    vaDestroySurfaces(va_dpy,&src_surface[0],SURFACE_NUM);
+    vaDestroySurfaces(va_dpy,&ref_surface[0],SURFACE_NUM);
+
+    for (i = 0; i < SURFACE_NUM; i++)
+        vaDestroyBuffer(va_dpy,coded_buf[i]);
+    
+    vaDestroyContext(va_dpy,context_id);
+    vaDestroyConfig(va_dpy,config_id);
+
+    return 0;
+}
+
+static int deinit_va()
+{ 
+    vaTerminate(va_dpy);
+
+    va_close_display(va_dpy);
+
+    return 0;
+}
+
+
+static int print_input()
+{
+    printf("\n\nINPUT:Try to encode H264...\n");
+    printf("INPUT: RateControl  : %s\n", rc_to_string(rc_mode));
+    printf("INPUT: Resolution   : %dx%d, %d frames\n",
+           frame_width, frame_height, frame_count);
+    printf("INPUT: FrameRate    : %d\n", frame_rate);
+    printf("INPUT: Bitrate      : %d\n", frame_bitrate);
+    printf("INPUT: Slieces      : %d\n", frame_slices);
+    printf("INPUT: IntraPeriod  : %d\n", intra_period);
+    printf("INPUT: IDRPeriod    : %d\n", intra_idr_period);
+    printf("INPUT: IpPeriod     : %d\n", ip_period);
+    printf("INPUT: Initial QP   : %d\n", initial_qp);
+    printf("INPUT: Min QP       : %d\n", minimal_qp);
+    printf("INPUT: Source YUV   : %s", srcyuv_fp?"FILE":"AUTO generated");
+    if (srcyuv_fp) 
+        printf(":%s (fourcc %s)\n", srcyuv_fn, fourcc_to_string(srcyuv_fourcc));
+    else
+        printf("\n");
+    printf("INPUT: Coded Clip   : %s\n", coded_fn);
+    if (recyuv_fp == NULL)
+        printf("INPUT: Rec   Clip   : %s\n", "Not save reconstructed frame");
+    else
+        printf("INPUT: Rec   Clip   : Save reconstructed frame into %s (fourcc %s)\n", recyuv_fn,
+               fourcc_to_string(srcyuv_fourcc));
+    
+    printf("\n\n"); /* return back to startpoint */
+    
+    return 0;
+}
+
+static int calc_PSNR(double *psnr)
+{
+    char *srcyuv_ptr = NULL, *recyuv_ptr = NULL, tmp;
+    unsigned long long min_size;
+    unsigned long long i, sse=0;
+    double ssemean;
+    int fourM = 0x400000; /* 4M */
+
+    min_size = MIN(srcyuv_frames, frame_count) * frame_width * frame_height * 1.5;
+    for (i=0; i<min_size; i++) {
+        unsigned long long j = i % fourM;
+        
+        if ((i % fourM) == 0) {
+            if (srcyuv_ptr)
+                munmap(srcyuv_ptr, fourM);
+            if (recyuv_ptr)
+                munmap(recyuv_ptr, fourM);
+            
+            srcyuv_ptr = mmap(0, fourM, PROT_READ, MAP_SHARED, fileno(srcyuv_fp), i);
+            recyuv_ptr = mmap(0, fourM, PROT_READ, MAP_SHARED, fileno(recyuv_fp), i);
+            if ((srcyuv_ptr == MAP_FAILED) || (recyuv_ptr == MAP_FAILED)) {
+                printf("Failed to mmap YUV files\n");
+                return 1;
+            }
+        }
+        tmp = srcyuv_ptr[j] - recyuv_ptr[j];
+        sse += tmp * tmp;
+    }
+    ssemean = (double)sse/(double)min_size;
+    *psnr = 20.0*log10(255) - 10.0*log10(ssemean);
+
+    if (srcyuv_ptr)
+        munmap(srcyuv_ptr, fourM);
+    if (recyuv_ptr)
+        munmap(recyuv_ptr, fourM);
+    
+    return 0;
+}
+
+static int print_performance(unsigned int PictureCount)
+{
+    unsigned int psnr_ret = 1, others = 0;
+    double psnr = 0, total_size = frame_width * frame_height * 1.5 * frame_count;
+
+    if (calc_psnr && srcyuv_fp && recyuv_fp)
+        psnr_ret = calc_PSNR(&psnr);
+    
+    others = TotalTicks - UploadPictureTicks - BeginPictureTicks
+        - RenderPictureTicks - EndPictureTicks - SyncPictureTicks - SavePictureTicks;
+
+    printf("\n\n");
+
+    printf("PERFORMANCE:   Frame Rate           : %.2f fps (%d frames, %d ms (%.2f ms per frame))\n",
+           (double) 1000*PictureCount / TotalTicks, PictureCount,
+           TotalTicks, ((double)  TotalTicks) / (double) PictureCount);
+    printf("PERFORMANCE:   Compression ratio    : %d:1\n", (unsigned int)(total_size / frame_size));
+    if (psnr_ret == 0)
+        printf("PERFORMANCE:   PSNR                 : %.2f (%lld frames calculated)\n",
+               psnr, MIN(frame_count, srcyuv_frames));
+
+    printf("PERFORMANCE:     UploadPicture      : %d ms (%.2f, %.2f%% percent)\n",
+           (int) UploadPictureTicks, ((double)  UploadPictureTicks) / (double) PictureCount,
+           UploadPictureTicks/(double) TotalTicks/0.01);
+    printf("PERFORMANCE:     vaBeginPicture     : %d ms (%.2f, %.2f%% percent)\n",
+           (int) BeginPictureTicks, ((double)  BeginPictureTicks) / (double) PictureCount,
+           BeginPictureTicks/(double) TotalTicks/0.01);
+    printf("PERFORMANCE:     vaRenderHeader     : %d ms (%.2f, %.2f%% percent)\n",
+           (int) RenderPictureTicks, ((double)  RenderPictureTicks) / (double) PictureCount,
+           RenderPictureTicks/(double) TotalTicks/0.01);
+    printf("PERFORMANCE:     vaEndPicture       : %d ms (%.2f, %.2f%% percent)\n",
+           (int) EndPictureTicks, ((double)  EndPictureTicks) / (double) PictureCount,
+           EndPictureTicks/(double) TotalTicks/0.01);
+    printf("PERFORMANCE:     vaSyncSurface      : %d ms (%.2f, %.2f%% percent)\n",
+           (int) SyncPictureTicks, ((double) SyncPictureTicks) / (double) PictureCount,
+           SyncPictureTicks/(double) TotalTicks/0.01);
+    printf("PERFORMANCE:     SavePicture        : %d ms (%.2f, %.2f%% percent)\n",
+           (int) SavePictureTicks, ((double)  SavePictureTicks) / (double) PictureCount,
+           SavePictureTicks/(double) TotalTicks/0.01);
+    printf("PERFORMANCE:     Others             : %d ms (%.2f, %.2f%% percent)\n",
+           (int) others, ((double) others) / (double) PictureCount,
+           others/(double) TotalTicks/0.01);
+
+    if (encode_syncmode == 0)
+        printf("(Multithread enabled, the timing is only for reference)\n");
+    
+    return 0;
+}
+
+
+int main(int argc,char **argv)
+{
+    unsigned int start;
+    
+    process_cmdline(argc, argv);
+
+    print_input();
+    
+    start = GetTickCount();
+    
+    init_va();
+    setup_encode();
+    
+    encode_frames();
+
+    release_encode();
+    deinit_va();
+
+    TotalTicks += GetTickCount() - start;
+    print_performance(frame_count);
+    
+    return 0;
+}
diff --git a/test/encode/h264encode_android.cpp b/test/encode/h264encode_android.cpp
deleted file mode 100644
index a3f4db4..0000000
--- a/test/encode/h264encode_android.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * it is a real program to show how VAAPI encoding work,
- * It does H264 element stream level encoding on auto-generated YUV data
- *
- * gcc -o  h264encode  h264encode -lva -lva-x11
- * ./h264encode -w <width> -h <height> -n <frame_num>
- *
- */  
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <binder/MemoryHeapBase.h>
-#define Display unsigned int
-
-using namespace android;
-#include "../android_winsys.cpp"
-#include "h264encode_common.c"
-
-sp<SurfaceComposerClient> client;
-sp<Surface> android_surface;
-sp<ISurface> android_isurface;
-sp<SurfaceControl> surface_ctrl;
-#if 0
-static int display_surface(int frame_id, int *exit_encode)
-{
-    VAStatus va_status;
-
-    sp<ProcessState> proc(ProcessState::self());
-    ProcessState::self()->startThreadPool();
-
-    printf("Create window0 for thread0\n");
-    SURFACE_CREATE(client,surface_ctrl,android_surface, android_isurface, 0, 0, win_width, win_height);
-    va_status = vaPutSurface(va_dpy, surface_id[frame_id], android_isurface,
-            0,0, frame_width, frame_height,
-            0,0, win_width, win_height,
-            NULL,0,0);
-
-    *exit_encode = 0;
-    return 0;
-}
-#endif
diff --git a/test/encode/h264encode_common.c b/test/encode/h264encode_common.c
deleted file mode 100644
index a3d3c8f..0000000
--- a/test/encode/h264encode_common.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * it is a real program to show how VAAPI encoding work,
- * It does H264 element stream level encoding on auto-generated YUV data
- * gcc -o  h264encode  h264encode -lva -lva-x11
- * ./h264encode -w <width> -h <height> -n <frame_num>
- */  
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <va/va.h>
-#include <va/va_tpi.h>
-#include <va/va_enc_h264.h>
-#ifdef ANDROID
-#include <va/va_android.h>
-#else
-#include <va/va_x11.h>
-#endif
-
-#define CHECK_VASTATUS(va_status,func)                                  \
-    if (va_status != VA_STATUS_SUCCESS) {                                   \
-        fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
-        exit(1);                                                            \
-    }
-
-#include "../loadsurface.h"
-#define SURFACE_NUM 18 /* 16 surfaces for src, 2 surface for reconstructed/reference */
-#define CODEDBUF_NUM 5
-static  VADisplay va_dpy;
-static  VASurfaceID surface_id[SURFACE_NUM];
-static  VABufferID coded_buf[CODEDBUF_NUM];
-static  VAContextID context_id;
-static  Display *x11_display;
-static  int coded_fd;
-static  char coded_file[256];
-static  int frame_width=320,  frame_height=240;
-static  int win_width;
-static  int win_height;
-static  int frame_display = 0; /* display the frame during encoding */
-static  int frame_rate = 30;
-static  int frame_count = 400;
-static  int intra_count = 30;
-static  int frame_bitrate = 8000000; /* 8M */
-static  int initial_qp = 15;
-static  int minimal_qp = 0;
-VASurfaceAttributeTPI * vaSurfaceAttrib;
-
-#define SURFACE_ATTRIB 0
-static int display_surface(int frame_id, int *exit_encode);
-
-static int upload_source_YUV_once_for_all()
-{
-    void *surface_p=NULL, *U_start,*V_start;
-    VAStatus va_status;
-    int box_width=8;
-    int row_shift=0;
-    int i;
-
-    for (i=0; i<SURFACE_NUM-2; i++) {
-        printf("\rLoading data into surface %d.....", i);
-#ifndef SURFACE_ATTRIB       
-        upload_surface(va_dpy, surface_id[i], box_width, row_shift, 0);
-#else
-        upload_surface_attrib(va_dpy, surface_id[i], box_width, row_shift, 0, (unsigned int *)vaSurfaceAttrib->buffers[i]);
-#endif
-        row_shift++;
-        if (row_shift==(2*box_width)) row_shift= 0;
-    }
-    printf("\n");
-
-    return 0;
-}
-
-
-static int save_coded_buf(VABufferID coded_buf, int current_frame, int frame_skipped)
-{    
-    void *coded_p=NULL;
-    VACodedBufferSegment *buf_list = NULL;
-    VAStatus va_status;
-    unsigned int coded_size = 0;
-
-    va_status = vaMapBuffer(va_dpy,coded_buf,(void **)(&buf_list));
-    CHECK_VASTATUS(va_status,"vaMapBuffer");
-    while (buf_list != NULL) {
-        printf("Write %d bytes", buf_list->size);
-        coded_size += write(coded_fd, buf_list->buf, buf_list->size);
-        buf_list = (VACodedBufferSegment *) buf_list->next;
-    }
-    vaUnmapBuffer(va_dpy,coded_buf);
-
-    printf("\r      "); /* return back to startpoint */
-    switch (current_frame % 4) {
-        case 0:
-            printf("|");
-            break;
-        case 1:
-            printf("/");
-            break;
-        case 2:
-            printf("-");
-            break;
-        case 3:
-            printf("\\");
-            break;
-    }
-    printf("%08d", current_frame);
-    if (current_frame % intra_count == 0)
-        printf("(I)");
-    else
-        printf("(P)");
-
-    printf("(%06d bytes coded)",coded_size);
-    if (frame_skipped)
-        printf("(SKipped)");
-    printf("                                    ");
-
-    return 0;
-}
-
-
-enum {
-    SH_LEVEL_1=10,
-    SH_LEVEL_1B=11,
-    SH_LEVEL_2=20,
-    SH_LEVEL_3=30,
-    SH_LEVEL_31=31,
-    SH_LEVEL_32=32,
-    SH_LEVEL_4=40,
-    SH_LEVEL_5=50
-};
-
-static int do_h264_encoding(void)
-{
-    VAEncPictureParameterBufferH264 pic_h264;
-    VAEncSliceParameterBuffer slice_h264;
-    VAStatus va_status;
-    VABufferID seq_param_buf, pic_param_buf, slice_param_buf;
-    int codedbuf_size;
-    VASurfaceStatus surface_status;
-    int src_surface, dst_surface, ref_surface;
-    int codedbuf_idx = 0;
-    int frame_skipped = 0;
-    int i;
-
-    /* upload RAW YUV data into all surfaces */
-    upload_source_YUV_once_for_all();
-
-    codedbuf_size = (frame_width * frame_height * 400) / (16*16);
-
-    for (i = 0; i < CODEDBUF_NUM; i++) {
-        /* create coded buffer once for all
-         * other VA buffers which won't be used again after vaRenderPicture.
-         * so APP can always vaCreateBuffer for every frame
-         * but coded buffer need to be mapped and accessed after vaRenderPicture/vaEndPicture
-         * so VA won't maintain the coded buffer
-         */
-        va_status = vaCreateBuffer(va_dpy,context_id,VAEncCodedBufferType,
-                codedbuf_size, 1, NULL, &coded_buf[i]);
-        CHECK_VASTATUS(va_status,"vaCreateBuffer");
-    }
-
-    src_surface = 0;
-    /* the last two frames are reference/reconstructed frame */
-    dst_surface = SURFACE_NUM - 1;
-    ref_surface = SURFACE_NUM - 2;
-
-    for (i = 0; i < frame_count; i++) {
-        va_status = vaBeginPicture(va_dpy, context_id, surface_id[src_surface]);
-        CHECK_VASTATUS(va_status,"vaBeginPicture");
-
-        if (i == 0) {
-            VAEncSequenceParameterBufferH264 seq_h264;
-            VAEncMiscParameterRateControl *rc_h264;
-            VAEncMiscParameterBuffer   *miscEncRCParamBuf;
-            VABufferID seq_param_buf, rc_param_buf;
-
-            va_status = vaCreateBuffer(va_dpy, context_id,
-                    VAEncMiscParameterBufferType,
-                    sizeof (VAEncMiscParameterBuffer) + sizeof (VAEncMiscParameterRateControl),
-                    1, NULL,
-                    &rc_param_buf);
-            CHECK_VASTATUS(va_status,"vaCreateBuffer");
-            va_status = vaMapBuffer(va_dpy, rc_param_buf, (void **)&miscEncRCParamBuf);
-            CHECK_VASTATUS(va_status,"vaMapBuffer");
-            miscEncRCParamBuf->type = VAEncMiscParameterTypeRateControl;
-            rc_h264 = (VAEncMiscParameterRateControl  *)miscEncRCParamBuf->data;               
-            rc_h264->initial_qp = initial_qp;
-            rc_h264->min_qp = minimal_qp;
-            rc_h264->window_size = 500;
-            rc_h264->basic_unit_size = 0;
-            va_status = vaUnmapBuffer(va_dpy, rc_param_buf);
-            CHECK_VASTATUS(va_status,"vaUnmapBuffer");
-            
-            seq_h264.level_idc = SH_LEVEL_3;
-            seq_h264.picture_width_in_mbs = frame_width / 16;
-            seq_h264.picture_height_in_mbs = frame_height / 16;
-            seq_h264.bits_per_second = frame_bitrate;
-            seq_h264.intra_period = intra_count;
-            va_status = vaCreateBuffer(va_dpy, context_id,
-                    VAEncSequenceParameterBufferType,
-                    sizeof(seq_h264),1,&seq_h264,&seq_param_buf);
-            CHECK_VASTATUS(va_status,"vaCreateBuffer");
-
-            va_status = vaRenderPicture(va_dpy,context_id, &rc_param_buf, 1);
-            CHECK_VASTATUS(va_status,"vaRenderPicture");;        
-            va_status = vaRenderPicture(va_dpy,context_id, &seq_param_buf, 1);
-            CHECK_VASTATUS(va_status,"vaRenderPicture");;
-        }
-
-
-        pic_h264.ReferenceFrames[0].picture_id= surface_id[ref_surface];
-        pic_h264.CurrPic.picture_id= surface_id[dst_surface];
-        pic_h264.coded_buf = coded_buf[codedbuf_idx];
-        pic_h264.last_picture = (i==frame_count);
-
-        va_status = vaCreateBuffer(va_dpy, context_id,VAEncPictureParameterBufferType,
-                sizeof(pic_h264),1,&pic_h264,&pic_param_buf);
-        CHECK_VASTATUS(va_status,"vaCreateBuffer");;
-
-        va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1);
-        CHECK_VASTATUS(va_status,"vaRenderPicture");
-
-        /* one frame, one slice */
-        slice_h264.start_row_number = 0;
-        slice_h264.slice_height = frame_height/16; /* Measured by MB */
-        slice_h264.slice_flags.bits.is_intra = ((i % intra_count) == 0);
-        slice_h264.slice_flags.bits.disable_deblocking_filter_idc = 0;
-        va_status = vaCreateBuffer(va_dpy,context_id,VAEncSliceParameterBufferType,
-                sizeof(slice_h264),1,&slice_h264,&slice_param_buf);
-        CHECK_VASTATUS(va_status,"vaCreateBuffer");;
-
-        va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1);
-        CHECK_VASTATUS(va_status,"vaRenderPicture");
-
-        va_status = vaEndPicture(va_dpy,context_id);
-        CHECK_VASTATUS(va_status,"vaEndPicture");;
-
-        va_status = vaSyncSurface(va_dpy, surface_id[src_surface]);
-        CHECK_VASTATUS(va_status,"vaSyncSurface");
-
-        surface_status = (VASurfaceStatus) 0;
-        va_status = vaQuerySurfaceStatus(va_dpy, surface_id[src_surface],&surface_status);
-        frame_skipped = (surface_status & VASurfaceSkipped);
-
-        save_coded_buf(coded_buf[codedbuf_idx], i, frame_skipped);
-#if 0        
-        /* should display reconstructed frame, but just diplay source frame */
-        if (frame_display) {
-            int exit_encode = 0;
-
-            display_surface(src_surface, &exit_encode);
-            if (exit_encode)
-                frame_count = i;
-        }
-#endif        
-        /* use next surface */
-        src_surface++;
-        if (src_surface == (SURFACE_NUM - 2))
-            src_surface = 0;
-
-        /* use next codedbuf */
-        codedbuf_idx++;
-        if (codedbuf_idx == (CODEDBUF_NUM - 1))
-            codedbuf_idx = 0;
-
-        /* if a frame is skipped, current frame still use last reference frame */
-        if (frame_skipped == 0) {
-            /* swap ref/dst */
-            int tmp = dst_surface;
-            dst_surface = ref_surface;
-            ref_surface = tmp;
-        } 
-    }
-
-    return 0;
-}
-
-int main(int argc,char **argv)
-{
-    VAEntrypoint entrypoints[5];
-    int num_entrypoints,slice_entrypoint;
-    VAConfigAttrib attrib[2];
-    VAConfigID config_id;
-    int major_ver, minor_ver;
-    VAStatus va_status;
-    char c;
-
-    strcpy(coded_file, "/sdcard/1.264");
-    while ((c =getopt(argc,argv,"w:h:n:p:f:r:q:s:o:d?") ) != EOF) {
-        switch (c) {
-            case 'w':
-                frame_width = atoi(optarg);
-                break;
-            case 'h':
-                frame_height = atoi(optarg);
-                break;
-            case 'n':
-                frame_count = atoi(optarg);
-                break;
-            case 'p':
-                intra_count = atoi(optarg);
-                break;
-            case 'f':
-                frame_rate = atoi(optarg);
-                break;
-            case 'b':
-                frame_bitrate = atoi(optarg);
-                break;
-            case 'q':
-                initial_qp = atoi(optarg);
-                break;
-            case 's':
-                minimal_qp = atoi(optarg);
-                break;
-            case 'd':
-                frame_display = 1;
-                break;
-            case 'o':
-                strcpy(coded_file, optarg);
-                break;
-            case ':':
-            case '?':
-                printf("./h264encode <options>\n");
-                printf("   -w -h: resolution\n");
-                printf("   -n frame number\n"); 
-                printf("   -d display the source frame\n");
-                printf("   -p P frame count between two I frames\n");
-                printf("   -f frame rate\n");
-                printf("   -r bit rate\n");
-                printf("   -q initial QP\n");
-                printf("   -s maximum QP\n");
-                printf("   -o coded file\n");
-                exit(0);
-        }
-    }
-
-#ifdef ANDROID
-    x11_display = (Display*)malloc(sizeof(Display));
-    *(x11_display) = 0x18c34078;
-#else
-    x11_display = XOpenDisplay(":0.0");
-#endif
-    assert(x11_display);
-
-    va_dpy = vaGetDisplay(x11_display);
-    va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
-    CHECK_VASTATUS(va_status, "vaInitialize");
-
-    vaQueryConfigEntrypoints(va_dpy, VAProfileH264Baseline, entrypoints, 
-            &num_entrypoints);
-    for	(slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) {
-        if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice)
-            break;
-    }
-    if (slice_entrypoint == num_entrypoints) {
-        /* not find Slice entry point */
-        assert(0);
-    }
-
-    /* find out the format for the render target, and rate control mode */
-    attrib[0].type = VAConfigAttribRTFormat;
-    attrib[1].type = VAConfigAttribRateControl;
-    vaGetConfigAttributes(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice,
-            &attrib[0], 2);
-    if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) {
-        /* not find desired YUV420 RT format */
-        assert(0);
-    }
-    if ((attrib[1].value & VA_RC_VBR) == 0) {
-        /* Can't find matched RC mode */
-        printf("VBR mode doesn't found, exit\n");
-        assert(0);
-    }
-    attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */
-    attrib[1].value = VA_RC_VBR; /* set to desired RC mode */
-
-    va_status = vaCreateConfig(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice,
-            &attrib[0], 2,&config_id);
-    CHECK_VASTATUS(va_status, "vaCreateConfig");
-
-#ifndef SURFACE_ATTRIB       
-    va_status = vaCreateSurfaces(
-            va_dpy,
-            VA_RT_FORMAT_YUV420, frame_width, frame_height,
-            &surface_id[0], SURFACE_NUM,
-            NULL, 0
-            );
-    CHECK_VASTATUS(va_status, "vaCreateSurfaces");
-#else
-    int index;
-    vaSurfaceAttrib = (VASurfaceAttributeTPI *)malloc(sizeof(VASurfaceAttributeTPI));
-    if (vaSurfaceAttrib == NULL) {
-        printf("Failed to allocate VASurfaceAttrib\n");
-        return -1;
-    }
-
-    vaSurfaceAttrib->buffers = (unsigned int *)malloc(SURFACE_NUM *sizeof(unsigned int));
-    if (vaSurfaceAttrib->buffers == NULL) {
-        printf("Failed to allocate buffers for vaSurfaceAttrib\n");
-        return -1;
-    }
-
-    vaSurfaceAttrib->count = SURFACE_NUM;
-    vaSurfaceAttrib->luma_stride = frame_width;
-    vaSurfaceAttrib->pixel_format = VA_FOURCC_NV12;
-    vaSurfaceAttrib->width = frame_width;
-    vaSurfaceAttrib->height = frame_height;
-    vaSurfaceAttrib->type = VAExternalMemoryUserPointer;
-    for(index = 0; index < SURFACE_NUM; index++) {
-        vaSurfaceAttrib->buffers[index] = (unsigned int)calloc(1, frame_width*frame_height*3/2); 
-    }
-        va_status = vaCreateSurfacesWithAttribute(
-                va_dpy,
-                frame_width,
-                frame_height,
-                VA_RT_FORMAT_YUV420,
-                SURFACE_NUM,
-                &surface_id[0],
-                vaSurfaceAttrib);
-        CHECK_VASTATUS(va_status, "vaCreateSurfacesWithAttribute");    
-#endif
-
-    /* Create a context for this decode pipe */
-    va_status = vaCreateContext(va_dpy, config_id,
-            frame_width, ((frame_height+15)/16)*16,
-            VA_PROGRESSIVE,&surface_id[0],SURFACE_NUM,&context_id);
-    CHECK_VASTATUS(va_status, "vaCreateContext");
-
-    /* store coded data into a file */
-    coded_fd = open(coded_file,O_CREAT|O_RDWR, 0);
-    if (coded_fd == -1) {
-        printf("Open file %s failed, exit\n", coded_file);
-        exit(1);
-    }
-
-    printf("Coded %d frames, %dx%d, save the coded file into %s\n",
-            frame_count, frame_width, frame_height, coded_file);
-    do_h264_encoding();
-
-    printf("\n\n");
-
-    vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM);
-    vaDestroyContext(va_dpy,context_id);
-    vaDestroyConfig(va_dpy,config_id);
-
-    vaTerminate(va_dpy);
-
-#ifdef ANDROID
-    free(x11_display);
-#else
-    XCloseDisplay(x11_display);
-#endif
-
-    return 0;
-}
diff --git a/test/encode/h264encode_x11.c b/test/encode/h264encode_x11.c
deleted file mode 100644
index 3f7aff2..0000000
--- a/test/encode/h264encode_x11.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * it is a real program to show how VAAPI encoding work,
- * It does H264 element stream level encoding on auto-generated YUV data
- *
- * gcc -o  h264encode  h264encode -lva -lva-x11
- * ./h264encode -w <width> -h <height> -n <frame_num>
- *
- */  
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <va/va.h>
-#include <X11/Xlib.h>
-#include <va/va_x11.h>
-
-#define SURFACE_NUM 18 /* 16 surfaces for src, 2 surface for reconstructed/reference */
-
-static  Display *x11_display;
-static  VADisplay va_dpy;
-static  VASurfaceID surface_id[SURFACE_NUM];
-static  Window display_win = 0;
-static  int win_width;
-static  int win_height;
-
-static int display_surface(int frame_id, int *exit_encode);
-
-#include "h264encode_common.c"
-
-
-static int display_surface(int frame_id, int *exit_encode)
-{
-    Window win = display_win;
-    XEvent event;
-    VAStatus va_status;
-    
-    if (win == 0) { /* display reconstructed surface */
-        win_width = frame_width;
-        win_height = frame_height;
-        
-        win = XCreateSimpleWindow(x11_display, RootWindow(x11_display, 0), 0, 0,
-                                  frame_width, frame_height, 0, 0, WhitePixel(x11_display, 0));
-        XMapWindow(x11_display, win);
-        XSync(x11_display, False);
-
-        display_win = win;
-    }
-
-    va_status = vaPutSurface(va_dpy, surface_id[frame_id], win,
-                             0,0, frame_width, frame_height,
-                             0,0, win_width, win_height,
-                             NULL,0,0);
-
-    *exit_encode = 0;
-    while(XPending(x11_display)) {
-        XNextEvent(x11_display, &event);
-            
-        /* bail on any focused key press */
-        if(event.type == KeyPress) {  
-            *exit_encode = 1;
-            break;
-        }
-            
-        /* rescale the video to fit the window */
-        if(event.type == ConfigureNotify) { 
-            win_width = event.xconfigure.width;
-            win_height = event.xconfigure.height;
-        }	
-    }	
-
-    return 0;
-}
-
diff --git a/test/encode/mpeg2enc.c b/test/encode/mpeg2enc.c
new file mode 100644
index 0000000..4e1776d
--- /dev/null
+++ b/test/encode/mpeg2enc.c
@@ -0,0 +1,1529 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Simple MPEG-2 encoder based on libVA.
+ *
+ */  
+
+#include "sysdeps.h"
+
+#include <getopt.h>
+#include <unistd.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <pthread.h>
+
+#include <va/va.h>
+#include <va/va_enc_mpeg2.h>
+
+#include "va_display.h"
+
+#define START_CODE_PICUTRE      0x00000100
+#define START_CODE_SLICE        0x00000101
+#define START_CODE_USER         0x000001B2
+#define START_CODE_SEQ          0x000001B3
+#define START_CODE_EXT          0x000001B5
+#define START_CODE_GOP          0x000001B8
+
+#define CHROMA_FORMAT_RESERVED  0
+#define CHROMA_FORMAT_420       1
+#define CHROMA_FORMAT_422       2
+#define CHROMA_FORMAT_444       3
+
+#define MAX_SLICES              128
+
+enum {
+    MPEG2_MODE_I = 0,
+    MPEG2_MODE_IP,
+    MPEG2_MODE_IPB,
+};
+
+enum {
+    MPEG2_LEVEL_LOW = 0,
+    MPEG2_LEVEL_MAIN,
+    MPEG2_LEVEL_HIGH,
+};
+
+#define CHECK_VASTATUS(va_status, func)                                 \
+    if (va_status != VA_STATUS_SUCCESS) {                               \
+        fprintf(stderr, "%s:%s (%d) failed, exit\n", __func__, func, __LINE__); \
+        exit(1);                                                        \
+    }
+
+static VAProfile mpeg2_va_profiles[] = {
+    VAProfileMPEG2Simple,
+    VAProfileMPEG2Main
+};
+
+static struct _mpeg2_sampling_density
+{
+    int samplers_per_line;
+    int line_per_frame;
+    int frame_per_sec;
+} mpeg2_upper_samplings[2][3] = {
+    { { 0, 0, 0 },
+      { 720, 576, 30 },
+      { 0, 0, 0 },
+    },
+
+    { { 352, 288, 30 },
+      { 720, 576, 30 },
+      { 1920, 1152, 60 },
+    }
+};
+
+struct mpeg2enc_context {
+    /* args */
+    int rate_control_mode;
+    int fps;
+    int mode; /* 0:I, 1:I/P, 2:I/P/B */
+    VAProfile profile;
+    int level;
+    int width;
+    int height;
+    int frame_size;
+    int num_pictures;
+    int qp;
+    FILE *ifp;
+    FILE *ofp;
+    unsigned char *frame_data_buffer;
+    int intra_period;
+    int ip_period;
+    int bit_rate; /* in kbps */
+    VAEncPictureType next_type;
+    int next_display_order;
+    int next_bframes;
+    int new_sequence;
+    int new_gop_header;
+    int gop_header_in_display_order;
+
+    /* VA resource */
+    VADisplay va_dpy;
+    VAEncSequenceParameterBufferMPEG2 seq_param;
+    VAEncPictureParameterBufferMPEG2 pic_param;
+    VAEncSliceParameterBufferMPEG2 slice_param[MAX_SLICES];
+    VAContextID context_id;
+    VAConfigID config_id;
+    VABufferID seq_param_buf_id;                /* Sequence level parameter */
+    VABufferID pic_param_buf_id;                /* Picture level parameter */
+    VABufferID slice_param_buf_id[MAX_SLICES];  /* Slice level parameter, multil slices */
+    VABufferID codedbuf_buf_id;                 /* Output buffer, compressed data */
+    VABufferID packed_seq_header_param_buf_id;
+    VABufferID packed_seq_buf_id;
+    VABufferID packed_pic_header_param_buf_id;
+    VABufferID packed_pic_buf_id;
+    int num_slice_groups;
+    int codedbuf_i_size;
+    int codedbuf_pb_size;
+
+    /* thread */
+    pthread_t upload_thread_id;
+    int upload_thread_value;
+    int current_input_surface;
+    int current_upload_surface;
+};
+
+/*
+ * mpeg2enc helpers
+ */
+#define BITSTREAM_ALLOCATE_STEPPING     4096
+
+struct __bitstream {
+    unsigned int *buffer;
+    int bit_offset;
+    int max_size_in_dword;
+};
+
+typedef struct __bitstream bitstream;
+
+static unsigned int 
+swap32(unsigned int val)
+{
+    unsigned char *pval = (unsigned char *)&val;
+
+    return ((pval[0] << 24)     |
+            (pval[1] << 16)     |
+            (pval[2] << 8)      |
+            (pval[3] << 0));
+}
+
+static void
+bitstream_start(bitstream *bs)
+{
+    bs->max_size_in_dword = BITSTREAM_ALLOCATE_STEPPING;
+    bs->buffer = calloc(bs->max_size_in_dword * sizeof(int), 1);
+    bs->bit_offset = 0;
+}
+
+static void
+bitstream_end(bitstream *bs)
+{
+    int pos = (bs->bit_offset >> 5);
+    int bit_offset = (bs->bit_offset & 0x1f);
+    int bit_left = 32 - bit_offset;
+
+    if (bit_offset) {
+        bs->buffer[pos] = swap32((bs->buffer[pos] << bit_left));
+    }
+}
+ 
+static void
+bitstream_put_ui(bitstream *bs, unsigned int val, int size_in_bits)
+{
+    int pos = (bs->bit_offset >> 5);
+    int bit_offset = (bs->bit_offset & 0x1f);
+    int bit_left = 32 - bit_offset;
+
+    if (!size_in_bits)
+        return;
+
+    if (size_in_bits < 32)
+        val &= ((1 << size_in_bits) - 1);
+
+    bs->bit_offset += size_in_bits;
+
+    if (bit_left > size_in_bits) {
+        bs->buffer[pos] = (bs->buffer[pos] << size_in_bits | val);
+    } else {
+        size_in_bits -= bit_left;
+        bs->buffer[pos] = (bs->buffer[pos] << bit_left) | (val >> size_in_bits);
+        bs->buffer[pos] = swap32(bs->buffer[pos]);
+
+        if (pos + 1 == bs->max_size_in_dword) {
+            bs->max_size_in_dword += BITSTREAM_ALLOCATE_STEPPING;
+            bs->buffer = realloc(bs->buffer, bs->max_size_in_dword * sizeof(unsigned int));
+        }
+
+        bs->buffer[pos + 1] = val;
+    }
+}
+
+static void
+bitstream_byte_aligning(bitstream *bs, int bit)
+{
+    int bit_offset = (bs->bit_offset & 0x7);
+    int bit_left = 8 - bit_offset;
+    int new_val;
+
+    if (!bit_offset)
+        return;
+
+    assert(bit == 0 || bit == 1);
+
+    if (bit)
+        new_val = (1 << bit_left) - 1;
+    else
+        new_val = 0;
+
+    bitstream_put_ui(bs, new_val, bit_left);
+}
+
+static struct mpeg2_frame_rate {
+    int code;
+    float value;
+} frame_rate_tab[] = {
+    {1, 23.976},
+    {2, 24.0},
+    {3, 25.0},
+    {4, 29.97},
+    {5, 30},
+    {6, 50},
+    {7, 59.94},
+    {8, 60}
+};
+
+static int
+find_frame_rate_code(const VAEncSequenceParameterBufferMPEG2 *seq_param)
+{
+    unsigned int delta = -1;
+    int code = 1, i;
+    float frame_rate_value = seq_param->frame_rate * 
+        (seq_param->sequence_extension.bits.frame_rate_extension_d + 1) / 
+        (seq_param->sequence_extension.bits.frame_rate_extension_n + 1);
+
+    for (i = 0; i < sizeof(frame_rate_tab) / sizeof(frame_rate_tab[0]); i++) {
+
+        if (abs(1000 * frame_rate_tab[i].value - 1000 * frame_rate_value) < delta) {
+            code = frame_rate_tab[i].code;
+            delta = abs(1000 * frame_rate_tab[i].value - 1000 * frame_rate_value);
+        }
+    }
+
+    return code;
+}
+
+static void 
+sps_rbsp(struct mpeg2enc_context *ctx,
+         const VAEncSequenceParameterBufferMPEG2 *seq_param,
+         bitstream *bs)
+{
+    int frame_rate_code = find_frame_rate_code(seq_param);
+
+    if (ctx->new_sequence) {
+        bitstream_put_ui(bs, START_CODE_SEQ, 32);
+        bitstream_put_ui(bs, seq_param->picture_width, 12);
+        bitstream_put_ui(bs, seq_param->picture_height, 12);
+        bitstream_put_ui(bs, seq_param->aspect_ratio_information, 4);
+        bitstream_put_ui(bs, frame_rate_code, 4); /* frame_rate_code */
+        bitstream_put_ui(bs, (seq_param->bits_per_second + 399) / 400, 18); /* the low 18 bits of bit_rate */
+        bitstream_put_ui(bs, 1, 1); /* marker_bit */
+        bitstream_put_ui(bs, seq_param->vbv_buffer_size, 10);
+        bitstream_put_ui(bs, 0, 1); /* constraint_parameter_flag, always 0 for MPEG-2 */
+        bitstream_put_ui(bs, 0, 1); /* load_intra_quantiser_matrix */
+        bitstream_put_ui(bs, 0, 1); /* load_non_intra_quantiser_matrix */
+
+        bitstream_byte_aligning(bs, 0);
+
+        bitstream_put_ui(bs, START_CODE_EXT, 32);
+        bitstream_put_ui(bs, 1, 4); /* sequence_extension id */
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.profile_and_level_indication, 8);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.progressive_sequence, 1);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.chroma_format, 2);
+        bitstream_put_ui(bs, seq_param->picture_width >> 12, 2);
+        bitstream_put_ui(bs, seq_param->picture_height >> 12, 2);
+        bitstream_put_ui(bs, ((seq_param->bits_per_second + 399) / 400) >> 18, 12); /* bit_rate_extension */
+        bitstream_put_ui(bs, 1, 1); /* marker_bit */
+        bitstream_put_ui(bs, seq_param->vbv_buffer_size >> 10, 8);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.low_delay, 1);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.frame_rate_extension_n, 2);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.frame_rate_extension_d, 5);
+
+        bitstream_byte_aligning(bs, 0);
+    }
+
+    if (ctx->new_gop_header) {
+        bitstream_put_ui(bs, START_CODE_GOP, 32);
+        bitstream_put_ui(bs, seq_param->gop_header.bits.time_code, 25);
+        bitstream_put_ui(bs, seq_param->gop_header.bits.closed_gop, 1);
+        bitstream_put_ui(bs, seq_param->gop_header.bits.broken_link, 1);
+
+        bitstream_byte_aligning(bs, 0);
+    }
+}
+
+static void 
+pps_rbsp(const VAEncSequenceParameterBufferMPEG2 *seq_param,
+         const VAEncPictureParameterBufferMPEG2 *pic_param,
+         bitstream *bs)
+{
+    int chroma_420_type;
+
+    if (seq_param->sequence_extension.bits.chroma_format == CHROMA_FORMAT_420)
+        chroma_420_type = pic_param->picture_coding_extension.bits.progressive_frame;
+    else
+        chroma_420_type = 0;
+
+    bitstream_put_ui(bs, START_CODE_PICUTRE, 32);
+    bitstream_put_ui(bs, pic_param->temporal_reference, 10);
+    bitstream_put_ui(bs,
+                     pic_param->picture_type == VAEncPictureTypeIntra ? 1 :
+                     pic_param->picture_type == VAEncPictureTypePredictive ? 2 : 3,
+                     3);
+    bitstream_put_ui(bs, 0xFFFF, 16); /* vbv_delay, always 0xFFFF */
+    
+    if (pic_param->picture_type == VAEncPictureTypePredictive ||
+        pic_param->picture_type == VAEncPictureTypeBidirectional) {
+        bitstream_put_ui(bs, 0, 1); /* full_pel_forward_vector, always 0 for MPEG-2 */
+        bitstream_put_ui(bs, 7, 3); /* forward_f_code, always 7 for MPEG-2 */
+    }
+
+    if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
+        bitstream_put_ui(bs, 0, 1); /* full_pel_backward_vector, always 0 for MPEG-2 */
+        bitstream_put_ui(bs, 7, 3); /* backward_f_code, always 7 for MPEG-2 */
+    }
+     
+    bitstream_put_ui(bs, 0, 1); /* extra_bit_picture, 0 */
+
+    bitstream_byte_aligning(bs, 0);
+
+    bitstream_put_ui(bs, START_CODE_EXT, 32);
+    bitstream_put_ui(bs, 8, 4); /* Picture Coding Extension ID: 8 */
+    bitstream_put_ui(bs, pic_param->f_code[0][0], 4);
+    bitstream_put_ui(bs, pic_param->f_code[0][1], 4);
+    bitstream_put_ui(bs, pic_param->f_code[1][0], 4);
+    bitstream_put_ui(bs, pic_param->f_code[1][1], 4);
+
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.intra_dc_precision, 2);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.picture_structure, 2);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.top_field_first, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.frame_pred_frame_dct, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.concealment_motion_vectors, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.q_scale_type, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.intra_vlc_format, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.alternate_scan, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.repeat_first_field, 1);
+    bitstream_put_ui(bs, chroma_420_type, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.progressive_frame, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.composite_display_flag, 1);
+
+    bitstream_byte_aligning(bs, 0);
+}
+
+static int
+build_packed_pic_buffer(const VAEncSequenceParameterBufferMPEG2 *seq_param,
+                        const VAEncPictureParameterBufferMPEG2 *pic_param,
+                        unsigned char **header_buffer)
+{
+    bitstream bs;
+
+    bitstream_start(&bs);
+    pps_rbsp(seq_param, pic_param, &bs);
+    bitstream_end(&bs);
+
+    *header_buffer = (unsigned char *)bs.buffer;
+    return bs.bit_offset;
+}
+
+static int
+build_packed_seq_buffer(struct mpeg2enc_context *ctx,
+                        const VAEncSequenceParameterBufferMPEG2 *seq_param,
+                        unsigned char **header_buffer)
+{
+    bitstream bs;
+
+    bitstream_start(&bs);
+    sps_rbsp(ctx, seq_param, &bs);
+    bitstream_end(&bs);
+
+    *header_buffer = (unsigned char *)bs.buffer;
+    return bs.bit_offset;
+}
+
+/*
+ * mpeg2enc
+ */
+#define SID_INPUT_PICTURE_0                     0
+#define SID_INPUT_PICTURE_1                     1
+#define SID_REFERENCE_PICTURE_L0                2
+#define SID_REFERENCE_PICTURE_L1                3
+#define SID_RECON_PICTURE                       4
+#define SID_NUMBER                              SID_RECON_PICTURE + 1
+
+static VASurfaceID surface_ids[SID_NUMBER];
+
+/*
+ * upload thread function
+ */
+static void *
+upload_yuv_to_surface(void *data)
+{
+    struct mpeg2enc_context *ctx = data;
+    VAImage surface_image;
+    VAStatus va_status;
+    void *surface_p = NULL;
+    unsigned char *y_src, *u_src, *v_src;
+    unsigned char *y_dst, *u_dst, *v_dst;
+    int y_size = ctx->width * ctx->height;
+    int u_size = (ctx->width >> 1) * (ctx->height >> 1);
+    int row, col;
+    size_t n_items;
+
+    do {
+        n_items = fread(ctx->frame_data_buffer, ctx->frame_size, 1, ctx->ifp);
+    } while (n_items != 1);
+
+    va_status = vaDeriveImage(ctx->va_dpy, surface_ids[ctx->current_upload_surface], &surface_image);
+    CHECK_VASTATUS(va_status,"vaDeriveImage");
+
+    vaMapBuffer(ctx->va_dpy, surface_image.buf, &surface_p);
+    assert(VA_STATUS_SUCCESS == va_status);
+        
+    y_src = ctx->frame_data_buffer;
+    u_src = ctx->frame_data_buffer + y_size; /* UV offset for NV12 */
+    v_src = ctx->frame_data_buffer + y_size + u_size;
+
+    y_dst = surface_p + surface_image.offsets[0];
+    u_dst = surface_p + surface_image.offsets[1]; /* UV offset for NV12 */
+    v_dst = surface_p + surface_image.offsets[2];
+
+    /* Y plane */
+    for (row = 0; row < surface_image.height; row++) {
+        memcpy(y_dst, y_src, surface_image.width);
+        y_dst += surface_image.pitches[0];
+        y_src += ctx->width;
+    }
+
+    if (surface_image.format.fourcc == VA_FOURCC_NV12) { /* UV plane */
+        for (row = 0; row < surface_image.height / 2; row++) {
+            for (col = 0; col < surface_image.width / 2; col++) {
+                u_dst[col * 2] = u_src[col];
+                u_dst[col * 2 + 1] = v_src[col];
+            }
+
+            u_dst += surface_image.pitches[1];
+            u_src += (ctx->width / 2);
+            v_src += (ctx->width / 2);
+        }
+    } else {
+        for (row = 0; row < surface_image.height / 2; row++) {
+            for (col = 0; col < surface_image.width / 2; col++) {
+                u_dst[col] = u_src[col];
+                v_dst[col] = v_src[col];
+            }
+
+            u_dst += surface_image.pitches[1];
+            v_dst += surface_image.pitches[2];
+            u_src += (ctx->width / 2);
+            v_src += (ctx->width / 2);
+        }
+    }
+
+    vaUnmapBuffer(ctx->va_dpy, surface_image.buf);
+    vaDestroyImage(ctx->va_dpy, surface_image.image_id);
+
+    return NULL;
+}
+
+static void 
+mpeg2enc_exit(struct mpeg2enc_context *ctx, int exit_code)
+{
+    if (ctx->frame_data_buffer) {
+        free(ctx->frame_data_buffer);
+        ctx->frame_data_buffer = NULL;
+    }
+
+    if (ctx->ifp) {
+        fclose(ctx->ifp);
+        ctx->ifp = NULL;
+    }
+
+    if (ctx->ofp) {
+        fclose(ctx->ofp);
+        ctx->ofp = NULL;
+    }
+
+    exit(exit_code);
+}
+
+static void 
+usage(char *program)
+{   
+    fprintf(stderr, "Usage: %s --help\n", program);
+    fprintf(stderr, "\t--help   print this message\n");
+    fprintf(stderr, "Usage: %s <width> <height> <ifile> <ofile> [options]\n", program);
+    fprintf(stderr, "\t<width>  specifies the frame width\n");
+    fprintf(stderr, "\t<height> specifies the frame height\n");
+    fprintf(stderr, "\t<ifile>  specifies the I420/IYUV YUV file\n");
+    fprintf(stderr, "\t<ofile>  specifies the encoded MPEG-2 file\n");
+    fprintf(stderr, "where options include:\n");
+    fprintf(stderr, "\t--cqp <QP>       const qp mode with specified <QP>\n");
+    fprintf(stderr, "\t--fps <FPS>      specify the frame rate\n");
+    fprintf(stderr, "\t--mode <MODE>    specify the mode 0 (I), 1 (I/P) and 2 (I/P/B)\n");
+    fprintf(stderr, "\t--profile <PROFILE>      specify the profile 0(Simple), or 1(Main, default)\n");
+    fprintf(stderr, "\t--level <LEVEL>  specify the level 0(Low), 1(Main, default) or 2(High)\n");    
+}
+
+void
+mpeg2_profile_level(struct mpeg2enc_context *ctx,
+                    int profile,
+                    int level)
+{
+    int l = 2, p;
+
+    for (p = profile; p < 2; p++) {
+        for (l = level; l < 3; l++) {
+            if (ctx->width <= mpeg2_upper_samplings[p][l].samplers_per_line &&
+                ctx->height <= mpeg2_upper_samplings[p][l].line_per_frame &&
+                ctx->fps <= mpeg2_upper_samplings[p][l].frame_per_sec) {
+                
+                goto __find;
+                break;
+            }
+        }
+    }
+
+    if (p == 2) {
+        fprintf(stderr, "Warning: can't find a proper profile and level for the specified width/height/fps\n");
+        p = 1;
+        l = 2;
+    }
+
+__find:    
+    ctx->profile = mpeg2_va_profiles[p];
+    ctx->level = l;
+}
+
+static void 
+parse_args(struct mpeg2enc_context *ctx, int argc, char **argv)
+{
+    int c, tmp;
+    int option_index = 0;
+    long file_size;
+    int profile = 1, level = 1;
+
+    static struct option long_options[] = {
+        {"help",        no_argument,            0,      'h'},
+        {"cqp",         required_argument,      0,      'c'},
+        {"fps",         required_argument,      0,      'f'},
+        {"mode",        required_argument,      0,      'm'},
+        {"profile",     required_argument,      0,      'p'},
+        {"level",       required_argument,      0,      'l'},
+        { NULL,         0,                      NULL,   0 }
+    };
+
+    if ((argc == 2 && strcmp(argv[1], "--help") == 0) ||
+        (argc < 5))
+        goto print_usage;
+
+    ctx->width = atoi(argv[1]);
+    ctx->height = atoi(argv[2]);
+
+    if (ctx->width <= 0 || ctx->height <= 0) {
+        fprintf(stderr, "<width> and <height> must be greater than 0\n");
+        goto err_exit;
+    }
+
+    ctx->ifp = fopen(argv[3], "rb");
+
+    if (ctx->ifp == NULL) {
+        fprintf(stderr, "Can't open the input file\n");
+        goto err_exit;
+    }
+
+    fseek(ctx->ifp, 0l, SEEK_END);
+    file_size = ftell(ctx->ifp);
+    ctx->frame_size = ctx->width * ctx->height * 3 / 2;
+
+    if ((file_size < ctx->frame_size) ||
+        (file_size % ctx->frame_size)) {
+        fprintf(stderr, "The input file size %ld isn't a multiple of the frame size %d\n", file_size, ctx->frame_size);
+        goto err_exit;
+    }
+
+    ctx->num_pictures = file_size / ctx->frame_size;
+    fseek(ctx->ifp, 0l, SEEK_SET);
+    
+    ctx->ofp = fopen(argv[4], "wb");
+    
+    if (ctx->ofp == NULL) {
+        fprintf(stderr, "Can't create the output file\n");
+        goto err_exit;
+    }
+
+    opterr = 0;
+    ctx->fps = 30;
+    ctx->qp = 8;
+    ctx->rate_control_mode = VA_RC_CQP;
+    ctx->mode = MPEG2_MODE_IP;
+    ctx->profile = VAProfileMPEG2Main;
+    ctx->level = MPEG2_LEVEL_MAIN;
+
+    optind = 5;
+
+    while((c = getopt_long(argc, argv,
+                           "",
+                           long_options, 
+                           &option_index)) != -1) {
+        switch(c) {
+        case 'c':
+            tmp = atoi(optarg);
+
+            /* only support q_scale_type = 0 */
+            if (tmp > 62 || tmp < 2) {
+                fprintf(stderr, "Warning: QP must be in [2, 62]\n");
+
+                if (tmp > 62)
+                    tmp = 62;
+
+                if (tmp < 2)
+                    tmp = 2;
+            }
+
+            ctx->qp = tmp & 0xFE;
+            ctx->rate_control_mode = VA_RC_CQP;
+
+            break;
+
+        case 'f':
+            tmp = atoi(optarg);
+
+            if (tmp <= 0)
+                fprintf(stderr, "Warning: FPS must be greater than 0\n");
+            else
+                ctx->fps = tmp;
+
+            ctx->rate_control_mode = VA_RC_CBR;
+
+            break;
+
+        case 'm':
+            tmp = atoi(optarg);
+            
+            if (tmp < MPEG2_MODE_I || tmp > MPEG2_MODE_IPB)
+                fprintf(stderr, "Waning: MODE must be 0, 1, or 2\n");
+            else
+                ctx->mode = tmp;
+
+            break;
+
+        case 'p':
+            tmp = atoi(optarg);
+            
+            if (tmp < 0 || tmp > 1)
+                fprintf(stderr, "Waning: PROFILE must be 0 or 1\n");
+            else
+                profile = tmp;
+
+            break;
+
+        case 'l':
+            tmp = atoi(optarg);
+            
+            if (tmp < MPEG2_LEVEL_LOW || tmp > MPEG2_LEVEL_HIGH)
+                fprintf(stderr, "Waning: LEVEL must be 0, 1, or 2\n");
+            else
+                level = tmp;
+
+            break;
+
+        case '?':
+            fprintf(stderr, "Error: unkown command options\n");
+
+        case 'h':
+            goto print_usage;
+        }
+    }
+
+    mpeg2_profile_level(ctx, profile, level);
+
+    return;
+
+print_usage:    
+    usage(argv[0]);
+err_exit:
+    mpeg2enc_exit(ctx, 1);
+}
+
+/*
+ * init
+ */
+void
+mpeg2enc_init_sequence_parameter(struct mpeg2enc_context *ctx,
+                                VAEncSequenceParameterBufferMPEG2 *seq_param)
+{
+    int profile = 4, level = 8;
+
+    switch (ctx->profile) {
+    case VAProfileMPEG2Simple:
+        profile = 5;
+        break;
+
+    case VAProfileMPEG2Main:
+        profile = 4;
+        break;
+
+    default:
+        assert(0);
+        break;
+    }
+
+    switch (ctx->level) {
+    case MPEG2_LEVEL_LOW:
+        level = 10;
+        break;
+
+    case MPEG2_LEVEL_MAIN:
+        level = 8;
+        break;
+
+    case MPEG2_LEVEL_HIGH:
+        level = 4;
+        break;
+
+    default:
+        assert(0);
+        break;
+    }
+        
+    seq_param->intra_period = ctx->intra_period;
+    seq_param->ip_period = ctx->ip_period;   /* FIXME: ??? */
+    seq_param->picture_width = ctx->width;
+    seq_param->picture_height = ctx->height;
+
+    if (ctx->bit_rate > 0)
+        seq_param->bits_per_second = 1024 * ctx->bit_rate; /* use kbps as input */
+    else
+        seq_param->bits_per_second = 0x3FFFF * 400;
+
+    seq_param->frame_rate = ctx->fps;
+    seq_param->aspect_ratio_information = 1;
+    seq_param->vbv_buffer_size = 3; /* B = 16 * 1024 * vbv_buffer_size */
+
+    seq_param->sequence_extension.bits.profile_and_level_indication = profile << 4 | level;
+    seq_param->sequence_extension.bits.progressive_sequence = 1; /* progressive frame-pictures */
+    seq_param->sequence_extension.bits.chroma_format = CHROMA_FORMAT_420; /* 4:2:0 */
+    seq_param->sequence_extension.bits.low_delay = 0; /* FIXME */
+    seq_param->sequence_extension.bits.frame_rate_extension_n = 0;
+    seq_param->sequence_extension.bits.frame_rate_extension_d = 0;
+
+    seq_param->gop_header.bits.time_code = (1 << 12); /* bit12: marker_bit */
+    seq_param->gop_header.bits.closed_gop = 0;
+    seq_param->gop_header.bits.broken_link = 0;    
+}
+
+static void
+mpeg2enc_init_picture_parameter(struct mpeg2enc_context *ctx,
+                               VAEncPictureParameterBufferMPEG2 *pic_param)
+{
+    pic_param->forward_reference_picture = VA_INVALID_ID;
+    pic_param->backward_reference_picture = VA_INVALID_ID;
+    pic_param->reconstructed_picture = VA_INVALID_ID;
+    pic_param->coded_buf = VA_INVALID_ID;
+    pic_param->picture_type = VAEncPictureTypeIntra;
+
+    pic_param->temporal_reference = 0;
+    pic_param->f_code[0][0] = 0xf;
+    pic_param->f_code[0][1] = 0xf;
+    pic_param->f_code[1][0] = 0xf;
+    pic_param->f_code[1][1] = 0xf;
+
+    pic_param->picture_coding_extension.bits.intra_dc_precision = 0; /* 8bits */
+    pic_param->picture_coding_extension.bits.picture_structure = 3; /* frame picture */
+    pic_param->picture_coding_extension.bits.top_field_first = 0; 
+    pic_param->picture_coding_extension.bits.frame_pred_frame_dct = 1; /* FIXME */
+    pic_param->picture_coding_extension.bits.concealment_motion_vectors = 0;
+    pic_param->picture_coding_extension.bits.q_scale_type = 0;
+    pic_param->picture_coding_extension.bits.intra_vlc_format = 0;
+    pic_param->picture_coding_extension.bits.alternate_scan = 0;
+    pic_param->picture_coding_extension.bits.repeat_first_field = 0;
+    pic_param->picture_coding_extension.bits.progressive_frame = 1;
+    pic_param->picture_coding_extension.bits.composite_display_flag = 0;
+}
+
+static void 
+mpeg2enc_alloc_va_resources(struct mpeg2enc_context *ctx)
+{
+    VAEntrypoint *entrypoint_list;
+    VAConfigAttrib attrib_list[2];
+    VAStatus va_status;
+    int max_entrypoints, num_entrypoints, entrypoint;
+    int major_ver, minor_ver;
+
+    ctx->va_dpy = va_open_display();
+    va_status = vaInitialize(ctx->va_dpy,
+                             &major_ver,
+                             &minor_ver);
+    CHECK_VASTATUS(va_status, "vaInitialize");
+
+    max_entrypoints = vaMaxNumEntrypoints(ctx->va_dpy);
+    entrypoint_list = malloc(max_entrypoints * sizeof(VAEntrypoint));
+    vaQueryConfigEntrypoints(ctx->va_dpy,
+                             ctx->profile,
+                             entrypoint_list,
+                             &num_entrypoints);
+
+    for	(entrypoint = 0; entrypoint < num_entrypoints; entrypoint++) {
+        if (entrypoint_list[entrypoint] == VAEntrypointEncSlice)
+            break;
+    }
+
+    free(entrypoint_list);
+
+    if (entrypoint == num_entrypoints) {
+        /* not find Slice entry point */
+        assert(0);
+    }
+
+    /* find out the format for the render target, and rate control mode */
+    attrib_list[0].type = VAConfigAttribRTFormat;
+    attrib_list[1].type = VAConfigAttribRateControl;
+    vaGetConfigAttributes(ctx->va_dpy,
+                          ctx->profile,
+                          VAEntrypointEncSlice,
+                          &attrib_list[0],
+                          2);
+
+    if ((attrib_list[0].value & VA_RT_FORMAT_YUV420) == 0) {
+        /* not find desired YUV420 RT format */
+        assert(0);
+    }
+
+    if ((attrib_list[1].value & ctx->rate_control_mode) == 0) {
+        /* Can't find matched RC mode */
+        fprintf(stderr, "RC mode %d isn't found, exit\n", ctx->rate_control_mode);
+        assert(0);
+    }
+
+    attrib_list[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */
+    attrib_list[1].value = ctx->rate_control_mode; /* set to desired RC mode */
+
+    va_status = vaCreateConfig(ctx->va_dpy,
+                               ctx->profile,
+                               VAEntrypointEncSlice,
+                               attrib_list,
+                               2,
+                               &ctx->config_id);
+    CHECK_VASTATUS(va_status, "vaCreateConfig");
+
+    /* Create a context for this decode pipe */
+    va_status = vaCreateContext(ctx->va_dpy,
+                                ctx->config_id,
+                                ctx->width,
+                                ctx->height,
+                                VA_PROGRESSIVE, 
+                                0,
+                                0,
+                                &ctx->context_id);
+    CHECK_VASTATUS(va_status, "vaCreateContext");
+
+    va_status = vaCreateSurfaces(ctx->va_dpy,
+                                 VA_RT_FORMAT_YUV420,
+                                 ctx->width,
+                                 ctx->height,
+                                 surface_ids,
+                                 SID_NUMBER,
+                                 NULL,
+                                 0);
+    CHECK_VASTATUS(va_status, "vaCreateSurfaces");
+}
+
+static void 
+mpeg2enc_init(struct mpeg2enc_context *ctx)
+{
+    int i;
+
+    ctx->frame_data_buffer = (unsigned char *)malloc(ctx->frame_size);
+    ctx->seq_param_buf_id = VA_INVALID_ID;
+    ctx->pic_param_buf_id = VA_INVALID_ID;
+    ctx->packed_seq_header_param_buf_id = VA_INVALID_ID;
+    ctx->packed_seq_buf_id = VA_INVALID_ID;
+    ctx->packed_pic_header_param_buf_id = VA_INVALID_ID;
+    ctx->packed_pic_buf_id = VA_INVALID_ID;
+    ctx->codedbuf_buf_id = VA_INVALID_ID;
+    ctx->codedbuf_i_size = ctx->frame_size;
+    ctx->codedbuf_pb_size = 0;
+    ctx->next_display_order = 0;
+    ctx->next_type = VAEncPictureTypeIntra;
+
+    if (ctx->mode == MPEG2_MODE_I) {
+        ctx->intra_period = 1;
+        ctx->ip_period = 0;
+    } else if (ctx->mode == MPEG2_MODE_IP) {
+        ctx->intra_period = 16;
+        ctx->ip_period = 0;
+    } else {
+        ctx->intra_period = 16;
+        ctx->ip_period = 2;
+    }
+
+    ctx->next_bframes = ctx->ip_period;
+
+    ctx->new_sequence = 1;
+    ctx->new_gop_header = 1;
+    ctx->gop_header_in_display_order = 0;
+
+    ctx->bit_rate = -1;
+
+    for (i = 0; i < MAX_SLICES; i++) {
+        ctx->slice_param_buf_id[i] = VA_INVALID_ID;
+    }
+
+    mpeg2enc_init_sequence_parameter(ctx, &ctx->seq_param);
+    mpeg2enc_init_picture_parameter(ctx, &ctx->pic_param);
+    mpeg2enc_alloc_va_resources(ctx);
+
+    /* thread */
+    ctx->current_input_surface = SID_INPUT_PICTURE_0;
+    ctx->current_upload_surface = SID_INPUT_PICTURE_1;
+    ctx->upload_thread_value = pthread_create(&ctx->upload_thread_id,
+                                              NULL,
+                                              upload_yuv_to_surface,
+                                              ctx);
+}
+
+static int 
+mpeg2enc_time_code(VAEncSequenceParameterBufferMPEG2 *seq_param,
+                   int num_frames)
+{
+    int fps = (int)(seq_param->frame_rate + 0.5);
+    int time_code = 0;
+    int time_code_pictures, time_code_seconds, time_code_minutes, time_code_hours;
+    int drop_frame_flag = 0;
+
+    assert(fps <= 60);
+
+    time_code_seconds = num_frames / fps;
+    time_code_pictures = num_frames % fps;
+    time_code |= time_code_pictures;
+
+    time_code_minutes = time_code_seconds / 60;
+    time_code_seconds = time_code_seconds % 60;
+    time_code |= (time_code_seconds << 6);
+
+    time_code_hours = time_code_minutes / 60;
+    time_code_minutes = time_code_minutes % 60;
+
+    time_code |= (1 << 12);     /* marker_bit */
+    time_code |= (time_code_minutes << 13);
+
+    time_code_hours = time_code_hours % 24;
+    time_code |= (time_code_hours << 19);
+
+    time_code |= (drop_frame_flag << 24);
+
+    return time_code;
+}
+
+/*
+ * run
+ */
+static void
+mpeg2enc_update_sequence_parameter(struct mpeg2enc_context *ctx,
+                                   VAEncPictureType picture_type,
+                                   int coded_order,
+                                   int display_order)
+{
+    VAEncSequenceParameterBufferMPEG2 *seq_param = &ctx->seq_param;
+
+    /* update the time_code info for the new GOP */
+    if (ctx->new_gop_header) {
+        seq_param->gop_header.bits.time_code = mpeg2enc_time_code(seq_param, display_order);
+    }
+}
+
+static void
+mpeg2enc_update_picture_parameter(struct mpeg2enc_context *ctx,
+                                  VAEncPictureType picture_type,
+                                  int coded_order,
+                                  int display_order)
+{
+    VAEncPictureParameterBufferMPEG2 *pic_param = &ctx->pic_param;
+
+    pic_param->picture_type = picture_type;
+    pic_param->temporal_reference = (display_order - ctx->gop_header_in_display_order) & 0x3FF;
+    pic_param->reconstructed_picture = surface_ids[SID_RECON_PICTURE];
+    pic_param->forward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L0];
+    pic_param->backward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L1];
+
+    if (pic_param->picture_type == VAEncPictureTypeIntra) {
+        pic_param->f_code[0][0] = 0xf;
+        pic_param->f_code[0][1] = 0xf;
+        pic_param->f_code[1][0] = 0xf;
+        pic_param->f_code[1][1] = 0xf;
+        pic_param->forward_reference_picture = VA_INVALID_SURFACE;
+        pic_param->backward_reference_picture = VA_INVALID_SURFACE;
+
+    } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
+        pic_param->f_code[0][0] = 0x1;
+        pic_param->f_code[0][1] = 0x1;
+        pic_param->f_code[1][0] = 0xf;
+        pic_param->f_code[1][1] = 0xf;
+        pic_param->forward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L0];
+        pic_param->backward_reference_picture = VA_INVALID_SURFACE;
+    } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
+        pic_param->f_code[0][0] = 0x1;
+        pic_param->f_code[0][1] = 0x1;
+        pic_param->f_code[1][0] = 0x1;
+        pic_param->f_code[1][1] = 0x1;
+        pic_param->forward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L0];
+        pic_param->backward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L1];
+    } else {
+        assert(0);
+    }
+}
+
+static void
+mpeg2enc_update_picture_parameter_buffer(struct mpeg2enc_context *ctx,
+                                         VAEncPictureType picture_type,
+                                         int coded_order,
+                                         int display_order)
+{
+    VAEncPictureParameterBufferMPEG2 *pic_param = &ctx->pic_param;
+    VAStatus va_status;
+
+    /* update the coded buffer id */
+    pic_param->coded_buf = ctx->codedbuf_buf_id;
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncPictureParameterBufferType,
+                               sizeof(*pic_param),
+                               1,
+                               pic_param,
+                               &ctx->pic_param_buf_id);
+    CHECK_VASTATUS(va_status, "vaCreateBuffer");
+}
+
+static void 
+mpeg2enc_update_slice_parameter(struct mpeg2enc_context *ctx, VAEncPictureType picture_type)
+{
+    VAEncSequenceParameterBufferMPEG2 *seq_param;
+    VAEncPictureParameterBufferMPEG2 *pic_param;
+    VAEncSliceParameterBufferMPEG2 *slice_param;
+    VAStatus va_status;
+    int i, width_in_mbs, height_in_mbs;
+
+    pic_param = &ctx->pic_param;
+    assert(pic_param->picture_coding_extension.bits.q_scale_type == 0);
+
+    seq_param = &ctx->seq_param;
+    width_in_mbs = (seq_param->picture_width + 15) / 16;
+    height_in_mbs = (seq_param->picture_height + 15) / 16;
+    ctx->num_slice_groups = 1;
+
+    for (i = 0; i < height_in_mbs; i++) {
+        slice_param = &ctx->slice_param[i];
+        slice_param->macroblock_address = i * width_in_mbs;
+        slice_param->num_macroblocks = width_in_mbs;
+        slice_param->is_intra_slice = (picture_type == VAEncPictureTypeIntra);
+        slice_param->quantiser_scale_code = ctx->qp / 2;
+    }
+
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncSliceParameterBufferType,
+                               sizeof(*slice_param),
+                               height_in_mbs,
+                               ctx->slice_param,
+                               ctx->slice_param_buf_id);
+    CHECK_VASTATUS(va_status, "vaCreateBuffer");;
+}
+
+static int 
+begin_picture(struct mpeg2enc_context *ctx,
+              int coded_order,
+              int display_order,
+              VAEncPictureType picture_type)
+{
+    VAStatus va_status;
+    int tmp;
+    VAEncPackedHeaderParameterBuffer packed_header_param_buffer;
+    unsigned int length_in_bits;
+    unsigned char *packed_seq_buffer = NULL, *packed_pic_buffer = NULL;
+
+    if (ctx->upload_thread_value != 0) {
+        fprintf(stderr, "FATAL error!!!\n");
+        exit(1);
+    }
+    
+    pthread_join(ctx->upload_thread_id, NULL);
+
+    ctx->upload_thread_value = -1;
+    tmp = ctx->current_input_surface;
+    ctx->current_input_surface = ctx->current_upload_surface;
+    ctx->current_upload_surface = tmp;
+
+    mpeg2enc_update_sequence_parameter(ctx, picture_type, coded_order, display_order);
+    mpeg2enc_update_picture_parameter(ctx, picture_type, coded_order, display_order);
+
+    if (ctx->new_sequence || ctx->new_gop_header) {
+        assert(picture_type == VAEncPictureTypeIntra);
+        length_in_bits = build_packed_seq_buffer(ctx, &ctx->seq_param, &packed_seq_buffer);
+        packed_header_param_buffer.type = VAEncPackedHeaderMPEG2_SPS;
+        packed_header_param_buffer.has_emulation_bytes = 0;
+        packed_header_param_buffer.bit_length = length_in_bits;
+        va_status = vaCreateBuffer(ctx->va_dpy,
+                                   ctx->context_id,
+                                   VAEncPackedHeaderParameterBufferType,
+                                   sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer,
+                                   &ctx->packed_seq_header_param_buf_id);
+        CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+        va_status = vaCreateBuffer(ctx->va_dpy,
+                                   ctx->context_id,
+                                   VAEncPackedHeaderDataBufferType,
+                                   (length_in_bits + 7) / 8, 1, packed_seq_buffer,
+                                   &ctx->packed_seq_buf_id);
+        CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+        free(packed_seq_buffer);
+    }
+
+    length_in_bits = build_packed_pic_buffer(&ctx->seq_param, &ctx->pic_param, &packed_pic_buffer);
+    packed_header_param_buffer.type = VAEncPackedHeaderMPEG2_PPS;
+    packed_header_param_buffer.has_emulation_bytes = 0;
+    packed_header_param_buffer.bit_length = length_in_bits;
+
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncPackedHeaderParameterBufferType,
+                               sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer,
+                               &ctx->packed_pic_header_param_buf_id);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncPackedHeaderDataBufferType,
+                               (length_in_bits + 7) / 8, 1, packed_pic_buffer,
+                               &ctx->packed_pic_buf_id);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    free(packed_pic_buffer);
+
+    /* sequence parameter set */
+    VAEncSequenceParameterBufferMPEG2 *seq_param = &ctx->seq_param;
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncSequenceParameterBufferType,
+                               sizeof(*seq_param),
+                               1,
+                               seq_param,
+                               &ctx->seq_param_buf_id);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");;
+
+    /* slice parameter */
+    mpeg2enc_update_slice_parameter(ctx, picture_type);
+
+    return 0;
+}
+
+static int 
+mpeg2enc_render_picture(struct mpeg2enc_context *ctx)
+{
+    VAStatus va_status;
+    VABufferID va_buffers[16];
+    unsigned int num_va_buffers = 0;
+
+    va_buffers[num_va_buffers++] = ctx->seq_param_buf_id;
+    va_buffers[num_va_buffers++] = ctx->pic_param_buf_id;
+
+    if (ctx->packed_seq_header_param_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = ctx->packed_seq_header_param_buf_id;
+
+    if (ctx->packed_seq_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = ctx->packed_seq_buf_id;
+
+    if (ctx->packed_pic_header_param_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = ctx->packed_pic_header_param_buf_id;
+
+    if (ctx->packed_pic_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = ctx->packed_pic_buf_id;
+
+    va_status = vaBeginPicture(ctx->va_dpy,
+                               ctx->context_id,
+                               surface_ids[ctx->current_input_surface]);
+    CHECK_VASTATUS(va_status,"vaBeginPicture");
+
+    va_status = vaRenderPicture(ctx->va_dpy,
+                                ctx->context_id,
+                                va_buffers,
+                                num_va_buffers);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+
+    va_status = vaRenderPicture(ctx->va_dpy,
+                                ctx->context_id,
+                                &ctx->slice_param_buf_id[0],
+                                ctx->num_slice_groups);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+
+    va_status = vaEndPicture(ctx->va_dpy, ctx->context_id);
+    CHECK_VASTATUS(va_status,"vaEndPicture");
+
+    return 0;
+}
+
+static int 
+mpeg2enc_destroy_buffers(struct mpeg2enc_context *ctx, VABufferID *va_buffers, unsigned int num_va_buffers)
+{
+    VAStatus va_status;
+    unsigned int i;
+
+    for (i = 0; i < num_va_buffers; i++) {
+        if (va_buffers[i] != VA_INVALID_ID) {
+            va_status = vaDestroyBuffer(ctx->va_dpy, va_buffers[i]);
+            CHECK_VASTATUS(va_status,"vaDestroyBuffer");
+            va_buffers[i] = VA_INVALID_ID;
+        }
+    }
+
+    return 0;
+}
+
+static void
+end_picture(struct mpeg2enc_context *ctx, VAEncPictureType picture_type, int next_is_bpic)
+{
+    VABufferID tempID;
+
+    /* Prepare for next picture */
+    tempID = surface_ids[SID_RECON_PICTURE];  
+
+    if (picture_type != VAEncPictureTypeBidirectional) {
+        if (next_is_bpic) {
+            surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE_L1]; 
+            surface_ids[SID_REFERENCE_PICTURE_L1] = tempID;	
+        } else {
+            surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE_L0]; 
+            surface_ids[SID_REFERENCE_PICTURE_L0] = tempID;
+        }
+    } else {
+        if (!next_is_bpic) {
+            surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE_L0]; 
+            surface_ids[SID_REFERENCE_PICTURE_L0] = surface_ids[SID_REFERENCE_PICTURE_L1];
+            surface_ids[SID_REFERENCE_PICTURE_L1] = tempID;
+        }
+    }
+
+    mpeg2enc_destroy_buffers(ctx, &ctx->seq_param_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->pic_param_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->packed_seq_header_param_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->packed_seq_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->packed_pic_header_param_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->packed_pic_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->slice_param_buf_id[0], ctx->num_slice_groups);
+    mpeg2enc_destroy_buffers(ctx, &ctx->codedbuf_buf_id, 1);
+    memset(ctx->slice_param, 0, sizeof(ctx->slice_param));
+    ctx->num_slice_groups = 0;
+}
+
+static int
+store_coded_buffer(struct mpeg2enc_context *ctx, VAEncPictureType picture_type)
+{
+    VACodedBufferSegment *coded_buffer_segment;
+    unsigned char *coded_mem;
+    int slice_data_length;
+    VAStatus va_status;
+    VASurfaceStatus surface_status;
+    size_t w_items;
+
+    va_status = vaSyncSurface(ctx->va_dpy, surface_ids[ctx->current_input_surface]);
+    CHECK_VASTATUS(va_status,"vaSyncSurface");
+
+    surface_status = 0;
+    va_status = vaQuerySurfaceStatus(ctx->va_dpy, surface_ids[ctx->current_input_surface], &surface_status);
+    CHECK_VASTATUS(va_status,"vaQuerySurfaceStatus");
+
+    va_status = vaMapBuffer(ctx->va_dpy, ctx->codedbuf_buf_id, (void **)(&coded_buffer_segment));
+    CHECK_VASTATUS(va_status,"vaMapBuffer");
+    coded_mem = coded_buffer_segment->buf;
+
+    if (coded_buffer_segment->status & VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK) {
+        if (picture_type == VAEncPictureTypeIntra)
+            ctx->codedbuf_i_size *= 2;
+        else
+            ctx->codedbuf_pb_size *= 2;
+
+        vaUnmapBuffer(ctx->va_dpy, ctx->codedbuf_buf_id);
+        return -1;
+    }
+
+    slice_data_length = coded_buffer_segment->size;
+
+    do {
+        w_items = fwrite(coded_mem, slice_data_length, 1, ctx->ofp);
+    } while (w_items != 1);
+
+    if (picture_type == VAEncPictureTypeIntra) {
+        if (ctx->codedbuf_i_size > slice_data_length * 3 / 2) {
+            ctx->codedbuf_i_size = slice_data_length * 3 / 2;
+        }
+        
+        if (ctx->codedbuf_pb_size < slice_data_length) {
+            ctx->codedbuf_pb_size = slice_data_length;
+        }
+    } else {
+        if (ctx->codedbuf_pb_size > slice_data_length * 3 / 2) {
+            ctx->codedbuf_pb_size = slice_data_length * 3 / 2;
+        }
+    }
+
+    vaUnmapBuffer(ctx->va_dpy, ctx->codedbuf_buf_id);
+
+    return 0;
+}
+
+static void
+encode_picture(struct mpeg2enc_context *ctx,
+               int coded_order,
+               int display_order,
+               VAEncPictureType picture_type,
+               int next_is_bpic,
+               int next_display_order)
+{
+    VAStatus va_status;
+    int ret = 0, codedbuf_size;
+    
+    begin_picture(ctx, coded_order, display_order, picture_type);
+
+    if (1) {
+        /* upload YUV data to VA surface for next frame */
+        if (next_display_order >= ctx->num_pictures)
+            next_display_order = ctx->num_pictures - 1;
+
+        fseek(ctx->ifp, ctx->frame_size * next_display_order, SEEK_SET);
+        ctx->upload_thread_value = pthread_create(&ctx->upload_thread_id,
+                                                  NULL,
+                                                  upload_yuv_to_surface,
+                                                  ctx);
+    }
+
+    do {
+        mpeg2enc_destroy_buffers(ctx, &ctx->codedbuf_buf_id, 1);
+        mpeg2enc_destroy_buffers(ctx, &ctx->pic_param_buf_id, 1);
+
+
+        if (VAEncPictureTypeIntra == picture_type) {
+            codedbuf_size = ctx->codedbuf_i_size;
+        } else {
+            codedbuf_size = ctx->codedbuf_pb_size;
+        }
+
+        /* coded buffer */
+        va_status = vaCreateBuffer(ctx->va_dpy,
+                                   ctx->context_id,
+                                   VAEncCodedBufferType,
+                                   codedbuf_size, 1, NULL,
+                                   &ctx->codedbuf_buf_id);
+        CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+        /* picture parameter set */
+        mpeg2enc_update_picture_parameter_buffer(ctx, picture_type, coded_order, display_order);
+
+        mpeg2enc_render_picture(ctx);
+
+        ret = store_coded_buffer(ctx, picture_type);
+    } while (ret);
+
+    end_picture(ctx, picture_type, next_is_bpic);
+}
+
+static void
+update_next_frame_info(struct mpeg2enc_context *ctx,
+                       VAEncPictureType curr_type,
+                       int curr_coded_order,
+                       int curr_display_order)
+{
+    if (((curr_coded_order + 1) % ctx->intra_period) == 0) {
+        ctx->next_type = VAEncPictureTypeIntra;
+        ctx->next_display_order = curr_coded_order + 1;
+        
+        return;
+    }
+
+    if (curr_type == VAEncPictureTypeIntra) {
+        assert(curr_display_order == curr_coded_order);
+        ctx->next_type = VAEncPictureTypePredictive;
+        ctx->next_bframes = ctx->ip_period;
+        ctx->next_display_order = curr_display_order + ctx->next_bframes + 1;
+    } else if (curr_type == VAEncPictureTypePredictive) {
+        if (ctx->ip_period == 0) {
+            assert(curr_display_order == curr_coded_order);
+            ctx->next_type = VAEncPictureTypePredictive;
+            ctx->next_display_order = curr_display_order + 1;
+        } else {
+            ctx->next_type = VAEncPictureTypeBidirectional;
+            ctx->next_display_order = curr_display_order - ctx->next_bframes;
+            ctx->next_bframes--;
+        }
+    } else if (curr_type == VAEncPictureTypeBidirectional) {
+        if (ctx->next_bframes == 0) {
+            ctx->next_type = VAEncPictureTypePredictive;
+            ctx->next_bframes = ctx->ip_period;
+            ctx->next_display_order = curr_display_order + ctx->next_bframes + 2;
+        } else {
+            ctx->next_type = VAEncPictureTypeBidirectional;
+            ctx->next_display_order = curr_display_order + 1;
+            ctx->next_bframes--;
+        }
+    }
+
+    if (ctx->next_display_order >= ctx->num_pictures) {
+        int rtmp = ctx->next_display_order - (ctx->num_pictures - 1);
+        ctx->next_display_order = ctx->num_pictures - 1;
+        ctx->next_bframes -= rtmp;
+    }
+}
+
+static void
+mpeg2enc_run(struct mpeg2enc_context *ctx)
+{
+    int display_order = 0, coded_order = 0;
+    VAEncPictureType type;
+
+    ctx->new_sequence = 1;
+    ctx->new_gop_header = 1;
+    ctx->gop_header_in_display_order = display_order;
+
+    while (coded_order < ctx->num_pictures) {
+        type = ctx->next_type;
+        display_order = ctx->next_display_order;
+        /* follow the IPBxxBPBxxB mode */
+        update_next_frame_info(ctx, type, coded_order, display_order);
+        encode_picture(ctx,
+                       coded_order,
+                       display_order,
+                       type,
+                       ctx->next_type == VAEncPictureTypeBidirectional,
+                       ctx->next_display_order);
+
+        /* update gop_header */
+        ctx->new_sequence = 0;
+        ctx->new_gop_header = ctx->next_type == VAEncPictureTypeIntra;
+
+        if (ctx->new_gop_header)
+            ctx->gop_header_in_display_order += ctx->intra_period;
+
+        coded_order++;
+
+        fprintf(stderr, "\r %d/%d ...", coded_order, ctx->num_pictures);
+        fflush(stdout);
+    }
+}
+
+/*
+ * end
+ */
+static void
+mpeg2enc_release_va_resources(struct mpeg2enc_context *ctx)
+{
+    vaDestroySurfaces(ctx->va_dpy, surface_ids, SID_NUMBER);	
+    vaDestroyContext(ctx->va_dpy, ctx->context_id);
+    vaDestroyConfig(ctx->va_dpy, ctx->config_id);
+    vaTerminate(ctx->va_dpy);
+    va_close_display(ctx->va_dpy);
+}
+
+static void
+mpeg2enc_end(struct mpeg2enc_context *ctx)
+{
+    pthread_join(ctx->upload_thread_id, NULL);
+    mpeg2enc_release_va_resources(ctx);
+}
+
+int 
+main(int argc, char *argv[])
+{
+    struct mpeg2enc_context ctx;
+    struct timeval tpstart, tpend; 
+    float timeuse;
+
+    gettimeofday(&tpstart, NULL);
+
+    memset(&ctx, 0, sizeof(ctx));
+    parse_args(&ctx, argc, argv);
+    mpeg2enc_init(&ctx);
+    mpeg2enc_run(&ctx);
+    mpeg2enc_end(&ctx);
+
+    gettimeofday(&tpend, NULL);
+    timeuse = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec;
+    timeuse /= 1000000;
+    fprintf(stderr, "\ndone!\n");
+    fprintf(stderr, "encode %d frames in %f secondes, FPS is %.1f\n", ctx.num_pictures, timeuse, ctx.num_pictures / timeuse);
+
+    mpeg2enc_exit(&ctx, 0);
+
+    return 0;
+}
diff --git a/test/encode/mpeg2vaenc.c b/test/encode/mpeg2vaenc.c
new file mode 100644
index 0000000..f49af27
--- /dev/null
+++ b/test/encode/mpeg2vaenc.c
@@ -0,0 +1,1545 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Simple MPEG-2 encoder based on libVA.
+ *
+ */  
+
+#include "sysdeps.h"
+
+#include <getopt.h>
+#include <unistd.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <pthread.h>
+
+#include <va/va.h>
+#include <va/va_enc_mpeg2.h>
+
+#include "va_display.h"
+
+#define START_CODE_PICUTRE      0x00000100
+#define START_CODE_SLICE        0x00000101
+#define START_CODE_USER         0x000001B2
+#define START_CODE_SEQ          0x000001B3
+#define START_CODE_EXT          0x000001B5
+#define START_CODE_GOP          0x000001B8
+
+#define CHROMA_FORMAT_RESERVED  0
+#define CHROMA_FORMAT_420       1
+#define CHROMA_FORMAT_422       2
+#define CHROMA_FORMAT_444       3
+
+#define MAX_SLICES              128
+
+enum {
+    MPEG2_MODE_I = 0,
+    MPEG2_MODE_IP,
+    MPEG2_MODE_IPB,
+};
+
+enum {
+    MPEG2_LEVEL_LOW = 0,
+    MPEG2_LEVEL_MAIN,
+    MPEG2_LEVEL_HIGH,
+};
+
+#define CHECK_VASTATUS(va_status, func)                                 \
+    if (va_status != VA_STATUS_SUCCESS) {                               \
+        fprintf(stderr, "%s:%s (%d) failed, exit\n", __func__, func, __LINE__); \
+        exit(1);                                                        \
+    }
+
+static VAProfile mpeg2_va_profiles[] = {
+    VAProfileMPEG2Simple,
+    VAProfileMPEG2Main
+};
+
+static struct _mpeg2_sampling_density
+{
+    int samplers_per_line;
+    int line_per_frame;
+    int frame_per_sec;
+} mpeg2_upper_samplings[2][3] = {
+    { { 0, 0, 0 },
+      { 720, 576, 30 },
+      { 0, 0, 0 },
+    },
+
+    { { 352, 288, 30 },
+      { 720, 576, 30 },
+      { 1920, 1152, 60 },
+    }
+};
+
+struct mpeg2enc_context {
+    /* args */
+    int rate_control_mode;
+    int fps;
+    int mode; /* 0:I, 1:I/P, 2:I/P/B */
+    VAProfile profile;
+    int level;
+    int width;
+    int height;
+    int frame_size;
+    int num_pictures;
+    int qp;
+    FILE *ifp;
+    FILE *ofp;
+    unsigned char *frame_data_buffer;
+    int intra_period;
+    int ip_period;
+    int bit_rate; /* in kbps */
+    VAEncPictureType next_type;
+    int next_display_order;
+    int next_bframes;
+    int new_sequence;
+    int new_gop_header;
+    int gop_header_in_display_order;
+
+    /* VA resource */
+    VADisplay va_dpy;
+    VAEncSequenceParameterBufferMPEG2 seq_param;
+    VAEncPictureParameterBufferMPEG2 pic_param;
+    VAEncSliceParameterBufferMPEG2 slice_param[MAX_SLICES];
+    VAContextID context_id;
+    VAConfigID config_id;
+    VABufferID seq_param_buf_id;                /* Sequence level parameter */
+    VABufferID pic_param_buf_id;                /* Picture level parameter */
+    VABufferID slice_param_buf_id[MAX_SLICES];  /* Slice level parameter, multil slices */
+    VABufferID codedbuf_buf_id;                 /* Output buffer, compressed data */
+    VABufferID packed_seq_header_param_buf_id;
+    VABufferID packed_seq_buf_id;
+    VABufferID packed_pic_header_param_buf_id;
+    VABufferID packed_pic_buf_id;
+    int num_slice_groups;
+    int codedbuf_i_size;
+    int codedbuf_pb_size;
+
+    /* thread */
+    pthread_t upload_thread_id;
+    int upload_thread_value;
+    int current_input_surface;
+    int current_upload_surface;
+};
+
+/*
+ * mpeg2enc helpers
+ */
+#define BITSTREAM_ALLOCATE_STEPPING     4096
+
+struct __bitstream {
+    unsigned int *buffer;
+    int bit_offset;
+    int max_size_in_dword;
+};
+
+typedef struct __bitstream bitstream;
+
+static unsigned int 
+swap32(unsigned int val)
+{
+    unsigned char *pval = (unsigned char *)&val;
+
+    return ((pval[0] << 24)     |
+            (pval[1] << 16)     |
+            (pval[2] << 8)      |
+            (pval[3] << 0));
+}
+
+static void
+bitstream_start(bitstream *bs)
+{
+    bs->max_size_in_dword = BITSTREAM_ALLOCATE_STEPPING;
+    bs->buffer = calloc(bs->max_size_in_dword * sizeof(int), 1);
+    bs->bit_offset = 0;
+}
+
+static void
+bitstream_end(bitstream *bs)
+{
+    int pos = (bs->bit_offset >> 5);
+    int bit_offset = (bs->bit_offset & 0x1f);
+    int bit_left = 32 - bit_offset;
+
+    if (bit_offset) {
+        bs->buffer[pos] = swap32((bs->buffer[pos] << bit_left));
+    }
+}
+ 
+static void
+bitstream_put_ui(bitstream *bs, unsigned int val, int size_in_bits)
+{
+    int pos = (bs->bit_offset >> 5);
+    int bit_offset = (bs->bit_offset & 0x1f);
+    int bit_left = 32 - bit_offset;
+
+    if (!size_in_bits)
+        return;
+
+    if (size_in_bits < 32)
+        val &= ((1 << size_in_bits) - 1);
+
+    bs->bit_offset += size_in_bits;
+
+    if (bit_left > size_in_bits) {
+        bs->buffer[pos] = (bs->buffer[pos] << size_in_bits | val);
+    } else {
+        size_in_bits -= bit_left;
+        bs->buffer[pos] = (bs->buffer[pos] << bit_left) | (val >> size_in_bits);
+        bs->buffer[pos] = swap32(bs->buffer[pos]);
+
+        if (pos + 1 == bs->max_size_in_dword) {
+            bs->max_size_in_dword += BITSTREAM_ALLOCATE_STEPPING;
+            bs->buffer = realloc(bs->buffer, bs->max_size_in_dword * sizeof(unsigned int));
+        }
+
+        bs->buffer[pos + 1] = val;
+    }
+}
+
+static void
+bitstream_byte_aligning(bitstream *bs, int bit)
+{
+    int bit_offset = (bs->bit_offset & 0x7);
+    int bit_left = 8 - bit_offset;
+    int new_val;
+
+    if (!bit_offset)
+        return;
+
+    assert(bit == 0 || bit == 1);
+
+    if (bit)
+        new_val = (1 << bit_left) - 1;
+    else
+        new_val = 0;
+
+    bitstream_put_ui(bs, new_val, bit_left);
+}
+
+static struct mpeg2_frame_rate {
+    int code;
+    float value;
+} frame_rate_tab[] = {
+    {1, 23.976},
+    {2, 24.0},
+    {3, 25.0},
+    {4, 29.97},
+    {5, 30},
+    {6, 50},
+    {7, 59.94},
+    {8, 60}
+};
+
+static int
+find_frame_rate_code(const VAEncSequenceParameterBufferMPEG2 *seq_param)
+{
+    unsigned int delta = -1;
+    int code = 1, i;
+    float frame_rate_value = seq_param->frame_rate * 
+        (seq_param->sequence_extension.bits.frame_rate_extension_d + 1) / 
+        (seq_param->sequence_extension.bits.frame_rate_extension_n + 1);
+
+    for (i = 0; i < sizeof(frame_rate_tab) / sizeof(frame_rate_tab[0]); i++) {
+
+        if (abs(1000 * frame_rate_tab[i].value - 1000 * frame_rate_value) < delta) {
+            code = frame_rate_tab[i].code;
+            delta = abs(1000 * frame_rate_tab[i].value - 1000 * frame_rate_value);
+        }
+    }
+
+    return code;
+}
+
+static void 
+sps_rbsp(struct mpeg2enc_context *ctx,
+         const VAEncSequenceParameterBufferMPEG2 *seq_param,
+         bitstream *bs)
+{
+    int frame_rate_code = find_frame_rate_code(seq_param);
+
+    if (ctx->new_sequence) {
+        bitstream_put_ui(bs, START_CODE_SEQ, 32);
+        bitstream_put_ui(bs, seq_param->picture_width, 12);
+        bitstream_put_ui(bs, seq_param->picture_height, 12);
+        bitstream_put_ui(bs, seq_param->aspect_ratio_information, 4);
+        bitstream_put_ui(bs, frame_rate_code, 4); /* frame_rate_code */
+        bitstream_put_ui(bs, (seq_param->bits_per_second + 399) / 400, 18); /* the low 18 bits of bit_rate */
+        bitstream_put_ui(bs, 1, 1); /* marker_bit */
+        bitstream_put_ui(bs, seq_param->vbv_buffer_size, 10);
+        bitstream_put_ui(bs, 0, 1); /* constraint_parameter_flag, always 0 for MPEG-2 */
+        bitstream_put_ui(bs, 0, 1); /* load_intra_quantiser_matrix */
+        bitstream_put_ui(bs, 0, 1); /* load_non_intra_quantiser_matrix */
+
+        bitstream_byte_aligning(bs, 0);
+
+        bitstream_put_ui(bs, START_CODE_EXT, 32);
+        bitstream_put_ui(bs, 1, 4); /* sequence_extension id */
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.profile_and_level_indication, 8);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.progressive_sequence, 1);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.chroma_format, 2);
+        bitstream_put_ui(bs, seq_param->picture_width >> 12, 2);
+        bitstream_put_ui(bs, seq_param->picture_height >> 12, 2);
+        bitstream_put_ui(bs, ((seq_param->bits_per_second + 399) / 400) >> 18, 12); /* bit_rate_extension */
+        bitstream_put_ui(bs, 1, 1); /* marker_bit */
+        bitstream_put_ui(bs, seq_param->vbv_buffer_size >> 10, 8);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.low_delay, 1);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.frame_rate_extension_n, 2);
+        bitstream_put_ui(bs, seq_param->sequence_extension.bits.frame_rate_extension_d, 5);
+
+        bitstream_byte_aligning(bs, 0);
+    }
+
+    if (ctx->new_gop_header) {
+        bitstream_put_ui(bs, START_CODE_GOP, 32);
+        bitstream_put_ui(bs, seq_param->gop_header.bits.time_code, 25);
+        bitstream_put_ui(bs, seq_param->gop_header.bits.closed_gop, 1);
+        bitstream_put_ui(bs, seq_param->gop_header.bits.broken_link, 1);
+
+        bitstream_byte_aligning(bs, 0);
+    }
+}
+
+static void 
+pps_rbsp(const VAEncSequenceParameterBufferMPEG2 *seq_param,
+         const VAEncPictureParameterBufferMPEG2 *pic_param,
+         bitstream *bs)
+{
+    int chroma_420_type;
+
+    if (seq_param->sequence_extension.bits.chroma_format == CHROMA_FORMAT_420)
+        chroma_420_type = pic_param->picture_coding_extension.bits.progressive_frame;
+    else
+        chroma_420_type = 0;
+
+    bitstream_put_ui(bs, START_CODE_PICUTRE, 32);
+    bitstream_put_ui(bs, pic_param->temporal_reference, 10);
+    bitstream_put_ui(bs,
+                     pic_param->picture_type == VAEncPictureTypeIntra ? 1 :
+                     pic_param->picture_type == VAEncPictureTypePredictive ? 2 : 3,
+                     3);
+    bitstream_put_ui(bs, 0xFFFF, 16); /* vbv_delay, always 0xFFFF */
+    
+    if (pic_param->picture_type == VAEncPictureTypePredictive ||
+        pic_param->picture_type == VAEncPictureTypeBidirectional) {
+        bitstream_put_ui(bs, 0, 1); /* full_pel_forward_vector, always 0 for MPEG-2 */
+        bitstream_put_ui(bs, 7, 3); /* forward_f_code, always 7 for MPEG-2 */
+    }
+
+    if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
+        bitstream_put_ui(bs, 0, 1); /* full_pel_backward_vector, always 0 for MPEG-2 */
+        bitstream_put_ui(bs, 7, 3); /* backward_f_code, always 7 for MPEG-2 */
+    }
+     
+    bitstream_put_ui(bs, 0, 1); /* extra_bit_picture, 0 */
+
+    bitstream_byte_aligning(bs, 0);
+
+    bitstream_put_ui(bs, START_CODE_EXT, 32);
+    bitstream_put_ui(bs, 8, 4); /* Picture Coding Extension ID: 8 */
+    bitstream_put_ui(bs, pic_param->f_code[0][0], 4);
+    bitstream_put_ui(bs, pic_param->f_code[0][1], 4);
+    bitstream_put_ui(bs, pic_param->f_code[1][0], 4);
+    bitstream_put_ui(bs, pic_param->f_code[1][1], 4);
+
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.intra_dc_precision, 2);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.picture_structure, 2);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.top_field_first, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.frame_pred_frame_dct, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.concealment_motion_vectors, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.q_scale_type, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.intra_vlc_format, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.alternate_scan, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.repeat_first_field, 1);
+    bitstream_put_ui(bs, chroma_420_type, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.progressive_frame, 1);
+    bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.composite_display_flag, 1);
+
+    bitstream_byte_aligning(bs, 0);
+}
+
+static int
+build_packed_pic_buffer(const VAEncSequenceParameterBufferMPEG2 *seq_param,
+                        const VAEncPictureParameterBufferMPEG2 *pic_param,
+                        unsigned char **header_buffer)
+{
+    bitstream bs;
+
+    bitstream_start(&bs);
+    pps_rbsp(seq_param, pic_param, &bs);
+    bitstream_end(&bs);
+
+    *header_buffer = (unsigned char *)bs.buffer;
+    return bs.bit_offset;
+}
+
+static int
+build_packed_seq_buffer(struct mpeg2enc_context *ctx,
+                        const VAEncSequenceParameterBufferMPEG2 *seq_param,
+                        unsigned char **header_buffer)
+{
+    bitstream bs;
+
+    bitstream_start(&bs);
+    sps_rbsp(ctx, seq_param, &bs);
+    bitstream_end(&bs);
+
+    *header_buffer = (unsigned char *)bs.buffer;
+    return bs.bit_offset;
+}
+
+/*
+ * mpeg2enc
+ */
+#define SID_INPUT_PICTURE_0                     0
+#define SID_INPUT_PICTURE_1                     1
+#define SID_REFERENCE_PICTURE_L0                2
+#define SID_REFERENCE_PICTURE_L1                3
+#define SID_RECON_PICTURE                       4
+#define SID_NUMBER                              SID_RECON_PICTURE + 1
+
+static VASurfaceID surface_ids[SID_NUMBER];
+
+/*
+ * upload thread function
+ */
+static void *
+upload_yuv_to_surface(void *data)
+{
+    struct mpeg2enc_context *ctx = data;
+    VAImage surface_image;
+    VAStatus va_status;
+    void *surface_p = NULL;
+    unsigned char *y_src, *u_src, *v_src;
+    unsigned char *y_dst, *u_dst, *v_dst;
+    int y_size = ctx->width * ctx->height;
+    int u_size = (ctx->width >> 1) * (ctx->height >> 1);
+    int row, col;
+    size_t n_items;
+
+    do {
+        n_items = fread(ctx->frame_data_buffer, ctx->frame_size, 1, ctx->ifp);
+    } while (n_items != 1);
+
+    va_status = vaDeriveImage(ctx->va_dpy, surface_ids[ctx->current_upload_surface], &surface_image);
+    CHECK_VASTATUS(va_status,"vaDeriveImage");
+
+    vaMapBuffer(ctx->va_dpy, surface_image.buf, &surface_p);
+    assert(VA_STATUS_SUCCESS == va_status);
+        
+    y_src = ctx->frame_data_buffer;
+    u_src = ctx->frame_data_buffer + y_size; /* UV offset for NV12 */
+    v_src = ctx->frame_data_buffer + y_size + u_size;
+
+    y_dst = surface_p + surface_image.offsets[0];
+    u_dst = surface_p + surface_image.offsets[1]; /* UV offset for NV12 */
+    v_dst = surface_p + surface_image.offsets[2];
+
+    /* Y plane */
+    for (row = 0; row < surface_image.height; row++) {
+        memcpy(y_dst, y_src, surface_image.width);
+        y_dst += surface_image.pitches[0];
+        y_src += ctx->width;
+    }
+
+    if (surface_image.format.fourcc == VA_FOURCC_NV12) { /* UV plane */
+        for (row = 0; row < surface_image.height / 2; row++) {
+            for (col = 0; col < surface_image.width / 2; col++) {
+                u_dst[col * 2] = u_src[col];
+                u_dst[col * 2 + 1] = v_src[col];
+            }
+
+            u_dst += surface_image.pitches[1];
+            u_src += (ctx->width / 2);
+            v_src += (ctx->width / 2);
+        }
+    } else {
+        for (row = 0; row < surface_image.height / 2; row++) {
+            for (col = 0; col < surface_image.width / 2; col++) {
+                u_dst[col] = u_src[col];
+                v_dst[col] = v_src[col];
+            }
+
+            u_dst += surface_image.pitches[1];
+            v_dst += surface_image.pitches[2];
+            u_src += (ctx->width / 2);
+            v_src += (ctx->width / 2);
+        }
+    }
+
+    vaUnmapBuffer(ctx->va_dpy, surface_image.buf);
+    vaDestroyImage(ctx->va_dpy, surface_image.image_id);
+
+    return NULL;
+}
+
+static void 
+mpeg2enc_exit(struct mpeg2enc_context *ctx, int exit_code)
+{
+    if (ctx->frame_data_buffer) {
+        free(ctx->frame_data_buffer);
+        ctx->frame_data_buffer = NULL;
+    }
+
+    if (ctx->ifp) {
+        fclose(ctx->ifp);
+        ctx->ifp = NULL;
+    }
+
+    if (ctx->ofp) {
+        fclose(ctx->ofp);
+        ctx->ofp = NULL;
+    }
+
+    exit(exit_code);
+}
+
+static void 
+usage(char *program)
+{   
+    fprintf(stderr, "Usage: %s --help\n", program);
+    fprintf(stderr, "\t--help   print this message\n");
+    fprintf(stderr, "Usage: %s <width> <height> <ifile> <ofile> [options]\n", program);
+    fprintf(stderr, "\t<width>  specifies the frame width\n");
+    fprintf(stderr, "\t<height> specifies the frame height\n");
+    fprintf(stderr, "\t<ifile>  specifies the I420/IYUV YUV file\n");
+    fprintf(stderr, "\t<ofile>  specifies the encoded MPEG-2 file\n");
+    fprintf(stderr, "where options include:\n");
+    fprintf(stderr, "\t--cqp <QP>       const qp mode with specified <QP>\n");
+    fprintf(stderr, "\t--fps <FPS>      specify the frame rate\n");
+    fprintf(stderr, "\t--mode <MODE>    specify the mode 0 (I), 1 (I/P) and 2 (I/P/B)\n");
+    fprintf(stderr, "\t--profile <PROFILE>      specify the profile 0(Simple), or 1(Main, default)\n");
+    fprintf(stderr, "\t--level <LEVEL>  specify the level 0(Low), 1(Main, default) or 2(High)\n");    
+}
+
+void
+mpeg2_profile_level(struct mpeg2enc_context *ctx,
+                    int profile,
+                    int level)
+{
+    int l = 2, p;
+
+    for (p = profile; p < 2; p++) {
+        for (l = level; l < 3; l++) {
+            if (ctx->width <= mpeg2_upper_samplings[p][l].samplers_per_line &&
+                ctx->height <= mpeg2_upper_samplings[p][l].line_per_frame &&
+                ctx->fps <= mpeg2_upper_samplings[p][l].frame_per_sec) {
+                
+                goto __find;
+                break;
+            }
+        }
+    }
+
+    if (p == 2) {
+        fprintf(stderr, "Warning: can't find a proper profile and level for the specified width/height/fps\n");
+        p = 1;
+        l = 2;
+    }
+
+__find:    
+    ctx->profile = mpeg2_va_profiles[p];
+    ctx->level = l;
+}
+
+static void 
+parse_args(struct mpeg2enc_context *ctx, int argc, char **argv)
+{
+    int c, tmp;
+    int option_index = 0;
+    long file_size;
+    int profile = 1, level = 1;
+
+    static struct option long_options[] = {
+        {"help",        no_argument,            0,      'h'},
+        {"cqp",         required_argument,      0,      'c'},
+        {"fps",         required_argument,      0,      'f'},
+        {"mode",        required_argument,      0,      'm'},
+        {"profile",     required_argument,      0,      'p'},
+        {"level",       required_argument,      0,      'l'},
+        { NULL,         0,                      NULL,   0 }
+    };
+
+    if ((argc == 2 && strcmp(argv[1], "--help") == 0) ||
+        (argc < 5))
+        goto print_usage;
+
+    ctx->width = atoi(argv[1]);
+    ctx->height = atoi(argv[2]);
+
+    if (ctx->width <= 0 || ctx->height <= 0) {
+        fprintf(stderr, "<width> and <height> must be greater than 0\n");
+        goto err_exit;
+    }
+
+    ctx->ifp = fopen(argv[3], "rb");
+
+    if (ctx->ifp == NULL) {
+        fprintf(stderr, "Can't open the input file\n");
+        goto err_exit;
+    }
+
+    fseek(ctx->ifp, 0l, SEEK_END);
+    file_size = ftell(ctx->ifp);
+    ctx->frame_size = ctx->width * ctx->height * 3 / 2;
+
+    if ((file_size < ctx->frame_size) ||
+        (file_size % ctx->frame_size)) {
+        fprintf(stderr, "The input file size %ld isn't a multiple of the frame size %d\n", file_size, ctx->frame_size);
+        goto err_exit;
+    }
+
+    ctx->num_pictures = file_size / ctx->frame_size;
+    fseek(ctx->ifp, 0l, SEEK_SET);
+    
+    ctx->ofp = fopen(argv[4], "wb");
+    
+    if (ctx->ofp == NULL) {
+        fprintf(stderr, "Can't create the output file\n");
+        goto err_exit;
+    }
+
+    opterr = 0;
+    ctx->fps = 30;
+    ctx->qp = 8;
+    ctx->rate_control_mode = VA_RC_CQP;
+    ctx->mode = MPEG2_MODE_IP;
+    ctx->profile = VAProfileMPEG2Main;
+    ctx->level = MPEG2_LEVEL_MAIN;
+
+    optind = 5;
+
+    while((c = getopt_long(argc, argv,
+                           "",
+                           long_options, 
+                           &option_index)) != -1) {
+        switch(c) {
+        case 'c':
+            tmp = atoi(optarg);
+
+            /* only support q_scale_type = 0 */
+            if (tmp > 62 || tmp < 2) {
+                fprintf(stderr, "Warning: QP must be in [2, 62]\n");
+
+                if (tmp > 62)
+                    tmp = 62;
+
+                if (tmp < 2)
+                    tmp = 2;
+            }
+
+            ctx->qp = tmp & 0xFE;
+            ctx->rate_control_mode = VA_RC_CQP;
+
+            break;
+
+        case 'f':
+            tmp = atoi(optarg);
+
+            if (tmp <= 0)
+                fprintf(stderr, "Warning: FPS must be greater than 0\n");
+            else
+                ctx->fps = tmp;
+
+            ctx->rate_control_mode = VA_RC_CBR;
+
+            break;
+
+        case 'm':
+            tmp = atoi(optarg);
+            
+            if (tmp < MPEG2_MODE_I || tmp > MPEG2_MODE_IPB)
+                fprintf(stderr, "Waning: MODE must be 0, 1, or 2\n");
+            else
+                ctx->mode = tmp;
+
+            break;
+
+        case 'p':
+            tmp = atoi(optarg);
+            
+            if (tmp < 0 || tmp > 1)
+                fprintf(stderr, "Waning: PROFILE must be 0 or 1\n");
+            else
+                profile = tmp;
+
+            break;
+
+        case 'l':
+            tmp = atoi(optarg);
+            
+            if (tmp < MPEG2_LEVEL_LOW || tmp > MPEG2_LEVEL_HIGH)
+                fprintf(stderr, "Waning: LEVEL must be 0, 1, or 2\n");
+            else
+                level = tmp;
+
+            break;
+
+        case '?':
+            fprintf(stderr, "Error: unkown command options\n");
+
+        case 'h':
+            goto print_usage;
+        }
+    }
+
+    mpeg2_profile_level(ctx, profile, level);
+
+    return;
+
+print_usage:    
+    usage(argv[0]);
+err_exit:
+    mpeg2enc_exit(ctx, 1);
+}
+
+/*
+ * init
+ */
+void
+mpeg2enc_init_sequence_parameter(struct mpeg2enc_context *ctx,
+                                VAEncSequenceParameterBufferMPEG2 *seq_param)
+{
+    int profile = 4, level = 8;
+
+    switch (ctx->profile) {
+    case VAProfileMPEG2Simple:
+        profile = 5;
+        break;
+
+    case VAProfileMPEG2Main:
+        profile = 4;
+        break;
+
+    default:
+        assert(0);
+        break;
+    }
+
+    switch (ctx->level) {
+    case MPEG2_LEVEL_LOW:
+        level = 10;
+        break;
+
+    case MPEG2_LEVEL_MAIN:
+        level = 8;
+        break;
+
+    case MPEG2_LEVEL_HIGH:
+        level = 4;
+        break;
+
+    default:
+        assert(0);
+        break;
+    }
+        
+    seq_param->intra_period = ctx->intra_period;
+    seq_param->ip_period = ctx->ip_period;   /* FIXME: ??? */
+    seq_param->picture_width = ctx->width;
+    seq_param->picture_height = ctx->height;
+
+    if (ctx->bit_rate > 0)
+        seq_param->bits_per_second = 1024 * ctx->bit_rate; /* use kbps as input */
+    else
+        seq_param->bits_per_second = 0x3FFFF * 400;
+
+    seq_param->frame_rate = ctx->fps;
+    seq_param->aspect_ratio_information = 1;
+    seq_param->vbv_buffer_size = 3; /* B = 16 * 1024 * vbv_buffer_size */
+
+    seq_param->sequence_extension.bits.profile_and_level_indication = profile << 4 | level;
+    seq_param->sequence_extension.bits.progressive_sequence = 1; /* progressive frame-pictures */
+    seq_param->sequence_extension.bits.chroma_format = CHROMA_FORMAT_420; /* 4:2:0 */
+    seq_param->sequence_extension.bits.low_delay = 0; /* FIXME */
+    seq_param->sequence_extension.bits.frame_rate_extension_n = 0;
+    seq_param->sequence_extension.bits.frame_rate_extension_d = 0;
+
+    seq_param->gop_header.bits.time_code = (1 << 12); /* bit12: marker_bit */
+    seq_param->gop_header.bits.closed_gop = 0;
+    seq_param->gop_header.bits.broken_link = 0;    
+}
+
+static void
+mpeg2enc_init_picture_parameter(struct mpeg2enc_context *ctx,
+                               VAEncPictureParameterBufferMPEG2 *pic_param)
+{
+    pic_param->forward_reference_picture = VA_INVALID_ID;
+    pic_param->backward_reference_picture = VA_INVALID_ID;
+    pic_param->reconstructed_picture = VA_INVALID_ID;
+    pic_param->coded_buf = VA_INVALID_ID;
+    pic_param->picture_type = VAEncPictureTypeIntra;
+
+    pic_param->temporal_reference = 0;
+    pic_param->f_code[0][0] = 0xf;
+    pic_param->f_code[0][1] = 0xf;
+    pic_param->f_code[1][0] = 0xf;
+    pic_param->f_code[1][1] = 0xf;
+
+    pic_param->picture_coding_extension.bits.intra_dc_precision = 0; /* 8bits */
+    pic_param->picture_coding_extension.bits.picture_structure = 3; /* frame picture */
+    pic_param->picture_coding_extension.bits.top_field_first = 0; 
+    pic_param->picture_coding_extension.bits.frame_pred_frame_dct = 1; /* FIXME */
+    pic_param->picture_coding_extension.bits.concealment_motion_vectors = 0;
+    pic_param->picture_coding_extension.bits.q_scale_type = 0;
+    pic_param->picture_coding_extension.bits.intra_vlc_format = 0;
+    pic_param->picture_coding_extension.bits.alternate_scan = 0;
+    pic_param->picture_coding_extension.bits.repeat_first_field = 0;
+    pic_param->picture_coding_extension.bits.progressive_frame = 1;
+    pic_param->picture_coding_extension.bits.composite_display_flag = 0;
+}
+
+static void 
+mpeg2enc_alloc_va_resources(struct mpeg2enc_context *ctx)
+{
+    VAEntrypoint *entrypoint_list;
+    VAConfigAttrib attrib_list[2];
+    VAStatus va_status;
+    int max_entrypoints, num_entrypoints, entrypoint;
+    int major_ver, minor_ver;
+
+    ctx->va_dpy = va_open_display();
+    va_status = vaInitialize(ctx->va_dpy,
+                             &major_ver,
+                             &minor_ver);
+    CHECK_VASTATUS(va_status, "vaInitialize");
+
+    max_entrypoints = vaMaxNumEntrypoints(ctx->va_dpy);
+    entrypoint_list = malloc(max_entrypoints * sizeof(VAEntrypoint));
+    vaQueryConfigEntrypoints(ctx->va_dpy,
+                             ctx->profile,
+                             entrypoint_list,
+                             &num_entrypoints);
+
+    for	(entrypoint = 0; entrypoint < num_entrypoints; entrypoint++) {
+        if (entrypoint_list[entrypoint] == VAEntrypointEncSlice)
+            break;
+    }
+
+    free(entrypoint_list);
+
+    if (entrypoint == num_entrypoints) {
+        /* not find Slice entry point */
+        assert(0);
+    }
+
+    /* find out the format for the render target, and rate control mode */
+    attrib_list[0].type = VAConfigAttribRTFormat;
+    attrib_list[1].type = VAConfigAttribRateControl;
+    vaGetConfigAttributes(ctx->va_dpy,
+                          ctx->profile,
+                          VAEntrypointEncSlice,
+                          &attrib_list[0],
+                          2);
+
+    if ((attrib_list[0].value & VA_RT_FORMAT_YUV420) == 0) {
+        /* not find desired YUV420 RT format */
+        assert(0);
+    }
+
+    if ((attrib_list[1].value & ctx->rate_control_mode) == 0) {
+        /* Can't find matched RC mode */
+        fprintf(stderr, "RC mode %d isn't found, exit\n", ctx->rate_control_mode);
+        assert(0);
+    }
+
+    attrib_list[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */
+    attrib_list[1].value = ctx->rate_control_mode; /* set to desired RC mode */
+
+    va_status = vaCreateConfig(ctx->va_dpy,
+                               ctx->profile,
+                               VAEntrypointEncSlice,
+                               attrib_list,
+                               2,
+                               &ctx->config_id);
+    CHECK_VASTATUS(va_status, "vaCreateConfig");
+
+    /* Create a context for this decode pipe */
+    va_status = vaCreateContext(ctx->va_dpy,
+                                ctx->config_id,
+                                ctx->width,
+                                ctx->height,
+                                VA_PROGRESSIVE, 
+                                0,
+                                0,
+                                &ctx->context_id);
+    CHECK_VASTATUS(va_status, "vaCreateContext");
+
+    va_status = vaCreateSurfaces(ctx->va_dpy,
+                                 VA_RT_FORMAT_YUV420,
+                                 ctx->width,
+                                 ctx->height,
+                                 surface_ids,
+                                 SID_NUMBER,
+                                 NULL,
+                                 0);
+    CHECK_VASTATUS(va_status, "vaCreateSurfaces");
+}
+
+static void 
+mpeg2enc_init(struct mpeg2enc_context *ctx)
+{
+    int i;
+
+    ctx->frame_data_buffer = (unsigned char *)malloc(ctx->frame_size);
+    ctx->seq_param_buf_id = VA_INVALID_ID;
+    ctx->pic_param_buf_id = VA_INVALID_ID;
+    ctx->packed_seq_header_param_buf_id = VA_INVALID_ID;
+    ctx->packed_seq_buf_id = VA_INVALID_ID;
+    ctx->packed_pic_header_param_buf_id = VA_INVALID_ID;
+    ctx->packed_pic_buf_id = VA_INVALID_ID;
+    ctx->codedbuf_buf_id = VA_INVALID_ID;
+    ctx->codedbuf_i_size = ctx->frame_size;
+    ctx->codedbuf_pb_size = 0;
+    ctx->next_display_order = 0;
+    ctx->next_type = VAEncPictureTypeIntra;
+
+    if (ctx->mode == MPEG2_MODE_I) {
+        ctx->intra_period = 1;
+        ctx->ip_period = 0;
+    } else if (ctx->mode == MPEG2_MODE_IP) {
+        ctx->intra_period = 16;
+        ctx->ip_period = 0;
+    } else {
+        ctx->intra_period = 16;
+        ctx->ip_period = 2;
+    }
+
+    ctx->next_bframes = ctx->ip_period;
+
+    ctx->new_sequence = 1;
+    ctx->new_gop_header = 1;
+    ctx->gop_header_in_display_order = 0;
+
+    ctx->bit_rate = -1;
+
+    for (i = 0; i < MAX_SLICES; i++) {
+        ctx->slice_param_buf_id[i] = VA_INVALID_ID;
+    }
+
+    mpeg2enc_init_sequence_parameter(ctx, &ctx->seq_param);
+    mpeg2enc_init_picture_parameter(ctx, &ctx->pic_param);
+    mpeg2enc_alloc_va_resources(ctx);
+
+    /* thread */
+    ctx->current_input_surface = SID_INPUT_PICTURE_0;
+    ctx->current_upload_surface = SID_INPUT_PICTURE_1;
+    ctx->upload_thread_value = pthread_create(&ctx->upload_thread_id,
+                                              NULL,
+                                              upload_yuv_to_surface,
+                                              ctx);
+}
+
+static int 
+mpeg2enc_time_code(VAEncSequenceParameterBufferMPEG2 *seq_param,
+                   int num_frames)
+{
+    int fps = (int)(seq_param->frame_rate + 0.5);
+    int time_code = 0;
+    int time_code_pictures, time_code_seconds, time_code_minutes, time_code_hours;
+    int drop_frame_flag = 0;
+
+    assert(fps <= 60);
+
+    time_code_seconds = num_frames / fps;
+    time_code_pictures = num_frames % fps;
+    time_code |= time_code_pictures;
+
+    time_code_minutes = time_code_seconds / 60;
+    time_code_seconds = time_code_seconds % 60;
+    time_code |= (time_code_seconds << 6);
+
+    time_code_hours = time_code_minutes / 60;
+    time_code_minutes = time_code_minutes % 60;
+
+    time_code |= (1 << 12);     /* marker_bit */
+    time_code |= (time_code_minutes << 13);
+
+    time_code_hours = time_code_hours % 24;
+    time_code |= (time_code_hours << 19);
+
+    time_code |= (drop_frame_flag << 24);
+
+    return time_code;
+}
+
+/*
+ * run
+ */
+static void
+mpeg2enc_update_sequence_parameter(struct mpeg2enc_context *ctx,
+                                   VAEncPictureType picture_type,
+                                   int coded_order,
+                                   int display_order)
+{
+    VAEncSequenceParameterBufferMPEG2 *seq_param = &ctx->seq_param;
+
+    /* update the time_code info for the new GOP */
+    if (ctx->new_gop_header) {
+        seq_param->gop_header.bits.time_code = mpeg2enc_time_code(seq_param, display_order);
+    }
+}
+
+static void
+mpeg2enc_update_picture_parameter(struct mpeg2enc_context *ctx,
+                                  VAEncPictureType picture_type,
+                                  int coded_order,
+                                  int display_order)
+{
+    VAEncPictureParameterBufferMPEG2 *pic_param = &ctx->pic_param;
+    uint8_t f_code_x, f_code_y;
+
+    pic_param->picture_type = picture_type;
+    pic_param->temporal_reference = (display_order - ctx->gop_header_in_display_order) & 0x3FF;
+    pic_param->reconstructed_picture = surface_ids[SID_RECON_PICTURE];
+    pic_param->forward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L0];
+    pic_param->backward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L1];
+
+    f_code_x = 0xf;
+    f_code_y = 0xf;
+    if (pic_param->picture_type != VAEncPictureTypeIntra) {
+	if (ctx->level == MPEG2_LEVEL_LOW) {
+		f_code_x = 7;
+		f_code_y = 4;
+	} else if (ctx->level == MPEG2_LEVEL_MAIN) {
+		f_code_x = 8;
+		f_code_y = 5;
+	} else {
+		f_code_x = 9;
+		f_code_y = 5;
+	}
+    }
+    
+    if (pic_param->picture_type == VAEncPictureTypeIntra) {
+        pic_param->f_code[0][0] = 0xf;
+        pic_param->f_code[0][1] = 0xf;
+        pic_param->f_code[1][0] = 0xf;
+        pic_param->f_code[1][1] = 0xf;
+        pic_param->forward_reference_picture = VA_INVALID_SURFACE;
+        pic_param->backward_reference_picture = VA_INVALID_SURFACE;
+
+    } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
+        pic_param->f_code[0][0] = f_code_x;
+        pic_param->f_code[0][1] = f_code_y;
+        pic_param->f_code[1][0] = 0xf;
+        pic_param->f_code[1][1] = 0xf;
+        pic_param->forward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L0];
+        pic_param->backward_reference_picture = VA_INVALID_SURFACE;
+    } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
+        pic_param->f_code[0][0] = f_code_x;
+        pic_param->f_code[0][1] = f_code_y;
+        pic_param->f_code[1][0] = f_code_x;
+        pic_param->f_code[1][1] = f_code_y;
+        pic_param->forward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L0];
+        pic_param->backward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L1];
+    } else {
+        assert(0);
+    }
+}
+
+static void
+mpeg2enc_update_picture_parameter_buffer(struct mpeg2enc_context *ctx,
+                                         VAEncPictureType picture_type,
+                                         int coded_order,
+                                         int display_order)
+{
+    VAEncPictureParameterBufferMPEG2 *pic_param = &ctx->pic_param;
+    VAStatus va_status;
+
+    /* update the coded buffer id */
+    pic_param->coded_buf = ctx->codedbuf_buf_id;
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncPictureParameterBufferType,
+                               sizeof(*pic_param),
+                               1,
+                               pic_param,
+                               &ctx->pic_param_buf_id);
+    CHECK_VASTATUS(va_status, "vaCreateBuffer");
+}
+
+static void 
+mpeg2enc_update_slice_parameter(struct mpeg2enc_context *ctx, VAEncPictureType picture_type)
+{
+    VAEncSequenceParameterBufferMPEG2 *seq_param;
+    VAEncPictureParameterBufferMPEG2 *pic_param;
+    VAEncSliceParameterBufferMPEG2 *slice_param;
+    VAStatus va_status;
+    int i, width_in_mbs, height_in_mbs;
+
+    pic_param = &ctx->pic_param;
+    assert(pic_param->picture_coding_extension.bits.q_scale_type == 0);
+
+    seq_param = &ctx->seq_param;
+    width_in_mbs = (seq_param->picture_width + 15) / 16;
+    height_in_mbs = (seq_param->picture_height + 15) / 16;
+    ctx->num_slice_groups = 1;
+
+    for (i = 0; i < height_in_mbs; i++) {
+        slice_param = &ctx->slice_param[i];
+        slice_param->macroblock_address = i * width_in_mbs;
+        slice_param->num_macroblocks = width_in_mbs;
+        slice_param->is_intra_slice = (picture_type == VAEncPictureTypeIntra);
+        slice_param->quantiser_scale_code = ctx->qp / 2;
+    }
+
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncSliceParameterBufferType,
+                               sizeof(*slice_param),
+                               height_in_mbs,
+                               ctx->slice_param,
+                               ctx->slice_param_buf_id);
+    CHECK_VASTATUS(va_status, "vaCreateBuffer");;
+}
+
+static int 
+begin_picture(struct mpeg2enc_context *ctx,
+              int coded_order,
+              int display_order,
+              VAEncPictureType picture_type)
+{
+    VAStatus va_status;
+    int tmp;
+    VAEncPackedHeaderParameterBuffer packed_header_param_buffer;
+    unsigned int length_in_bits;
+    unsigned char *packed_seq_buffer = NULL, *packed_pic_buffer = NULL;
+
+    if (ctx->upload_thread_value != 0) {
+        fprintf(stderr, "FATAL error!!!\n");
+        exit(1);
+    }
+    
+    pthread_join(ctx->upload_thread_id, NULL);
+
+    ctx->upload_thread_value = -1;
+    tmp = ctx->current_input_surface;
+    ctx->current_input_surface = ctx->current_upload_surface;
+    ctx->current_upload_surface = tmp;
+
+    mpeg2enc_update_sequence_parameter(ctx, picture_type, coded_order, display_order);
+    mpeg2enc_update_picture_parameter(ctx, picture_type, coded_order, display_order);
+
+    if (ctx->new_sequence || ctx->new_gop_header) {
+        assert(picture_type == VAEncPictureTypeIntra);
+        length_in_bits = build_packed_seq_buffer(ctx, &ctx->seq_param, &packed_seq_buffer);
+        packed_header_param_buffer.type = VAEncPackedHeaderMPEG2_SPS;
+        packed_header_param_buffer.has_emulation_bytes = 0;
+        packed_header_param_buffer.bit_length = length_in_bits;
+        va_status = vaCreateBuffer(ctx->va_dpy,
+                                   ctx->context_id,
+                                   VAEncPackedHeaderParameterBufferType,
+                                   sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer,
+                                   &ctx->packed_seq_header_param_buf_id);
+        CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+        va_status = vaCreateBuffer(ctx->va_dpy,
+                                   ctx->context_id,
+                                   VAEncPackedHeaderDataBufferType,
+                                   (length_in_bits + 7) / 8, 1, packed_seq_buffer,
+                                   &ctx->packed_seq_buf_id);
+        CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+        free(packed_seq_buffer);
+    }
+
+    length_in_bits = build_packed_pic_buffer(&ctx->seq_param, &ctx->pic_param, &packed_pic_buffer);
+    packed_header_param_buffer.type = VAEncPackedHeaderMPEG2_PPS;
+    packed_header_param_buffer.has_emulation_bytes = 0;
+    packed_header_param_buffer.bit_length = length_in_bits;
+
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncPackedHeaderParameterBufferType,
+                               sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer,
+                               &ctx->packed_pic_header_param_buf_id);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncPackedHeaderDataBufferType,
+                               (length_in_bits + 7) / 8, 1, packed_pic_buffer,
+                               &ctx->packed_pic_buf_id);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    free(packed_pic_buffer);
+
+    /* sequence parameter set */
+    VAEncSequenceParameterBufferMPEG2 *seq_param = &ctx->seq_param;
+    va_status = vaCreateBuffer(ctx->va_dpy,
+                               ctx->context_id,
+                               VAEncSequenceParameterBufferType,
+                               sizeof(*seq_param),
+                               1,
+                               seq_param,
+                               &ctx->seq_param_buf_id);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");;
+
+    /* slice parameter */
+    mpeg2enc_update_slice_parameter(ctx, picture_type);
+
+    return 0;
+}
+
+static int 
+mpeg2enc_render_picture(struct mpeg2enc_context *ctx)
+{
+    VAStatus va_status;
+    VABufferID va_buffers[16];
+    unsigned int num_va_buffers = 0;
+
+    va_buffers[num_va_buffers++] = ctx->seq_param_buf_id;
+    va_buffers[num_va_buffers++] = ctx->pic_param_buf_id;
+
+    if (ctx->packed_seq_header_param_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = ctx->packed_seq_header_param_buf_id;
+
+    if (ctx->packed_seq_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = ctx->packed_seq_buf_id;
+
+    if (ctx->packed_pic_header_param_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = ctx->packed_pic_header_param_buf_id;
+
+    if (ctx->packed_pic_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] = ctx->packed_pic_buf_id;
+
+    va_status = vaBeginPicture(ctx->va_dpy,
+                               ctx->context_id,
+                               surface_ids[ctx->current_input_surface]);
+    CHECK_VASTATUS(va_status,"vaBeginPicture");
+
+    va_status = vaRenderPicture(ctx->va_dpy,
+                                ctx->context_id,
+                                va_buffers,
+                                num_va_buffers);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+
+    va_status = vaRenderPicture(ctx->va_dpy,
+                                ctx->context_id,
+                                &ctx->slice_param_buf_id[0],
+                                ctx->num_slice_groups);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+
+    va_status = vaEndPicture(ctx->va_dpy, ctx->context_id);
+    CHECK_VASTATUS(va_status,"vaEndPicture");
+
+    return 0;
+}
+
+static int 
+mpeg2enc_destroy_buffers(struct mpeg2enc_context *ctx, VABufferID *va_buffers, unsigned int num_va_buffers)
+{
+    VAStatus va_status;
+    unsigned int i;
+
+    for (i = 0; i < num_va_buffers; i++) {
+        if (va_buffers[i] != VA_INVALID_ID) {
+            va_status = vaDestroyBuffer(ctx->va_dpy, va_buffers[i]);
+            CHECK_VASTATUS(va_status,"vaDestroyBuffer");
+            va_buffers[i] = VA_INVALID_ID;
+        }
+    }
+
+    return 0;
+}
+
+static void
+end_picture(struct mpeg2enc_context *ctx, VAEncPictureType picture_type, int next_is_bpic)
+{
+    VABufferID tempID;
+
+    /* Prepare for next picture */
+    tempID = surface_ids[SID_RECON_PICTURE];  
+
+    if (picture_type != VAEncPictureTypeBidirectional) {
+        if (next_is_bpic) {
+            surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE_L1]; 
+            surface_ids[SID_REFERENCE_PICTURE_L1] = tempID;	
+        } else {
+            surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE_L0]; 
+            surface_ids[SID_REFERENCE_PICTURE_L0] = tempID;
+        }
+    } else {
+        if (!next_is_bpic) {
+            surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE_L0]; 
+            surface_ids[SID_REFERENCE_PICTURE_L0] = surface_ids[SID_REFERENCE_PICTURE_L1];
+            surface_ids[SID_REFERENCE_PICTURE_L1] = tempID;
+        }
+    }
+
+    mpeg2enc_destroy_buffers(ctx, &ctx->seq_param_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->pic_param_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->packed_seq_header_param_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->packed_seq_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->packed_pic_header_param_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->packed_pic_buf_id, 1);
+    mpeg2enc_destroy_buffers(ctx, &ctx->slice_param_buf_id[0], ctx->num_slice_groups);
+    mpeg2enc_destroy_buffers(ctx, &ctx->codedbuf_buf_id, 1);
+    memset(ctx->slice_param, 0, sizeof(ctx->slice_param));
+    ctx->num_slice_groups = 0;
+}
+
+static int
+store_coded_buffer(struct mpeg2enc_context *ctx, VAEncPictureType picture_type)
+{
+    VACodedBufferSegment *coded_buffer_segment;
+    unsigned char *coded_mem;
+    int slice_data_length;
+    VAStatus va_status;
+    VASurfaceStatus surface_status;
+    size_t w_items;
+
+    va_status = vaSyncSurface(ctx->va_dpy, surface_ids[ctx->current_input_surface]);
+    CHECK_VASTATUS(va_status,"vaSyncSurface");
+
+    surface_status = 0;
+    va_status = vaQuerySurfaceStatus(ctx->va_dpy, surface_ids[ctx->current_input_surface], &surface_status);
+    CHECK_VASTATUS(va_status,"vaQuerySurfaceStatus");
+
+    va_status = vaMapBuffer(ctx->va_dpy, ctx->codedbuf_buf_id, (void **)(&coded_buffer_segment));
+    CHECK_VASTATUS(va_status,"vaMapBuffer");
+    coded_mem = coded_buffer_segment->buf;
+
+    if (coded_buffer_segment->status & VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK) {
+        if (picture_type == VAEncPictureTypeIntra)
+            ctx->codedbuf_i_size *= 2;
+        else
+            ctx->codedbuf_pb_size *= 2;
+
+        vaUnmapBuffer(ctx->va_dpy, ctx->codedbuf_buf_id);
+        return -1;
+    }
+
+    slice_data_length = coded_buffer_segment->size;
+
+    do {
+        w_items = fwrite(coded_mem, slice_data_length, 1, ctx->ofp);
+    } while (w_items != 1);
+
+    if (picture_type == VAEncPictureTypeIntra) {
+        if (ctx->codedbuf_i_size > slice_data_length * 3 / 2) {
+            ctx->codedbuf_i_size = slice_data_length * 3 / 2;
+        }
+        
+        if (ctx->codedbuf_pb_size < slice_data_length) {
+            ctx->codedbuf_pb_size = slice_data_length;
+        }
+    } else {
+        if (ctx->codedbuf_pb_size > slice_data_length * 3 / 2) {
+            ctx->codedbuf_pb_size = slice_data_length * 3 / 2;
+        }
+    }
+
+    vaUnmapBuffer(ctx->va_dpy, ctx->codedbuf_buf_id);
+
+    return 0;
+}
+
+static void
+encode_picture(struct mpeg2enc_context *ctx,
+               int coded_order,
+               int display_order,
+               VAEncPictureType picture_type,
+               int next_is_bpic,
+               int next_display_order)
+{
+    VAStatus va_status;
+    int ret = 0, codedbuf_size;
+    
+    begin_picture(ctx, coded_order, display_order, picture_type);
+
+    if (1) {
+        /* upload YUV data to VA surface for next frame */
+        if (next_display_order >= ctx->num_pictures)
+            next_display_order = ctx->num_pictures - 1;
+
+        fseek(ctx->ifp, ctx->frame_size * next_display_order, SEEK_SET);
+        ctx->upload_thread_value = pthread_create(&ctx->upload_thread_id,
+                                                  NULL,
+                                                  upload_yuv_to_surface,
+                                                  ctx);
+    }
+
+    do {
+        mpeg2enc_destroy_buffers(ctx, &ctx->codedbuf_buf_id, 1);
+        mpeg2enc_destroy_buffers(ctx, &ctx->pic_param_buf_id, 1);
+
+
+        if (VAEncPictureTypeIntra == picture_type) {
+            codedbuf_size = ctx->codedbuf_i_size;
+        } else {
+            codedbuf_size = ctx->codedbuf_pb_size;
+        }
+
+        /* coded buffer */
+        va_status = vaCreateBuffer(ctx->va_dpy,
+                                   ctx->context_id,
+                                   VAEncCodedBufferType,
+                                   codedbuf_size, 1, NULL,
+                                   &ctx->codedbuf_buf_id);
+        CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+        /* picture parameter set */
+        mpeg2enc_update_picture_parameter_buffer(ctx, picture_type, coded_order, display_order);
+
+        mpeg2enc_render_picture(ctx);
+
+        ret = store_coded_buffer(ctx, picture_type);
+    } while (ret);
+
+    end_picture(ctx, picture_type, next_is_bpic);
+}
+
+static void
+update_next_frame_info(struct mpeg2enc_context *ctx,
+                       VAEncPictureType curr_type,
+                       int curr_coded_order,
+                       int curr_display_order)
+{
+    if (((curr_coded_order + 1) % ctx->intra_period) == 0) {
+        ctx->next_type = VAEncPictureTypeIntra;
+        ctx->next_display_order = curr_coded_order + 1;
+        
+        return;
+    }
+
+    if (curr_type == VAEncPictureTypeIntra) {
+        assert(curr_display_order == curr_coded_order);
+        ctx->next_type = VAEncPictureTypePredictive;
+        ctx->next_bframes = ctx->ip_period;
+        ctx->next_display_order = curr_display_order + ctx->next_bframes + 1;
+    } else if (curr_type == VAEncPictureTypePredictive) {
+        if (ctx->ip_period == 0) {
+            assert(curr_display_order == curr_coded_order);
+            ctx->next_type = VAEncPictureTypePredictive;
+            ctx->next_display_order = curr_display_order + 1;
+        } else {
+            ctx->next_type = VAEncPictureTypeBidirectional;
+            ctx->next_display_order = curr_display_order - ctx->next_bframes;
+            ctx->next_bframes--;
+        }
+    } else if (curr_type == VAEncPictureTypeBidirectional) {
+        if (ctx->next_bframes == 0) {
+            ctx->next_type = VAEncPictureTypePredictive;
+            ctx->next_bframes = ctx->ip_period;
+            ctx->next_display_order = curr_display_order + ctx->next_bframes + 2;
+        } else {
+            ctx->next_type = VAEncPictureTypeBidirectional;
+            ctx->next_display_order = curr_display_order + 1;
+            ctx->next_bframes--;
+        }
+    }
+
+    if (ctx->next_display_order >= ctx->num_pictures) {
+        int rtmp = ctx->next_display_order - (ctx->num_pictures - 1);
+        ctx->next_display_order = ctx->num_pictures - 1;
+        ctx->next_bframes -= rtmp;
+    }
+}
+
+static void
+mpeg2enc_run(struct mpeg2enc_context *ctx)
+{
+    int display_order = 0, coded_order = 0;
+    VAEncPictureType type;
+
+    ctx->new_sequence = 1;
+    ctx->new_gop_header = 1;
+    ctx->gop_header_in_display_order = display_order;
+
+    while (coded_order < ctx->num_pictures) {
+        type = ctx->next_type;
+        display_order = ctx->next_display_order;
+        /* follow the IPBxxBPBxxB mode */
+        update_next_frame_info(ctx, type, coded_order, display_order);
+        encode_picture(ctx,
+                       coded_order,
+                       display_order,
+                       type,
+                       ctx->next_type == VAEncPictureTypeBidirectional,
+                       ctx->next_display_order);
+
+        /* update gop_header */
+        ctx->new_sequence = 0;
+        ctx->new_gop_header = ctx->next_type == VAEncPictureTypeIntra;
+
+        if (ctx->new_gop_header)
+            ctx->gop_header_in_display_order += ctx->intra_period;
+
+        coded_order++;
+
+        fprintf(stderr, "\r %d/%d ...", coded_order, ctx->num_pictures);
+        fflush(stdout);
+    }
+}
+
+/*
+ * end
+ */
+static void
+mpeg2enc_release_va_resources(struct mpeg2enc_context *ctx)
+{
+    vaDestroySurfaces(ctx->va_dpy, surface_ids, SID_NUMBER);	
+    vaDestroyContext(ctx->va_dpy, ctx->context_id);
+    vaDestroyConfig(ctx->va_dpy, ctx->config_id);
+    vaTerminate(ctx->va_dpy);
+    va_close_display(ctx->va_dpy);
+}
+
+static void
+mpeg2enc_end(struct mpeg2enc_context *ctx)
+{
+    pthread_join(ctx->upload_thread_id, NULL);
+    mpeg2enc_release_va_resources(ctx);
+}
+
+int 
+main(int argc, char *argv[])
+{
+    struct mpeg2enc_context ctx;
+    struct timeval tpstart, tpend; 
+    float timeuse;
+
+    gettimeofday(&tpstart, NULL);
+
+    memset(&ctx, 0, sizeof(ctx));
+    parse_args(&ctx, argc, argv);
+    mpeg2enc_init(&ctx);
+    mpeg2enc_run(&ctx);
+    mpeg2enc_end(&ctx);
+
+    gettimeofday(&tpend, NULL);
+    timeuse = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec;
+    timeuse /= 1000000;
+    fprintf(stderr, "\ndone!\n");
+    fprintf(stderr, "encode %d frames in %f secondes, FPS is %.1f\n", ctx.num_pictures, timeuse, ctx.num_pictures / timeuse);
+
+    mpeg2enc_exit(&ctx, 0);
+
+    return 0;
+}
diff --git a/test/loadsurface.h b/test/loadsurface.h
old mode 100644
new mode 100755
index ce2f630..cd08e6a
--- a/test/loadsurface.h
+++ b/test/loadsurface.h
@@ -24,7 +24,7 @@
 #include "loadsurface_yuv.h"
 
 static int scale_2dimage(unsigned char *src_img, int src_imgw, int src_imgh,
-                  unsigned char *dst_img, int dst_imgw, int dst_imgh)
+                         unsigned char *dst_img, int dst_imgw, int dst_imgh)
 {
     int row=0, col=0;
 
@@ -39,10 +39,10 @@
 
 
 static int YUV_blend_with_pic(int width, int height,
-                  unsigned char *Y_start, int Y_pitch,
-		  unsigned char *U_start, int U_pitch,
-                  unsigned char *V_start, int V_pitch,
-		  int UV_interleave, int fixed_alpha)
+                              unsigned char *Y_start, int Y_pitch,
+                              unsigned char *U_start, int U_pitch,
+                              unsigned char *V_start, int V_pitch,
+                              unsigned int fourcc, int fixed_alpha)
 {
     /* PIC YUV format */
     unsigned char *pic_y_old = yuvga_pic;
@@ -88,41 +88,49 @@
     /* begin blend */
 
     /* Y plane */
-    for (row=0; row<height; row++) 
-        for (col=0; col<width; col++) {
-            unsigned char *p = Y_start + row * Y_pitch + col;
-            unsigned char *q = pic_y + row * width + col;
-            
+    int Y_pixel_stride = 1;
+    if (fourcc == VA_FOURCC_YUY2) 
+        Y_pixel_stride = 2;
+         
+    for (row=0; row<height; row++) {
+        unsigned char *p = Y_start + row * Y_pitch;
+        unsigned char *q = pic_y + row * width;
+        for (col=0; col<width; col++, q++) {
             *p  = *p * (100 - alpha) / 100 + *q * alpha/100;
+            p += Y_pixel_stride;
         }
+    }
 
-    if (UV_interleave == 0) {
-        for (row=0; row<height/2; row++) 
-            for (col=0; col<width/2; col++) {
-                unsigned char *p = U_start + row * U_pitch + col;
-                unsigned char *q = pic_u + row * width/2 + col;
+    /* U/V plane */
+    int U_pixel_stride = 0, V_pixel_stride = 0;
+    int v_factor_to_nv12 = 1;
+    switch (fourcc) {
+    case VA_FOURCC_YV12:
+        U_pixel_stride = V_pixel_stride = 1;
+        break;
+    case VA_FOURCC_NV12:
+        U_pixel_stride = V_pixel_stride = 2;
+        break;
+    case VA_FOURCC_YUY2:
+        U_pixel_stride = V_pixel_stride = 4;
+        v_factor_to_nv12 = 2;
+        break;
+    default:
+        break;
+    }
+    for (row=0; row<height/2*v_factor_to_nv12; row++) {
+        unsigned char *pU = U_start + row * U_pitch;
+        unsigned char *pV = V_start + row * V_pitch;
+        unsigned char *qU = pic_u + row/v_factor_to_nv12 * width/2;
+        unsigned char *qV = pic_v + row/v_factor_to_nv12 * width/2;
             
-                *p  = *p * (100 - alpha) / 100 + *q * alpha/100;
-            }
-    
-        for (row=0; row<height/2; row++) 
-            for (col=0; col<width/2; col++) {
-                unsigned char *p = V_start + row * V_pitch + col;
-                unsigned char *q = pic_v + row * width/2 + col;
-            
-                *p  = *p * (100 - alpha) / 100 + *q * alpha/100;
-            }
-    }  else { /* NV12 */
-        for (row=0; row<height/2; row++) 
-            for (col=0; col<width/2; col++) {
-                unsigned char *pU = U_start + row * U_pitch + col*2;
-                unsigned char *qU = pic_u + row * width/2 + col;
-                unsigned char *pV = pU + 1;
-                unsigned char *qV = pic_v + row * width/2 + col;
-            
-                *pU  = *pU * (100 - alpha) / 100 + *qU * alpha/100;
-                *pV  = *pV * (100 - alpha) / 100 + *qV * alpha/100;
-            }
+        for (col=0; col<width/2; col++, qU++, qV++) {
+            *pU  = *pU * (100 - alpha) / 100 + *qU * alpha/100;
+            *pV  = *pV * (100 - alpha) / 100 + *qV * alpha/100;
+
+            pU += U_pixel_stride;
+            pV += V_pixel_stride;
+        }
     }
         
     
@@ -139,12 +147,15 @@
                          unsigned char *Y_start, int Y_pitch,
                          unsigned char *U_start, int U_pitch,
                          unsigned char *V_start, int V_pitch,
-                         int UV_interleave, int box_width, int row_shift,
+                         unsigned int fourcc, int box_width, int row_shift,
                          int field)
 {
     int row, alpha;
+    unsigned char uv_value = 0x80;
 
     /* copy Y plane */
+    int y_factor = 1;
+    if (fourcc == VA_FOURCC_YUY2) y_factor = 2;
     for (row=0;row<height;row++) {
         unsigned char *Y_row = Y_start + row * Y_pitch;
         int jj, xpos, ypos;
@@ -160,43 +171,46 @@
         
         for (jj=0; jj<width; jj++) {
             xpos = ((row_shift + jj) / box_width) & 0x1;
-                        
-            if ((xpos == 0) && (ypos == 0))
-                Y_row[jj] = 0xeb;
-            if ((xpos == 1) && (ypos == 1))
-                Y_row[jj] = 0xeb;
-                        
-            if ((xpos == 1) && (ypos == 0))
-                Y_row[jj] = 0x10;
-            if ((xpos == 0) && (ypos == 1))
-                Y_row[jj] = 0x10;
+            if (xpos == ypos)
+                Y_row[jj*y_factor] = 0xeb;
+            else 
+                Y_row[jj*y_factor] = 0x10;
+
+            if (fourcc == VA_FOURCC_YUY2) {
+                Y_row[jj*y_factor+1] = uv_value; // it is for UV
+            }
         }
     }
   
     /* copy UV data */
     for( row =0; row < height/2; row++) {
-        unsigned short value = 0x80;
 
         /* fill garbage data into the other field */
         if (((field == VA_TOP_FIELD) && (row &1))
             || ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) {
-            value = 0xff;
+            uv_value = 0xff;
         }
 
-        if (UV_interleave) {
-            unsigned short *UV_row = (unsigned short *)(U_start + row * U_pitch);
-
-            memset(UV_row, value, width);
-        } else {
-            unsigned char *U_row = U_start + row * U_pitch;
-            unsigned char *V_row = V_start + row * V_pitch;
-            
-            memset (U_row,value,width/2);
-            memset (V_row,value,width/2);
+        unsigned char *U_row = U_start + row * U_pitch;
+        unsigned char *V_row = V_start + row * V_pitch;
+        switch (fourcc) {
+        case VA_FOURCC_NV12:
+            memset(U_row, uv_value, width);
+            break;
+        case VA_FOURCC_YV12:
+            memset (U_row,uv_value,width/2);
+            memset (V_row,uv_value,width/2);
+            break;
+        case VA_FOURCC_YUY2:
+            // see above. it is set with Y update.
+            break;
+        default:
+            printf("unsupported fourcc in loadsurface.h\n");
+            assert(0);
         }
     }
 
-    if (getenv("AUTO_NOUV"))
+    if (getenv("AUTO_UV") == 0)
         return 0;
 
     if (getenv("AUTO_ALPHA"))
@@ -208,7 +222,7 @@
                        Y_start, Y_pitch,
                        U_start, U_pitch,
                        V_start, V_pitch,
-                       UV_interleave, alpha);
+                       fourcc, alpha);
     
     return 0;
 }
@@ -218,24 +232,52 @@
                           int field)
 {
     VAImage surface_image;
-    void *surface_p=NULL, *U_start,*V_start;
+    void *surface_p=NULL, *U_start = NULL,*V_start = NULL;
     VAStatus va_status;
+    unsigned int pitches[3]={0,0,0};
     
     va_status = vaDeriveImage(va_dpy,surface_id,&surface_image);
     CHECK_VASTATUS(va_status,"vaDeriveImage");
 
     vaMapBuffer(va_dpy,surface_image.buf,&surface_p);
     assert(VA_STATUS_SUCCESS == va_status);
-        
-    U_start = (char *)surface_p + surface_image.offsets[1];
-    V_start = (char *)surface_p + surface_image.offsets[2];
+
+    pitches[0] = surface_image.pitches[0];
+    switch (surface_image.format.fourcc) {
+    case VA_FOURCC_NV12:
+        U_start = (char *)surface_p + surface_image.offsets[1];
+        V_start = (char *)U_start + 1;
+        pitches[1] = surface_image.pitches[1];
+        pitches[2] = surface_image.pitches[1];
+        break;
+    case VA_FOURCC_IYUV:
+        U_start = (char *)surface_p + surface_image.offsets[1];
+        V_start = (char *)surface_p + surface_image.offsets[2];
+        pitches[1] = surface_image.pitches[1];
+        pitches[2] = surface_image.pitches[2];
+        break;
+    case VA_FOURCC_YV12:
+        U_start = (char *)surface_p + surface_image.offsets[2];
+        V_start = (char *)surface_p + surface_image.offsets[1];
+        pitches[1] = surface_image.pitches[2];
+        pitches[2] = surface_image.pitches[1];
+        break;
+    case VA_FOURCC_YUY2:
+        U_start = (char *)surface_p + 1;
+        V_start = (char *)surface_p + 3;
+        pitches[1] = surface_image.pitches[0];
+        pitches[2] = surface_image.pitches[0];
+        break;
+    default:
+        assert(0);
+    }
 
     /* assume surface is planar format */
     yuvgen_planar(surface_image.width, surface_image.height,
-                  (unsigned char *)surface_p, surface_image.pitches[0],
-                  (unsigned char *)U_start, surface_image.pitches[1],
-                  (unsigned char *)V_start, surface_image.pitches[2],
-                  (surface_image.format.fourcc==VA_FOURCC_NV12),
+                  (unsigned char *)surface_p, pitches[0],
+                  (unsigned char *)U_start, pitches[1],
+                  (unsigned char *)V_start, pitches[2],
+                  surface_image.format.fourcc,
                   box_width, row_shift, field);
         
     vaUnmapBuffer(va_dpy,surface_image.buf);
@@ -245,30 +287,93 @@
     return 0;
 }
 
-
-static int upload_surface_attrib(VADisplay va_dpy, VASurfaceID surface_id,
-                          int box_width, int row_shift,
-                          int field, unsigned int *addr)
+/*
+ * Upload YUV data from memory into a surface
+ * if src_fourcc == NV12, assume the buffer pointed by src_U
+ * is UV interleaved (src_V is ignored)
+ */
+static int upload_surface_yuv(VADisplay va_dpy, VASurfaceID surface_id,
+                              int src_fourcc, int src_width, int src_height,
+                              unsigned char *src_Y, unsigned char *src_U, unsigned char *src_V)
 {
     VAImage surface_image;
-    void *surface_p=NULL, *U_start,*V_start;
+    unsigned char *surface_p=NULL, *Y_start=NULL, *U_start=NULL, *V_start=NULL;
+    int Y_pitch=0, U_pitch=0, V_pitch=0, row;
     VAStatus va_status;
     
-    va_status = vaDeriveImage(va_dpy,surface_id,&surface_image);
+    va_status = vaDeriveImage(va_dpy,surface_id, &surface_image);
     CHECK_VASTATUS(va_status,"vaDeriveImage");
 
-    surface_p = addr;
-    U_start = (char *)surface_p + surface_image.offsets[1];
-    V_start = (char *)surface_p + surface_image.offsets[2];
+    vaMapBuffer(va_dpy,surface_image.buf,(void **)&surface_p);
+    assert(VA_STATUS_SUCCESS == va_status);
 
-    /* assume surface is planar format */
-    yuvgen_planar(surface_image.width, surface_image.height,
-                  (unsigned char *)surface_p, surface_image.pitches[0],
-                  (unsigned char *)U_start, surface_image.pitches[1],
-                  (unsigned char *)V_start, surface_image.pitches[2],
-                  (surface_image.format.fourcc==VA_FOURCC_NV12),
-                  box_width, row_shift, field);
-        
+    Y_start = surface_p;
+    Y_pitch = surface_image.pitches[0];
+    switch (surface_image.format.fourcc) {
+    case VA_FOURCC_NV12:
+        U_start = (unsigned char *)surface_p + surface_image.offsets[1];
+        V_start = U_start + 1;
+        U_pitch = surface_image.pitches[1];
+        V_pitch = surface_image.pitches[1];
+        break;
+    case VA_FOURCC_IYUV:
+        U_start = (unsigned char *)surface_p + surface_image.offsets[1];
+        V_start = (unsigned char *)surface_p + surface_image.offsets[2];
+        U_pitch = surface_image.pitches[1];
+        V_pitch = surface_image.pitches[2];
+        break;
+    case VA_FOURCC_YV12:
+        U_start = (unsigned char *)surface_p + surface_image.offsets[2];
+        V_start = (unsigned char *)surface_p + surface_image.offsets[1];
+        U_pitch = surface_image.pitches[2];
+        V_pitch = surface_image.pitches[1];
+        break;
+    case VA_FOURCC_YUY2:
+        U_start = surface_p + 1;
+        V_start = surface_p + 3;
+        U_pitch = surface_image.pitches[0];
+        V_pitch = surface_image.pitches[0];
+        break;
+    default:
+        assert(0);
+    }
+
+    /* copy Y plane */
+    for (row=0;row<src_height;row++) {
+        unsigned char *Y_row = Y_start + row * Y_pitch;
+        memcpy(Y_row, src_Y + row*src_width, src_width);
+    }
+  
+    for (row =0; row < src_height/2; row++) {
+        unsigned char *U_row = U_start + row * U_pitch;
+        unsigned char *u_ptr = NULL, *v_ptr=NULL;
+        int j;
+        switch (surface_image.format.fourcc) {
+        case VA_FOURCC_NV12:
+            if (src_fourcc == VA_FOURCC_NV12) {
+                memcpy(U_row, src_U + row * src_width, src_width);
+                break;
+            } else if (src_fourcc == VA_FOURCC_IYUV) {
+                u_ptr = src_U + row * (src_width/2);
+                v_ptr = src_V + row * (src_width/2);
+            } else if (src_fourcc == VA_FOURCC_YV12) {
+                v_ptr = src_U + row * (src_width/2);
+                u_ptr = src_V + row * (src_width/2);
+            }
+            for(j = 0; j < src_width/2; j++) {
+                U_row[2*j] = u_ptr[j];
+                U_row[2*j+1] = v_ptr[j];
+            }
+            break;
+        case VA_FOURCC_IYUV:
+        case VA_FOURCC_YV12:
+        case VA_FOURCC_YUY2:
+        default:
+            printf("unsupported fourcc in load_surface_yuv\n");
+            assert(0);
+        }
+    }
+    
     vaUnmapBuffer(va_dpy,surface_image.buf);
 
     vaDestroyImage(va_dpy,surface_image.image_id);
@@ -276,3 +381,100 @@
     return 0;
 }
 
+/*
+ * Download YUV data from a surface into memory
+ * Some hardward doesn't have a aperture for linear access of
+ * tiled surface, thus use vaGetImage to expect the implemnetion
+ * to do tile to linear convert
+ * 
+ * if dst_fourcc == NV12, assume the buffer pointed by dst_U
+ * is UV interleaved (src_V is ignored)
+ */
+static int download_surface_yuv(VADisplay va_dpy, VASurfaceID surface_id,
+                                int dst_fourcc, int dst_width, int dst_height,
+                                unsigned char *dst_Y, unsigned char *dst_U, unsigned char *dst_V)
+{
+    VAImage surface_image;
+    unsigned char *surface_p=NULL, *Y_start=NULL, *U_start=NULL,*V_start=NULL;
+    int Y_pitch=0, U_pitch=0, V_pitch=0, row;
+    VAStatus va_status;
+    
+    va_status = vaDeriveImage(va_dpy,surface_id, &surface_image);
+    CHECK_VASTATUS(va_status,"vaDeriveImage");
+
+    vaMapBuffer(va_dpy,surface_image.buf,(void **)&surface_p);
+    assert(VA_STATUS_SUCCESS == va_status);
+
+    Y_start = surface_p;
+    Y_pitch = surface_image.pitches[0];
+    switch (surface_image.format.fourcc) {
+    case VA_FOURCC_NV12:
+        U_start = (unsigned char *)surface_p + surface_image.offsets[1];
+        V_start = U_start + 1;
+        U_pitch = surface_image.pitches[1];
+        V_pitch = surface_image.pitches[1];
+        break;
+    case VA_FOURCC_IYUV:
+        U_start = (unsigned char *)surface_p + surface_image.offsets[1];
+        V_start = (unsigned char *)surface_p + surface_image.offsets[2];
+        U_pitch = surface_image.pitches[1];
+        V_pitch = surface_image.pitches[2];
+        break;
+    case VA_FOURCC_YV12:
+        U_start = (unsigned char *)surface_p + surface_image.offsets[2];
+        V_start = (unsigned char *)surface_p + surface_image.offsets[1];
+        U_pitch = surface_image.pitches[2];
+        V_pitch = surface_image.pitches[1];
+        break;
+    case VA_FOURCC_YUY2:
+        U_start = surface_p + 1;
+        V_start = surface_p + 3;
+        U_pitch = surface_image.pitches[0];
+        V_pitch = surface_image.pitches[0];
+        break;
+    default:
+        assert(0);
+    }
+
+    /* copy Y plane */
+    for (row=0;row<dst_height;row++) {
+        unsigned char *Y_row = Y_start + row * Y_pitch;
+        memcpy(dst_Y + row*dst_width, Y_row, dst_width);
+    }
+  
+    for (row =0; row < dst_height/2; row++) {
+        unsigned char *U_row = U_start + row * U_pitch;
+        unsigned char *u_ptr = NULL, *v_ptr = NULL;
+        int j;
+        switch (surface_image.format.fourcc) {
+        case VA_FOURCC_NV12:
+            if (dst_fourcc == VA_FOURCC_NV12) {
+                memcpy(dst_U + row * dst_width, U_row, dst_width);
+                break;
+            } else if (dst_fourcc == VA_FOURCC_IYUV) {
+                u_ptr = dst_U + row * (dst_width/2);
+                v_ptr = dst_V + row * (dst_width/2);
+            } else if (dst_fourcc == VA_FOURCC_YV12) {
+                v_ptr = dst_U + row * (dst_width/2);
+                u_ptr = dst_V + row * (dst_width/2);
+            }
+            for(j = 0; j < dst_width/2; j++) {
+                u_ptr[j] = U_row[2*j];
+                v_ptr[j] = U_row[2*j+1];
+            }
+            break;
+        case VA_FOURCC_IYUV:
+        case VA_FOURCC_YV12:
+        case VA_FOURCC_YUY2:
+        default:
+            printf("unsupported fourcc in load_surface_yuv\n");
+            assert(0);
+        }
+    }
+    
+    vaUnmapBuffer(va_dpy,surface_image.buf);
+
+    vaDestroyImage(va_dpy,surface_image.image_id);
+
+    return 0;
+}
diff --git a/test/putsurface/Android.mk b/test/putsurface/Android.mk
index cce0b63..628492d 100644
--- a/test/putsurface/Android.mk
+++ b/test/putsurface/Android.mk
@@ -10,7 +10,7 @@
   #putsurface_x11.c
 
 LOCAL_CFLAGS += \
-    -DANDROID  
+    -DANDROID -Wno-unused-parameter
 
 LOCAL_C_INCLUDES += \
   $(TARGET_OUT_HEADERS)/libva
@@ -18,7 +18,7 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := putsurface
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libui libsurfaceflinger_client
+LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libgui
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/test/putsurface/Makefile.am b/test/putsurface/Makefile.am
index fbf23d3..15b3348 100644
--- a/test/putsurface/Makefile.am
+++ b/test/putsurface/Makefile.am
@@ -22,12 +22,34 @@
 
 bin_PROGRAMS = putsurface
 
-INCLUDES = -I$(top_srcdir)
+INCLUDES = \
+	-I$(top_srcdir)		\
+	-I$(top_builddir)	\
+	$(NULL)
 
-TEST_LIBS = $(top_builddir)/va/$(libvabackendlib) $(top_builddir)/va/$(libvacorelib) -lpthread -lX11
+TEST_CFLAGS = \
+	-DIN_LIBVA		\
+	$(NULL)
 
-putsurface_LDADD = $(TEST_LIBS)
-putsurface_SOURCES = putsurface_x11.c
+TEST_LIBS = \
+	$(top_builddir)/va/libva.la \
+	-lpthread		\
+	$(NULL)
+
+putsurface_SOURCES		= putsurface_x11.c
+putsurface_CFLAGS		= $(X11_CFLAGS) $(TEST_CFLAGS)
+putsurface_LDADD		= $(X11_LIBS) $(TEST_LIBS)	\
+	$(top_builddir)/va/libva-x11.la			\
+	$(NULL)
+
+if USE_WAYLAND
+bin_PROGRAMS			+= putsurface_wayland
+putsurface_wayland_SOURCES	= putsurface_wayland.c
+putsurface_wayland_CFLAGS	= $(WAYLAND_CFLAGS) $(TEST_CFLAGS)
+putsurface_wayland_LDADD	= $(WAYLAND_LIBS) $(TEST_LIBS)	\
+	$(top_builddir)/va/libva-wayland.la			\
+	$(NULL)
+endif
 
 EXTRA_DIST = putsurface_common.c
 
diff --git a/test/putsurface/putsurface_android.cpp b/test/putsurface/putsurface_android.cpp
index 8b70480..b4e0a92 100644
--- a/test/putsurface/putsurface_android.cpp
+++ b/test/putsurface/putsurface_android.cpp
@@ -24,39 +24,30 @@
 #include <stdio.h>
 #include <va/va.h>
 #include <va/va_android.h>
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <binder/MemoryHeapBase.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/ISurfaceComposer.h>
 #include <assert.h>
 #include <pthread.h>
 
+using namespace android;
+
 static  int android_display=0;
 
-using namespace android;
-#include "../android_winsys.cpp"
+static sp<SurfaceComposerClient> client0 = NULL;
+static sp<SurfaceControl> surface_ctrl0 = NULL;
+static sp<ANativeWindow> anw0 = NULL;
 
-sp<SurfaceComposerClient> client;
-sp<Surface> android_surface;
-sp<ISurface> android_isurface;
-sp<SurfaceControl> surface_ctrl;
-
-sp<SurfaceComposerClient> client1;
-sp<Surface> android_surface1;
-sp<ISurface> android_isurface1;
-sp<SurfaceControl> surface_ctrl1;
+static sp<SurfaceComposerClient> client1 = NULL;
+static sp<SurfaceControl> surface_ctrl1 = NULL;
+static sp<ANativeWindow> anw1 = NULL;
 
 static void *open_display(void);
 static void close_display(void *win_display);
 static int create_window(void *win_display, int x, int y, int width, int height);
 static int check_window_event(void *x11_display, void *win, int *width, int *height, int *quit);
 
-#define CAST_DRAWABLE(a)  static_cast<ISurface*>((void *)(*(unsigned int *)a))
+#define CAST_DRAWABLE(a)  static_cast<ANativeWindow *>((void *)(*(unsigned int *)a))
 #include "putsurface_common.c"
 
 static void *open_display()
@@ -71,20 +62,56 @@
 
 static int create_window(void *win_display, int x, int y, int width, int height)
 {
-    sp<ProcessState> proc(ProcessState::self());
-    ProcessState::self()->startThreadPool();
+    client0 = new SurfaceComposerClient();
+    
+    surface_ctrl0 = client1->createSurface(
+        String8("Test Surface"),
+        width, height,
+        PIXEL_FORMAT_RGB_888, 0);
 
-    printf("Create window0 for thread0\n");
-    SURFACE_CREATE(client,surface_ctrl,android_surface, android_isurface, x, y, width, height);
+    SurfaceComposerClient::openGlobalTransaction();
+    surface_ctrl0->setLayer(0x7FFFFFFF);
+    surface_ctrl0->show();
+    SurfaceComposerClient::closeGlobalTransaction();
+    
+    SurfaceComposerClient::openGlobalTransaction();
+    surface_ctrl0->setPosition(x, y);
+    SurfaceComposerClient::closeGlobalTransaction();
+    
+    SurfaceComposerClient::openGlobalTransaction();
+    surface_ctrl0->setSize(width, height);
+    SurfaceComposerClient::closeGlobalTransaction();
+    
+    anw0 = surface_ctrl0->getSurface();
 
-    drawable_thread0 = static_cast<void*>(&android_isurface);
+    drawable_thread0 = static_cast<void*>(&anw0);
     if (multi_thread == 0)
         return 0;
 
     printf("Create window1 for thread1\n");
-    /* need to modify here jgl*/
-    SURFACE_CREATE(client1,surface_ctrl1,android_surface1, android_isurface1, x, y, width, height);
-    drawable_thread1 = static_cast<void *>(&android_isurface);
+    client1 = new SurfaceComposerClient();
+    
+    surface_ctrl1 = client1->createSurface(
+        String8("Test Surface"),
+        width, height,
+        PIXEL_FORMAT_RGB_888, 0);
+
+    SurfaceComposerClient::openGlobalTransaction();
+    surface_ctrl1->setLayer(0x7FFFFFFF);
+    surface_ctrl1->show();
+    SurfaceComposerClient::closeGlobalTransaction();
+    
+    SurfaceComposerClient::openGlobalTransaction();
+    surface_ctrl1->setPosition(x*2, y*2);
+    SurfaceComposerClient::closeGlobalTransaction();
+    
+    SurfaceComposerClient::openGlobalTransaction();
+    surface_ctrl1->setSize(width, height);
+    SurfaceComposerClient::closeGlobalTransaction();
+    
+    anw1 = surface_ctrl1->getSurface();
+
+    drawable_thread1 = static_cast<void *>(&anw1);
     
     return 0;
 }
diff --git a/test/putsurface/putsurface_common.c b/test/putsurface/putsurface_common.c
old mode 100644
new mode 100755
index 54ae8d3..d7d7003
--- a/test/putsurface/putsurface_common.c
+++ b/test/putsurface/putsurface_common.c
@@ -8,11 +8,11 @@
  * 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.
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <getopt.h>
 
 #include <sys/time.h>
@@ -59,6 +60,11 @@
 
 static  void *win_display;
 static  VADisplay va_dpy;
+static  VAImageFormat *va_image_formats;
+static  int va_num_image_formats = -1;
+static  VAConfigID vpp_config_id = VA_INVALID_ID;
+static  VASurfaceAttrib *va_surface_attribs;
+static  int va_num_surface_attribs = -1;
 static  VASurfaceID surface_id[SURFACE_NUM];
 static  pthread_mutex_t surface_mutex[SURFACE_NUM];
 
@@ -76,6 +82,235 @@
 static  int box_width = 32;
 static  int multi_thread = 0;
 static  int verbose = 0;
+static  int test_color_conversion = 0;
+static  unsigned int csc_src_fourcc = 0, csc_dst_fourcc = 0;
+static  VAImage csc_dst_fourcc_image;
+static  VASurfaceID csc_render_surface;
+
+
+typedef struct {
+    const char * fmt_str;
+    unsigned int fourcc;
+} fourcc_map;
+fourcc_map va_fourcc_map[] = {
+    {"YUYV", VA_FOURCC_YUY2},
+    {"YUY2", VA_FOURCC_YUY2},
+    {"NV12", VA_FOURCC_NV12},
+    {"YV12", VA_FOURCC_YV12},
+    {"BGRA", VA_FOURCC_BGRA},
+    {"RGBA", VA_FOURCC_RGBA},
+    {"BGRX", VA_FOURCC_BGRX},
+    {"RGBX", VA_FOURCC_RGBX},
+};
+unsigned int map_str_to_vafourcc (char * str)
+{
+    unsigned int i;
+    for (i=0; i< sizeof(va_fourcc_map)/sizeof(fourcc_map); i++) {
+        if (!strcmp(va_fourcc_map[i].fmt_str, str)) {
+            return va_fourcc_map[i].fourcc;
+        }
+    }
+
+    return 0;
+
+}
+const char* map_vafourcc_to_str (unsigned int format)
+{
+    static char unknown_format[] = "unknown-format";
+    unsigned int i;
+    for (i=0; i< sizeof(va_fourcc_map)/sizeof(fourcc_map); i++) {
+        if (va_fourcc_map[i].fourcc == format) {
+            return va_fourcc_map[i].fmt_str;
+        }
+    }
+
+    return unknown_format;
+
+}
+
+static int
+va_value_equals(const VAGenericValue *v1, const VAGenericValue *v2)
+{
+    if (v1->type != v2->type)
+        return 0;
+
+    switch (v1->type) {
+    case VAGenericValueTypeInteger:
+        return v1->value.i == v2->value.i;
+    case VAGenericValueTypeFloat:
+        return v1->value.f == v2->value.f;
+    case VAGenericValueTypePointer:
+        return v1->value.p == v2->value.p;
+    case VAGenericValueTypeFunc:
+        return v1->value.fn == v2->value.fn;
+    }
+    return 0;
+}
+
+static int
+ensure_image_formats(void)
+{
+    VAStatus va_status;
+    VAImageFormat *image_formats;
+    int num_image_formats;
+
+    if (va_num_image_formats >= 0)
+        return va_num_image_formats;
+
+    num_image_formats = vaMaxNumImageFormats(va_dpy);
+    if (num_image_formats == 0)
+        return 0;
+
+    image_formats = (VAImageFormat *) malloc(num_image_formats * sizeof(*image_formats));
+    if (!image_formats)
+        return 0;
+
+    va_status = vaQueryImageFormats(va_dpy, image_formats, &num_image_formats);
+    CHECK_VASTATUS(va_status, "vaQuerySurfaceAttributes()");
+
+    va_image_formats = image_formats;
+    va_num_image_formats = num_image_formats;
+    return num_image_formats;
+}
+
+static const VAImageFormat *
+lookup_image_format(uint32_t fourcc)
+{
+    int i;
+
+    if (!ensure_image_formats())
+        return NULL;
+
+    for (i = 0; i < va_num_image_formats; i++) {
+        const VAImageFormat * const image_format = &va_image_formats[i];
+        if (image_format->fourcc == fourcc)
+            return image_format;
+    }
+    return NULL;
+}
+
+static int
+ensure_surface_attribs(void)
+{
+    VAStatus va_status;
+    VASurfaceAttrib *surface_attribs;
+    unsigned int num_image_formats, num_surface_attribs;
+
+    if (va_num_surface_attribs >= 0)
+        return va_num_surface_attribs;
+
+    num_image_formats = vaMaxNumImageFormats(va_dpy);
+    if (num_image_formats == 0)
+        return 0;
+
+    va_status = vaCreateConfig(va_dpy, VAProfileNone, VAEntrypointVideoProc,
+        NULL, 0, &vpp_config_id);
+    CHECK_VASTATUS(va_status, "vaCreateConfig()");
+
+    /* Guess the number of surface attributes, thus including any
+       pixel-format supported by the VA driver */
+    num_surface_attribs = VASurfaceAttribCount + num_image_formats;
+    surface_attribs = (VASurfaceAttrib *) malloc(num_surface_attribs * sizeof(*surface_attribs));
+    if (!surface_attribs)
+        return 0;
+
+    va_status = vaQuerySurfaceAttributes(va_dpy, vpp_config_id,
+        surface_attribs, &num_surface_attribs);
+    if (va_status == VA_STATUS_SUCCESS)
+        va_surface_attribs =  surface_attribs;
+    else if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) {
+        va_surface_attribs = (VASurfaceAttrib *) realloc(surface_attribs,
+            num_surface_attribs * sizeof(*va_surface_attribs));
+        if (!va_surface_attribs) {
+            free(surface_attribs);
+            return 0;
+        }
+        va_status = vaQuerySurfaceAttributes(va_dpy, vpp_config_id,
+            va_surface_attribs, &num_surface_attribs);
+    }
+    CHECK_VASTATUS(va_status, "vaQuerySurfaceAttributes()");
+    va_num_surface_attribs = num_surface_attribs;
+    return num_surface_attribs;
+}
+
+static const VASurfaceAttrib *
+lookup_surface_attrib(VASurfaceAttribType type, const VAGenericValue *value)
+{
+    int i;
+
+    if (!ensure_surface_attribs())
+        return NULL;
+
+    for (i = 0; i < va_num_surface_attribs; i++) {
+        const VASurfaceAttrib * const surface_attrib = &va_surface_attribs[i];
+        if (surface_attrib->type != type)
+            continue;
+        if (!(surface_attrib->flags & VA_SURFACE_ATTRIB_SETTABLE))
+            continue;
+        if (va_value_equals(&surface_attrib->value, value))
+            return surface_attrib;
+    }
+    return NULL;
+}
+
+int csc_preparation ()
+{
+    VAStatus va_status;
+    VASurfaceAttrib surface_attribs[1], * const s_attrib = &surface_attribs[0];
+
+    // 1. make sure dst fourcc is supported for vaImage
+    if (!lookup_image_format(csc_dst_fourcc)) {
+        test_color_conversion = 0;
+        printf("VA driver doesn't support %s image, skip additional color conversion\n",  map_vafourcc_to_str(csc_dst_fourcc));
+        goto cleanup;
+    }
+
+    // 2. make sure src_fourcc is supported for vaSurface
+    s_attrib->type = VASurfaceAttribPixelFormat;
+    s_attrib->flags = VA_SURFACE_ATTRIB_SETTABLE;
+    s_attrib->value.type = VAGenericValueTypeInteger;
+    s_attrib->value.value.i = csc_src_fourcc;
+
+    if (!lookup_surface_attrib(VASurfaceAttribPixelFormat, &s_attrib->value)) {
+        printf("VA driver doesn't support %s surface, skip additional color conversion\n",  map_vafourcc_to_str(csc_src_fourcc));
+        test_color_conversion = 0;
+        goto cleanup;
+    }
+
+    // 3 create all objs required by csc
+    // 3.1 vaSurface with src fourcc
+    va_status = vaCreateSurfaces(
+        va_dpy,
+        VA_RT_FORMAT_YUV420, surface_width, surface_height,
+        &surface_id[0], SURFACE_NUM,
+        surface_attribs, 1
+    );
+    CHECK_VASTATUS(va_status,"vaCreateSurfaces");
+
+    // 3.2 vaImage with dst fourcc
+    VAImageFormat image_format;
+    image_format.fourcc = csc_dst_fourcc;
+    image_format.byte_order = VA_LSB_FIRST;
+    image_format.bits_per_pixel = 16;
+
+    va_status = vaCreateImage(va_dpy, &image_format,
+                    surface_width, surface_height,
+                    &csc_dst_fourcc_image);
+    CHECK_VASTATUS(va_status,"vaCreateImage");
+
+
+    // 3.3 create a temp VASurface for final rendering(vaPutSurface)
+    s_attrib->value.value.i = VA_FOURCC_NV12;
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420,
+                                 surface_width, surface_height,
+                                 &csc_render_surface, 1,
+                                 surface_attribs, 1);
+    CHECK_VASTATUS(va_status,"vaCreateSurfaces");
+
+
+cleanup:
+    return test_color_conversion;
+}
 
 static VASurfaceID get_next_free_surface(int *index)
 {
@@ -93,7 +328,7 @@
 
         return surface_id[i];
     }
-    
+
     for (i=0; i<SURFACE_NUM; i++) {
         surface_status = (VASurfaceStatus)0;
         vaQuerySurfaceStatus(va_dpy, surface_id[i], &surface_status);
@@ -121,11 +356,11 @@
     int box_width_loc=8;
     int row_shift_loc=0;
     int i;
-    
+
     for (i=0; i<SURFACE_NUM; i++) {
         printf("\rLoading data into surface %d.....", i);
         upload_surface(va_dpy, surface_id[i], box_width_loc, row_shift_loc, 0);
-        
+
         row_shift_loc++;
         if (row_shift_loc==(2*box_width_loc)) row_shift_loc= 0;
     }
@@ -149,9 +384,9 @@
 {
     if (test_clip == 0)
         return;
-            
+
     srand((unsigned)time(NULL));
-                
+
     cliprects[0].x = (rand() % width);
     cliprects[0].y = (rand() % height);
     cliprects[0].width = (rand() % (width - cliprects[0].x));
@@ -177,55 +412,83 @@
     unsigned int frame_num=0, start_time, putsurface_time;
     VARectangle cliprects[2]; /* client supplied clip list */
     int continue_display = 0;
-    
+
     if (drawable == drawable_thread0)
         printf("Enter into thread0\n\n");
     if (drawable == drawable_thread1)
         printf("Enter into thread1\n\n");
-    
+
     putsurface_time = 0;
     while (!quit) {
         VASurfaceID surface_id = VA_INVALID_SURFACE;
-        
+
         while (surface_id == VA_INVALID_SURFACE)
             surface_id = get_next_free_surface(&index);
 
-        if (verbose) printf("Thread %x Display surface 0x%p,\n", (unsigned int)drawable, (void *)surface_id);
+        if (verbose) printf("Thread: %p Display surface 0x%x,\n", drawable, surface_id);
 
         if (multi_thread)
             upload_surface(va_dpy, surface_id, box_width, row_shift, display_field);
 
         if (check_event)
             pthread_mutex_lock(&gmutex);
-        
+
         start_time = get_tick_count();
-	if ((continue_display == 0) && getenv("FRAME_STOP")) {
+        if ((continue_display == 0) && getenv("FRAME_STOP")) {
             char c;
             printf("Press any key to display frame %d...(c/C to continue)\n", frame_num);
             c = getchar();
             if (c == 'c' || c == 'C')
                 continue_display = 1;
         }
-        vaStatus = vaPutSurface(va_dpy, surface_id, CAST_DRAWABLE(drawable),
-                                0,0,surface_width,surface_height,
-                                0,0,width,height,
-                                (test_clip==0)?NULL:&cliprects[0],
-                                (test_clip==0)?0:2,
-                                display_field);
-        CHECK_VASTATUS(vaStatus,"vaPutSurface");
+        if (test_color_conversion) {
+            static int _put_surface_count = 0;
+            if (_put_surface_count++ %50 == 0) {
+                printf("do additional colorcoversion from %s to %s\n", map_vafourcc_to_str(csc_src_fourcc), map_vafourcc_to_str(csc_dst_fourcc));
+            }
+            // get image from surface, csc_src_fourcc to csc_dst_fourcc conversion happens
+            vaStatus = vaGetImage(va_dpy, surface_id, 0, 0,
+                surface_width, surface_height, csc_dst_fourcc_image.image_id);
+            CHECK_VASTATUS(vaStatus,"vaGetImage");
+
+            // render csc_dst_fourcc image to temp surface
+            vaStatus = vaPutImage(va_dpy, csc_render_surface, csc_dst_fourcc_image.image_id,
+                                    0, 0, surface_width, surface_height,
+                                    0, 0, surface_width, surface_height);
+            CHECK_VASTATUS(vaStatus,"vaPutImage");
+
+            // render the temp surface, it should be same with original surface without color conversion test
+            vaStatus = vaPutSurface(va_dpy, csc_render_surface, CAST_DRAWABLE(drawable),
+                                    0,0,surface_width,surface_height,
+                                    0,0,width,height,
+                                    (test_clip==0)?NULL:&cliprects[0],
+                                    (test_clip==0)?0:2,
+                                    display_field);
+            CHECK_VASTATUS(vaStatus,"vaPutSurface");
+        }
+        else {
+            vaStatus = vaPutSurface(va_dpy, surface_id, CAST_DRAWABLE(drawable),
+                                    0,0,surface_width,surface_height,
+                                    0,0,width,height,
+                                    (test_clip==0)?NULL:&cliprects[0],
+                                    (test_clip==0)?0:2,
+                                    display_field);
+            CHECK_VASTATUS(vaStatus,"vaPutSurface");
+        }
+
         putsurface_time += (get_tick_count() - start_time);
-        
+
         if (check_event)
             pthread_mutex_unlock(&gmutex);
-        
+
         pthread_mutex_unlock(&surface_mutex[index]); /* locked in get_next_free_surface */
-        
+
         if ((frame_num % 0xff) == 0) {
             fprintf(stderr, "%.2f FPS             \r", 256000.0 / (float)putsurface_time);
             putsurface_time = 0;
             update_clipbox(cliprects, width, height);
         }
-        
+
         if (check_event)
             check_window_event(win_display, drawable, &width, &height, &quit);
 
@@ -233,7 +496,7 @@
             row_shift++;
             if (row_shift==(2*box_width)) row_shift= 0;
         }
-        
+
         if (frame_rate != 0) /* rough framerate control */
             usleep(1000/frame_rate*1000);
 
@@ -241,14 +504,12 @@
         if (frame_num >= frame_num_total)
             quit = 1;
     }
-    
-    if (drawable == drawable_thread1)    
+
+    if (drawable == drawable_thread1)
         pthread_exit(NULL);
-    
+
     return 0;
 }
-
-
 int main(int argc,char **argv)
 {
     int major_ver, minor_ver;
@@ -257,8 +518,16 @@
     int ret;
     char c;
     int i;
+    char str_src_fmt[5], str_dst_fmt[5];
 
-    while ((c =getopt(argc,argv,"w:h:g:r:d:f:tcep?n:v") ) != EOF) {
+    static struct option long_options[] =
+                 {
+                   {"fmt1",  required_argument,       NULL, '1'},
+                   {"fmt2",  required_argument,       NULL, '2'},
+                   {0, 0, 0, 0}
+                 };
+
+    while ((c =getopt_long(argc,argv,"w:h:g:r:d:f:tcep?n:1:2:v", long_options, NULL)) != EOF) {
         switch (c) {
             case '?':
                 printf("putsurface <options>\n");
@@ -269,6 +538,10 @@
                 printf("           -t multi-threads\n");
                 printf("           -c test clipbox\n");
                 printf("           -f <1/2> top field, or bottom field\n");
+                printf("           -1 source format (fourcc) for color conversion test\n");
+                printf("           -2 dest   format (fourcc) for color conversion test\n");
+                printf("           --fmt1 same to -1\n");
+                printf("           --fmt2 same to -2\n");
                 printf("           -v verbose output\n");
                 exit(0);
                 break;
@@ -319,6 +592,24 @@
                 } else
                     printf("The validate input for -f is: 1(top field)/2(bottom field)\n");
                 break;
+            case '1':
+                sscanf(optarg, "%s", str_src_fmt);
+                csc_src_fourcc = map_str_to_vafourcc (str_src_fmt);
+
+                                if (!csc_src_fourcc) {
+                    printf("invalid fmt1: %s\n", str_src_fmt );
+                    exit(0);
+                }
+                break;
+            case '2':
+                sscanf(optarg, "%s", str_dst_fmt);
+                csc_dst_fourcc = map_str_to_vafourcc (str_dst_fmt);
+
+                                if (!csc_dst_fourcc) {
+                    printf("invalid fmt1: %s\n", str_dst_fmt );
+                    exit(0);
+                }
+                break;
             case 'v':
                 verbose = 1;
                 printf("Enable verbose output\n");
@@ -326,6 +617,10 @@
         }
     }
 
+    if (csc_src_fourcc && csc_dst_fourcc) {
+        test_color_conversion = 1;
+    }
+
     win_display = (void *)open_display();
     if (win_display == NULL) {
         fprintf(stderr, "Can't open the connection of display!\n");
@@ -337,35 +632,56 @@
     va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
     CHECK_VASTATUS(va_status, "vaInitialize");
 
-    va_status = vaCreateSurfaces(
-        va_dpy,
-        VA_RT_FORMAT_YUV420, surface_width, surface_height,
-        &surface_id[0], SURFACE_NUM,
-        NULL, 0
-    );
+    if (test_color_conversion) {
+        ret = csc_preparation();
+    }
+    if (!test_color_conversion || !ret ) {
+        va_status = vaCreateSurfaces(
+            va_dpy,
+            VA_RT_FORMAT_YUV420, surface_width, surface_height,
+            &surface_id[0], SURFACE_NUM,
+            NULL, 0
+        );
+        }
     CHECK_VASTATUS(va_status, "vaCreateSurfaces");
     if (multi_thread == 0) /* upload the content for all surfaces */
         upload_source_YUV_once_for_all();
-    
+
     if (check_event)
         pthread_mutex_init(&gmutex, NULL);
-   
+
     for(i = 0; i< SURFACE_NUM; i++)
         pthread_mutex_init(&surface_mutex[i], NULL);
-    
-    if (multi_thread == 1) 
+
+    if (multi_thread == 1)
         ret = pthread_create(&thread1, NULL, putsurface_thread, (void*)drawable_thread1);
 
     putsurface_thread((void *)drawable_thread0);
 
-    if (multi_thread == 1) 
+    if (multi_thread == 1)
         pthread_join(thread1, (void **)&ret);
     printf("thread1 is free\n");
-    
-    vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM);    
+
+    if (test_color_conversion) {
+        // destroy temp surface/image
+        va_status = vaDestroySurfaces(va_dpy, &csc_render_surface, 1);
+        CHECK_VASTATUS(va_status,"vaDestroySurfaces");
+
+        va_status = vaDestroyImage(va_dpy, csc_dst_fourcc_image.image_id);
+        CHECK_VASTATUS(va_status,"vaDestroyImage");
+    }
+
+    if (vpp_config_id != VA_INVALID_ID) {
+        vaDestroyConfig (va_dpy, vpp_config_id);
+        vpp_config_id = VA_INVALID_ID;
+    }
+
+    vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM);
     vaTerminate(va_dpy);
 
+    free(va_image_formats);
+    free(va_surface_attribs);
     close_display(win_display);
-    
+
     return 0;
 }
diff --git a/test/putsurface/putsurface_wayland.c b/test/putsurface/putsurface_wayland.c
new file mode 100644
index 0000000..b93334d
--- /dev/null
+++ b/test/putsurface/putsurface_wayland.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stddef.h>
+#include <errno.h>
+#include <sys/select.h>
+#ifdef IN_LIBVA
+# include "va/wayland/va_wayland.h"
+#else
+# include <va/va_wayland.h>
+#endif
+#include <wayland-server.h>
+
+static void *open_display(void);
+static void close_display(void *win_display);
+static int create_window(void *win_display,
+             int x, int y, int width, int height);
+static int check_window_event(void *win_display, void *drawable,
+                  int *width, int *height, int *quit);
+
+struct display;
+struct drawable;
+
+static VAStatus
+va_put_surface(
+    VADisplay           dpy,
+    struct drawable    *wl_drawable,
+    VASurfaceID         va_surface,
+    const VARectangle  *src_rect,
+    const VARectangle  *dst_rect,
+    const VARectangle  *cliprects,
+    unsigned int        num_cliprects,
+    unsigned int        flags
+);
+
+/* Glue code for the current PutSurface test design */
+#define CAST_DRAWABLE(a)  (struct drawable *)(a)
+
+static inline VADisplay
+vaGetDisplay(VANativeDisplay native_dpy)
+{
+    return vaGetDisplayWl(native_dpy);
+}
+
+static VAStatus
+vaPutSurface(
+    VADisplay           dpy,
+    VASurfaceID         surface,
+    struct drawable    *wl_drawable,
+    short               src_x,
+    short               src_y,
+    unsigned short      src_w,
+    unsigned short      src_h,
+    short               dst_x,
+    short               dst_y,
+    unsigned short      dst_w,
+    unsigned short      dst_h,
+    const VARectangle  *cliprects,
+    unsigned int        num_cliprects,
+    unsigned int        flags
+)
+{
+    VARectangle src_rect, dst_rect;
+
+    src_rect.x      = src_x;
+    src_rect.y      = src_y;
+    src_rect.width  = src_w;
+    src_rect.height = src_h;
+
+    dst_rect.x      = src_x;
+    dst_rect.y      = src_y;
+    dst_rect.width  = src_w;
+    dst_rect.height = src_h;
+    return va_put_surface(dpy, wl_drawable, surface, &src_rect, &dst_rect,
+                          cliprects, num_cliprects, flags);
+}
+
+#include "putsurface_common.c"
+
+struct display {
+    struct wl_display  *display;
+    struct wl_compositor *compositor;
+    struct wl_shell    *shell;
+    struct wl_registry *registry;
+    int                 event_fd;
+};
+
+struct drawable {
+    struct wl_display  *display;
+    struct wl_surface  *surface;
+    unsigned int        redraw_pending  : 1;
+};
+
+static void
+frame_redraw_callback(void *data, struct wl_callback *callback, uint32_t time)
+{
+    struct drawable * const drawable = data;
+
+    drawable->redraw_pending = 0;
+    wl_callback_destroy(callback);
+}
+
+static const struct wl_callback_listener frame_callback_listener = {
+    frame_redraw_callback
+};
+
+static VAStatus
+va_put_surface(
+    VADisplay           dpy,
+    struct drawable    *wl_drawable,
+    VASurfaceID         va_surface,
+    const VARectangle  *src_rect,
+    const VARectangle  *dst_rect,
+    const VARectangle  *cliprects,
+    unsigned int        num_cliprects,
+    unsigned int        flags
+)
+{
+    struct display *d;
+    struct wl_callback *callback;
+    VAStatus va_status;
+    struct wl_buffer *buffer;
+
+    if (!wl_drawable)
+        return VA_STATUS_ERROR_INVALID_SURFACE;
+
+    d = wl_display_get_user_data(wl_drawable->display);
+    if (!d)
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+
+    /* Wait for the previous frame to complete redraw */
+    if (wl_drawable->redraw_pending) {
+        wl_display_flush(d->display);
+        while (wl_drawable->redraw_pending)
+            wl_display_dispatch(wl_drawable->display);
+    }
+
+    va_status = vaGetSurfaceBufferWl(va_dpy, va_surface, VA_FRAME_PICTURE, &buffer);
+    if (va_status != VA_STATUS_SUCCESS)
+        return va_status;
+
+    wl_surface_attach(wl_drawable->surface, buffer, 0, 0);
+    wl_surface_damage(
+        wl_drawable->surface,
+        dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height
+    );
+
+    wl_display_flush(d->display);
+    wl_drawable->redraw_pending = 1;
+    callback = wl_surface_frame(wl_drawable->surface);
+    wl_surface_commit(wl_drawable->surface);
+    wl_callback_add_listener(callback, &frame_callback_listener, wl_drawable);
+    return VA_STATUS_SUCCESS;
+}
+
+static void
+registry_handle_global(
+    void               *data,
+    struct wl_registry *registry,
+    uint32_t            id,
+    const char         *interface,
+    uint32_t            version
+)
+{
+    struct display * const d = data;
+
+    if (strcmp(interface, "wl_compositor") == 0)
+        d->compositor =
+            wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+    else if (strcmp(interface, "wl_shell") == 0)
+        d->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
+}
+
+static const struct wl_registry_listener registry_listener = {
+    registry_handle_global,
+    NULL,
+};
+
+static void *
+open_display(void)
+{
+    struct display *d;
+
+    d = calloc(1, sizeof *d);
+    if (!d)
+        return NULL;
+
+    d->display = wl_display_connect(NULL);
+    if (!d->display)
+        return NULL;
+
+    wl_display_set_user_data(d->display, d);
+    d->registry = wl_display_get_registry(d->display);
+    wl_registry_add_listener(d->registry, &registry_listener, d);
+    d->event_fd = wl_display_get_fd(d->display);
+    wl_display_dispatch(d->display);
+    return d->display;
+}
+
+static void
+close_display(void *win_display)
+{
+    struct display * const d = wl_display_get_user_data(win_display);
+
+    if (d->shell) {
+        wl_shell_destroy(d->shell);
+        d->shell = NULL;
+    }
+
+    if (d->compositor) {
+        wl_compositor_destroy(d->compositor);
+        d->compositor = NULL;
+    }
+
+    if (d->display) {
+        wl_display_disconnect(d->display);
+        d->display = NULL;
+    }
+    free(d);
+}
+
+static int
+create_window(void *win_display, int x, int y, int width, int height)
+{
+    struct wl_display * const display = win_display;
+    struct display * const d = wl_display_get_user_data(display);
+    struct wl_surface *surface1, *surface2;
+    struct wl_shell_surface *shell_surface;
+    struct wl_shell_surface *shell_surface_2;
+    struct drawable *drawable1, *drawable2;
+
+    surface1 = wl_compositor_create_surface(d->compositor);
+    shell_surface = wl_shell_get_shell_surface(d->shell, surface1);
+    wl_shell_surface_set_toplevel(shell_surface);
+
+    drawable1 = malloc(sizeof(*drawable1));
+    drawable1->display          = display;
+    drawable1->surface          = surface1;
+    drawable1->redraw_pending   = 0;
+
+    /* global out */
+    drawable_thread0 = drawable1;
+
+    if (multi_thread == 0)
+        return 0;
+
+    surface2 = wl_compositor_create_surface(d->compositor);
+    shell_surface_2 = wl_shell_get_shell_surface(d->shell, surface2);
+    wl_shell_surface_set_toplevel(shell_surface_2);
+
+    drawable2 = malloc(sizeof(*drawable2));
+    drawable2->display          = display;
+    drawable1->surface          = surface2;
+    drawable2->redraw_pending   = 0;
+
+    /* global out */
+    drawable_thread1 = drawable2;
+    return 0;
+}
+
+static int
+check_window_event(
+    void *win_display,
+    void *drawable,
+    int  *width,
+    int  *height,
+    int  *quit
+)
+{
+    struct wl_display * const display = win_display;
+    struct display * const d = wl_display_get_user_data(display);
+    struct timeval tv;
+    fd_set rfds;
+    int retval;
+
+    if (check_event == 0)
+        return 0;
+
+    tv.tv_sec  = 0;
+    tv.tv_usec = 0;
+    do {
+        FD_ZERO(&rfds);
+        FD_SET(d->event_fd, &rfds);
+
+        retval = select(d->event_fd + 1, &rfds, NULL, NULL, &tv);
+        if (retval < 0) {
+            perror("select");
+            break;
+        }
+        if (retval == 1)
+            wl_display_dispatch(d->display);
+    } while (retval > 0);
+
+#if 0
+    /* bail on any focused key press */
+    if(event.type == KeyPress) {  
+        *quit = 1;
+        return 0;
+    }
+#endif
+
+#if 0
+    /* rescale the video to fit the window */
+    if(event.type == ConfigureNotify) { 
+        *width = event.xconfigure.width;
+        *height = event.xconfigure.height;
+        printf("Scale window to %dx%d\n", width, height);
+    }
+#endif
+    return 0;
+}
diff --git a/test/putsurface/putsurface_x11.c b/test/putsurface/putsurface_x11.c
index a89d914..db765af 100644
--- a/test/putsurface/putsurface_x11.c
+++ b/test/putsurface/putsurface_x11.c
@@ -41,7 +41,7 @@
 
 static void *open_display(void)
 {
-    return XOpenDisplay(":0.0");
+    return XOpenDisplay(NULL);
 }
 
 static void close_display(void *win_display)
diff --git a/test/transcode/Makefile.am b/test/transcode/Makefile.am
index a721381..feccf55 100644
--- a/test/transcode/Makefile.am
+++ b/test/transcode/Makefile.am
@@ -24,10 +24,13 @@
 
 INCLUDES = -I$(top_srcdir)
 
-TEST_LIBS = $(top_builddir)/va/$(libvacorelib) $(top_builddir)/va/$(libvabackendlib) -lX11
-
-mpeg2transcode_LDADD = $(TEST_LIBS)
-mpeg2transcode_SOURCES = mpeg2transcode.cpp
+mpeg2transcode_SOURCES	= mpeg2transcode.cpp
+mpeg2transcode_CFLAGS	= -I$(top_srcdir) $(X11_CFLAGS)
+mpeg2transcode_LDADD	= \
+	$(top_builddir)/va/libva.la \
+	$(top_builddir)/va/libva-x11.la \
+	$(X11_LIBS) \
+	-lpthread
 
 valgrind:	$(bin_PROGRAMS)
 	for a in $(bin_PROGRAMS); do \
diff --git a/test/vainfo/Android.mk b/test/vainfo/Android.mk
index 0aac2cf..5c97388 100644
--- a/test/vainfo/Android.mk
+++ b/test/vainfo/Android.mk
@@ -6,18 +6,22 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-  vainfo.c
+	vainfo.c		\
+	../common/va_display.c	\
+	../common/va_display_android.cpp
 
 LOCAL_CFLAGS += \
   -DANDROID
 
 LOCAL_C_INCLUDES += \
-  $(TARGET_OUT_HEADERS)/libva
+  $(LOCAL_PATH)/../../va \
+  $(LOCAL_PATH)/../common \
+  $(LOCAL_PATH)/../.. \
 
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := vainfo
 
-LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils
+LOCAL_SHARED_LIBRARIES := libva-android libva libdl libdrm libcutils libutils libgui
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/test/vainfo/Makefile.am b/test/vainfo/Makefile.am
index 190aa8b..680d099 100644
--- a/test/vainfo/Makefile.am
+++ b/test/vainfo/Makefile.am
@@ -20,18 +20,25 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-
 bin_PROGRAMS = vainfo
 
-INCLUDES = \
-	-I$(top_srcdir)					\
-	-I$(top_srcdir)/test/basic			\
-	-DLIBVA_VERSION_S="\"${LIBVA_VERSION}\""	\
+vainfo_cflags = \
+	-I$(top_srcdir)				\
+	-I$(top_srcdir)/va			\
+	-I$(top_srcdir)/test/common		\
+	-I$(top_builddir)			\
+	-DLIBVA_VERSION_S="\"$(LIBVA_VERSION)\"" \
 	$(NULL)
 
-vainfo_LDADD = $(top_builddir)/va/$(libvacorelib) $(top_builddir)/va/$(libvabackendlib) -lX11
+vainfo_libs = \
+	$(top_builddir)/va/libva.la		\
+	$(top_builddir)/test/common/libva-display.la	\
+	$(NULL)
 
-vainfo_DEPENDENCIES =  $(top_builddir)/va/$(libvacorelib) $(top_builddir)/va/$(libvabackendlib)
+vainfo_SOURCES	= vainfo.c
+noinst_HEADERS	= $(source_h)
+vainfo_CFLAGS	= $(vainfo_cflags)
+vainfo_LDADD	= $(vainfo_libs)
 
 valgrind:	vainfo
 	valgrind --leak-check=full --show-reachable=yes .libs/vainfo; 
diff --git a/test/vainfo/vainfo.c b/test/vainfo/vainfo.c
index c386b5e..e18eb5f 100644
--- a/test/vainfo/vainfo.c
+++ b/test/vainfo/vainfo.c
@@ -22,23 +22,18 @@
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#ifndef ANDROID
-#include <va/va_x11.h>
-#else
-#include "va/va_android.h"
-#define Display unsigned int
-#endif
-
+#include "sysdeps.h"
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-
+#include "va_display.h"
 
 #define CHECK_VASTATUS(va_status,func, ret)                             \
 if (va_status != VA_STATUS_SUCCESS) {                                   \
     fprintf(stderr,"%s failed with error code %d (%s),exit\n",func, va_status, vaErrorStr(va_status)); \
-    exit(ret);                                                          \
+    ret_val = ret;                                                      \
+    goto error;                                                         \
 }
 
 static char * profile_string(VAProfile profile)
@@ -59,6 +54,10 @@
             case VAProfileH263Baseline: return "VAProfileH263Baseline";
             case VAProfileH264ConstrainedBaseline: return "VAProfileH264ConstrainedBaseline";
             case VAProfileJPEGBaseline: return "VAProfileJPEGBaseline";
+            case VAProfileH264MultiviewHigh: return "VAProfileH264MultiviewHigh";
+            case VAProfileH264StereoHigh: return "VAProfileH264StereoHigh";
+            case VAProfileVP8Version0_3: return "VAProfileVP8Version0_3";
+
             default:
                 break;
     }
@@ -85,34 +84,23 @@
 
 int main(int argc, const char* argv[])
 {
-  Display *dpy;
   VADisplay va_dpy;
   VAStatus va_status;
   int major_version, minor_version;
   const char *driver;
-  const char *display = getenv("DISPLAY");
   const char *name = strrchr(argv[0], '/'); 
-  VAProfile profile;
+  VAProfile profile, *profile_list = NULL;
+  int num_profiles, max_num_profiles, i;
   VAEntrypoint entrypoint, entrypoints[10];
   int num_entrypoint;
+  int ret_val = 0;
   
   if (name)
       name++;
   else
       name = argv[0];
 
-#ifndef ANDROID
-  dpy = XOpenDisplay(NULL);
-#else
-  dpy = (Display*)malloc(sizeof(Display));
-#endif
-  if (NULL == dpy)
-  {
-      fprintf(stderr, "%s: Error, can't open display: '%s'\n", name, display ? display : "");
-      return 1;
-  }
-  
-  va_dpy = vaGetDisplay(dpy);
+  va_dpy = va_open_display();
   if (NULL == va_dpy)
   {
       fprintf(stderr, "%s: vaGetDisplay() failed\n", name);
@@ -129,9 +117,22 @@
   printf("%s: Driver version: %s\n", name, driver ? driver : "<unknown>");
 
   printf("%s: Supported profile and entrypoints\n", name);
-  for	(profile = VAProfileNone; profile <= VAProfileH264ConstrainedBaseline; profile++) {
+  max_num_profiles = vaMaxNumProfiles(va_dpy);
+  profile_list = malloc(max_num_profiles * sizeof(VAProfile));
+
+  if (!profile_list) {
+      printf("Failed to allocate memory for profile list\n");
+      ret_val = 5;
+      goto error;
+  }
+
+  va_status = vaQueryConfigProfiles(va_dpy, profile_list, &num_profiles);
+  CHECK_VASTATUS(va_status, "vaQueryConfigProfiles", 6);
+
+  for (i = 0; i < num_profiles; i++) {
       char *profile_str;
 
+      profile = profile_list[i];
       va_status = vaQueryConfigEntrypoints(va_dpy, profile, entrypoints, 
                                            &num_entrypoint);
       if (va_status == VA_STATUS_ERROR_UNSUPPORTED_PROFILE)
@@ -144,7 +145,10 @@
           printf("      %-32s:	%s\n", profile_str, entrypoint_string(entrypoints[entrypoint]));
   }
   
+error:
+  free(profile_list);
   vaTerminate(va_dpy);
+  va_close_display(va_dpy);
   
-  return 0;
+  return ret_val;
 }
diff --git a/va/android/Makefile.am b/test/videoprocess/Makefile.am
similarity index 68%
copy from va/android/Makefile.am
copy to test/videoprocess/Makefile.am
index 8e532ac..969b5a6 100644
--- a/va/android/Makefile.am
+++ b/test/videoprocess/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 Intel Corporation. All Rights Reserved.
+# Copyright (c) 2014 Intel Corporation. All Rights Reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the
@@ -7,11 +7,11 @@
 # 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.
@@ -20,13 +20,18 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-AM_CFLAGS = -DLINUX -I$(top_srcdir)/va -I$(top_srcdir)/va/x11 $(DRM_CFLAGS)
+noinst_PROGRAMS = videoprocess
 
-noinst_LTLIBRARIES = libva_dummy.la	
+INCLUDES = -I$(top_srcdir) \
+           -I$(top_srcdir)/test/common \
+           $(NULL)
 
-libva_dummy_la_LIBADD = $(LIBVA_LIBS) -ldl -ludev
+videoprocess_SOURCES = videoprocess.cpp
+videoprocess_LDADD   = $(top_builddir)/va/libva.la \
+                       $(top_builddir)/test/common/libva-display.la \
+                       $(NULL)
 
-libva_dummyincludedir = ${includedir}/va
-
-libva_dummy_la_SOURCES = va_dummy.c drmtest.c
-
+valgrind:(noinst_PROGRAMS)
+	for a in(noinst_PROGRAMS); do \
+		valgrind --leak-check=full --show-reachable=yes .libs/$$a; \
+	done
diff --git a/test/videoprocess/process.cfg b/test/videoprocess/process.cfg
new file mode 100644
index 0000000..a11a0a4
--- /dev/null
+++ b/test/videoprocess/process.cfg
@@ -0,0 +1,76 @@
+#Configuration information for video process test case.
+#    This application will firstly loads frames(yv12 format in file) to one type of
+#surface(NV12/YV12/I420) you require, after video processing ,the processed content
+#(NV12/YV12/I420 surface) will be stored to frames(yv12 format in file).
+#    Supported features including: denoise, deinterlacing, sharpening, color balance,
+# blending and implicit format conversion(NV12<->YV12<->I420), each time only one
+# kind of processing will be executed in test application, although libva supports
+# multiply filters execution in one time. you can modify this configure to set the
+# filter and the corresponding parameters.
+
+#1.Source YUV(RGB) file information
+SRC_FILE_NAME:    /root/clips/YUV/bus_cif.yv12
+SRC_FRAME_WIDTH:  352
+SRC_FRAME_HEIGHT: 288
+SRC_FRAME_FORMAT: NV12
+
+#2.Destination YUV(RGB) file information
+DST_FILE_NAME:    ./bus_cif_deinterlacing.yv12
+DST_FRAME_WIDTH:  352
+DST_FRAME_HEIGHT: 288
+DST_FRAME_FORMAT: NV12
+
+#3.How many frames to be processed
+FRAME_SUM: 10
+
+#4.VPP filter type and parameters, the following filters are supported:
+  #(VAProcFilterNone,VAProcFilterNoiseReduction,VAProcFilterDeinterlacing,
+  # VAProcFilterSharpening,VAProcFilterColorBalance,
+  # defalut VAProcFilterNone)
+FILTER_TYPE: VAProcFilterDeinterlacing
+
+#5.VPP filter specific parameters. If they are not specified here,
+#default value will be applied then.
+
+#5.1 Denoise filter paramters
+ #(0.0 ~ 1.0, default 0.5)
+DENOISE_INTENSITY: 0.75
+
+#5.2 Deinterlacding parameters
+  #(VAProcDeinterlacingBob, VAProcDeinterlacingWeave,
+  # VAProcDeinterlacingMotionAdaptive, VAProcDeinterlacingMotionCompensated,
+  # default: VAProcDeinterlacingBob)
+DEINTERLACING_ALGORITHM:  VAProcDeinterlacingBob
+
+ #(VA_DEINTERLACING_BOTTOM_FIELD_FIRST |
+ # VA_DEINTERLACING_BOTTOM_FIELD |
+ # VA_DEINTERLACING_ONE_FIELD, defalut 0)
+DEINTERLACING_FLAGS: 0
+
+#5.3 Sharpening parameters
+ # (0.0 ~ 1.0, default 0.5)
+SHARPENING_INTENSITY: 0.75
+
+#5.4 Blending
+ # (0, 1, default 0)
+BLENDING_ENABLED:  0
+ # (VA_BLEND_GLOBAL_ALPHA |
+ #  VA_BLEND_LUMA_KEY, defalut 0)
+BLENDING_FLAGS: VA_BLEND_GLOBAL_ALPHA
+ # (0.0 ~ 1.0, default 0.5)
+BLENDING_GLOBAL_ALPHA: 0.5
+ # (1 ~ 254, defalut 1)
+BLENDING_MIN_LUMA: 1
+ # (1 ~ 254, defalut 254)
+BLENDING_MAX_LUMA: 254
+
+#5.5 Color balance parameters
+ #(-180 ~ 180, default 0)
+COLOR_BALANCE_HUE: 0
+ #(0.0 ~ 10.0, default 1.0)
+COLOR_BALANCE_SATURATION: 1.0
+ #(-100 ~ 100, default 0)
+COLOR_BALANCE_BRIGHTNESS: 20
+ #(0.0 ~ 10.0, default 1.0)
+COLOR_BALANCE_CONTRAST:  1.2
+
diff --git a/test/videoprocess/videoprocess.cpp b/test/videoprocess/videoprocess.cpp
new file mode 100644
index 0000000..855fa14
--- /dev/null
+++ b/test/videoprocess/videoprocess.cpp
@@ -0,0 +1,1118 @@
+/*
+ * Copyright (c) 2014 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Video process test case based on LibVA.
+ * This test covers deinterlace, denoise, color balance, sharpening,
+ * blending, scaling and several surface format conversion.
+ * Usage: videoprocess process.cfg
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <assert.h>
+#include <va/va.h>
+#include <va/va_vpp.h>
+#include "va_display.h"
+
+#ifndef VA_FOURCC_I420
+#define VA_FOURCC_I420 0x30323449
+#endif
+
+#define MAX_LEN   1024
+
+#define CHECK_VASTATUS(va_status,func)                                      \
+  if (va_status != VA_STATUS_SUCCESS) {                                     \
+      fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
+      exit(1);                                                              \
+  }
+
+static VADisplay va_dpy = NULL;
+static VAContextID context_id = 0;
+static VAConfigID  config_id = 0;
+static VAProcFilterType g_filter_type = VAProcFilterNone;
+static VASurfaceID g_in_surface_id = VA_INVALID_ID;
+static VASurfaceID g_out_surface_id = VA_INVALID_ID;
+
+static FILE* g_config_file_fd = NULL;
+static FILE* g_src_file_fd = NULL;
+static FILE* g_dst_file_fd = NULL;
+
+static char g_config_file_name[MAX_LEN];
+static char g_src_file_name[MAX_LEN];
+static char g_dst_file_name[MAX_LEN];
+static char g_filter_type_name[MAX_LEN];
+
+static uint32_t g_in_pic_width = 352;
+static uint32_t g_in_pic_height = 288;
+static uint32_t g_out_pic_width = 352;
+static uint32_t g_out_pic_height = 288;
+
+static uint32_t g_in_fourcc  = VA_FOURCC('N', 'V', '1', '2');
+static uint32_t g_in_format  = VA_RT_FORMAT_YUV420;
+static uint32_t g_out_fourcc = VA_FOURCC('N', 'V', '1', '2');
+static uint32_t g_out_format = VA_RT_FORMAT_YUV420;
+
+static uint8_t g_blending_enabled = 0;
+static uint8_t g_blending_min_luma = 1;
+static uint8_t g_blending_max_luma = 254;
+
+static uint32_t g_frame_count = 0;
+
+static int8_t
+read_value_string(FILE *fp, const char* field_name, char* value)
+{
+    char strLine[MAX_LEN];
+    char* field;
+    char* str;
+    uint16_t i;
+
+    if (!fp || !field_name || !value)  {
+        printf("Invalid fuction parameters\n");
+        return -1;
+    }
+
+    rewind(fp);
+
+    while (!feof(fp)) {
+        if (!fgets(strLine, MAX_LEN, fp))
+            continue;
+
+        for (i = 0; strLine[i] && i < MAX_LEN; i++)
+            if (strLine[i] != ' ') break;
+
+        if (strLine[i] == '#' || strLine[i] == '\n' || i == 1024)
+            continue;
+
+        field = strtok(&strLine[i], ":");
+        if (strncmp(field, field_name, strlen(field_name)))
+            continue;
+
+        if (!(str = strtok(NULL, ":")))
+            continue;
+
+        /* skip blank space in string */
+        while (*str == ' ')
+            str++;
+
+        *(str + strlen(str)-1) = '\0';
+        strcpy(value, str);
+
+        return 0;
+    }
+
+    return -1;
+}
+
+static int8_t
+read_value_uint8(FILE* fp, const char* field_name, uint8_t* value)
+{
+    char str[MAX_LEN];
+
+    if (read_value_string(fp, field_name, str)) {
+        printf("Failed to find integer field: %s", field_name);
+        return -1;
+    }
+
+    *value = (uint8_t)atoi(str);
+    return 0;
+}
+
+static int8_t
+read_value_uint32(FILE* fp, const char* field_name, uint32_t* value)
+{
+    char str[MAX_LEN];
+
+    if (read_value_string(fp, field_name, str)) {
+       printf("Failed to find integer field: %s", field_name);
+       return -1;
+    }
+
+    *value = (uint32_t)atoi(str);
+    return 0;
+}
+
+static int8_t
+read_value_float(FILE *fp, const char* field_name, float* value)
+{
+    char str[MAX_LEN];
+    if (read_value_string(fp, field_name, str)) {
+       printf("Failed to find float field: %s \n",field_name);
+       return -1;
+    }
+
+    *value = atof(str);
+    return 0;
+}
+
+static float
+adjust_to_range(VAProcFilterValueRange *range, float value)
+{
+    if (value < range->min_value || value > range->max_value){
+        printf("Value: %f exceed range: (%f ~ %f), force to use default: %f \n",
+                value, range->min_value, range->max_value, range->default_value);
+        return range->default_value;
+    }
+
+    return value;
+}
+
+static VAStatus
+create_surface(VASurfaceID * p_surface_id,
+               uint32_t width, uint32_t height,
+               uint32_t fourCC, uint32_t format)
+{
+    VAStatus va_status;
+    VASurfaceAttrib    surface_attrib;
+    surface_attrib.type =  VASurfaceAttribPixelFormat;
+    surface_attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
+    surface_attrib.value.type = VAGenericValueTypeInteger;
+    surface_attrib.value.value.i = fourCC;
+
+    va_status = vaCreateSurfaces(va_dpy,
+                                 format,
+                                 width ,
+                                 height,
+                                 p_surface_id,
+                                 1,
+                                 &surface_attrib,
+                                 1);
+   return va_status;
+}
+
+static VAStatus
+construct_nv12_mask_surface(VASurfaceID surface_id,
+                            uint8_t min_luma,
+                            uint8_t max_luma)
+{
+    VAStatus va_status;
+    VAImage surface_image;
+    void *surface_p = NULL;
+    unsigned char *y_dst, *u_dst, *v_dst;
+    uint32_t row, col;
+
+    va_status = vaDeriveImage(va_dpy, surface_id, &surface_image);
+    CHECK_VASTATUS(va_status, "vaDeriveImage");
+
+    va_status = vaMapBuffer(va_dpy, surface_image.buf, &surface_p);
+    CHECK_VASTATUS(va_status, "vaMapBuffer");
+
+    y_dst = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[0]);
+    u_dst = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[1]);
+    v_dst = u_dst;
+
+    /* fill Y plane, the luma values of some pixels is in the range of min_luma~max_luma,
+     * and others are out side of it, in luma key blending case, the pixels with Y value
+     * exceeding the range will be hided*/
+    for (row = 0; row < surface_image.height; row++) {
+        if (row < surface_image.height / 4 || row > surface_image.height * 3 / 4)
+            memset(y_dst, max_luma + 1, surface_image.pitches[0]);
+        else
+            memset(y_dst, (min_luma + max_luma) / 2, surface_image.pitches[0]);
+
+        y_dst += surface_image.pitches[0];
+     }
+
+     /* fill UV plane */
+     for (row = 0; row < surface_image.height / 2; row++) {
+         for (col = 0; col < surface_image.width / 2; col++) {
+             u_dst[col * 2] = 128;
+             u_dst[col * 2 + 1] = 128;
+        }
+        u_dst += surface_image.pitches[1];
+     }
+
+    vaUnmapBuffer(va_dpy, surface_image.buf);
+    vaDestroyImage(va_dpy, surface_image.image_id);
+
+    return VA_STATUS_SUCCESS;
+}
+
+/* Load yv12 frame to NV12/YV12/I420 surface*/
+static VAStatus
+upload_yv12_frame_to_yuv_surface(FILE *fp,
+                                 VASurfaceID surface_id)
+{
+    VAStatus va_status;
+    VAImage surface_image;
+    unsigned char *y_src, *u_src, *v_src;
+    unsigned char *y_dst, *u_dst, *v_dst;
+    void *surface_p = NULL;
+    uint32_t frame_size, i, row, col;
+    size_t n_items;
+    unsigned char * newImageBuffer = NULL;
+
+    va_status = vaDeriveImage(va_dpy, surface_id, &surface_image);
+    CHECK_VASTATUS(va_status, "vaDeriveImage");
+
+    va_status = vaMapBuffer(va_dpy, surface_image.buf, &surface_p);
+    CHECK_VASTATUS(va_status, "vaMapBuffer");
+
+    if (surface_image.format.fourcc == VA_FOURCC_YV12 ||
+        surface_image.format.fourcc == VA_FOURCC_I420 ||
+        surface_image.format.fourcc == VA_FOURCC_NV12){
+
+        frame_size = surface_image.width * surface_image.height * 3 / 2;
+        newImageBuffer = (unsigned char*)malloc(frame_size);
+        do {
+            n_items = fread(newImageBuffer, frame_size, 1, fp);
+        } while (n_items != 1);
+
+        y_src = newImageBuffer;
+        v_src = newImageBuffer + surface_image.width * surface_image.height;
+        u_src = newImageBuffer + surface_image.width * surface_image.height * 5 / 4;
+
+        y_dst = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[0]);
+
+        if(surface_image.format.fourcc == VA_FOURCC_YV12){
+            v_dst = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[1]);
+            u_dst = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[2]);
+        }else if(surface_image.format.fourcc == VA_FOURCC_I420){
+            u_dst = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[1]);
+            v_dst = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[2]);
+        }else {
+            u_dst = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[1]);
+            v_dst = u_dst;
+        }
+
+        /* Y plane, directly copy */
+        for (row = 0; row < surface_image.height; row++) {
+            memcpy(y_dst, y_src, surface_image.width);
+            y_dst += surface_image.pitches[0];
+            y_src += surface_image.width;
+        }
+
+        /* UV plane */
+        if (surface_image.format.fourcc == VA_FOURCC_YV12||
+            surface_image.format.fourcc == VA_FOURCC_I420){
+            /* UV plane */
+            for (row = 0; row < surface_image.height /2; row ++){
+                memcpy(v_dst, v_src, surface_image.width/2);
+                memcpy(u_dst, u_src, surface_image.width/2);
+
+                v_src += surface_image.width/2;
+                u_src += surface_image.width/2;
+
+                if (surface_image.format.fourcc == VA_FOURCC_YV12){
+                    v_dst += surface_image.pitches[1];
+                    u_dst += surface_image.pitches[2];
+                } else {
+                    v_dst += surface_image.pitches[2];
+                    u_dst += surface_image.pitches[1];
+                }
+            }
+        } else if (surface_image.format.fourcc == VA_FOURCC_NV12){
+            for (row = 0; row < surface_image.height / 2; row++) {
+                for (col = 0; col < surface_image.width / 2; col++) {
+                    u_dst[col * 2] = u_src[col];
+                    u_dst[col * 2 + 1] = v_src[col];
+                }
+
+                u_dst += surface_image.pitches[1];
+                u_src += (surface_image.width / 2);
+                v_src += (surface_image.width / 2);
+            }
+        }
+     } else {
+         printf("Not supported YUV surface fourcc !!! \n");
+         return VA_STATUS_ERROR_INVALID_SURFACE;
+     }
+
+     if (newImageBuffer){
+         free(newImageBuffer);
+         newImageBuffer = NULL;
+     }
+
+     vaUnmapBuffer(va_dpy, surface_image.buf);
+     vaDestroyImage(va_dpy, surface_image.image_id);
+
+     return VA_STATUS_SUCCESS;
+}
+
+/* Store NV12/YV12/I420 surface to yv12 frame*/
+static VAStatus
+store_yuv_surface_to_yv12_frame(FILE *fp,
+                            VASurfaceID surface_id)
+{
+    VAStatus va_status;
+    VAImageFormat image_format;
+    VAImage surface_image;
+    void *surface_p = NULL;
+    unsigned char *y_src, *u_src, *v_src;
+    unsigned char *y_dst, *u_dst, *v_dst;
+    uint32_t frame_size, row, col;
+    int32_t  ret, n_items;
+    unsigned char * newImageBuffer = NULL;
+
+    va_status = vaDeriveImage(va_dpy, surface_id, &surface_image);
+    CHECK_VASTATUS(va_status, "vaDeriveImage");
+
+    va_status = vaMapBuffer(va_dpy, surface_image.buf, &surface_p);
+    CHECK_VASTATUS(va_status, "vaMapBuffer");
+
+    /* store the surface to one YV12 file or one bmp file*/
+    if (surface_image.format.fourcc == VA_FOURCC_YV12 ||
+        surface_image.format.fourcc == VA_FOURCC_I420 ||
+        surface_image.format.fourcc == VA_FOURCC_NV12){
+
+        uint32_t y_size = surface_image.width * surface_image.height;
+        uint32_t u_size = y_size/4;
+
+        newImageBuffer = (unsigned char*)malloc(y_size * 3 / 2);
+
+        /* stored as YV12 format */
+        y_dst = newImageBuffer;
+        v_dst = newImageBuffer + y_size;
+        u_dst = newImageBuffer + y_size + u_size;
+
+        y_src = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[0]);
+        if (surface_image.format.fourcc == VA_FOURCC_YV12){
+            v_src = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[1]);
+            u_src = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[2]);
+        } else if(surface_image.format.fourcc == VA_FOURCC_I420){
+            u_src = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[1]);
+            v_src = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[2]);
+        } else if(surface_image.format.fourcc == VA_FOURCC_NV12){
+            u_src = (unsigned char *)((unsigned char*)surface_p + surface_image.offsets[1]);
+            v_src = u_src;
+        }
+
+        /* Y plane copy */
+        for (row = 0; row < surface_image.height; row++) {
+            memcpy(y_dst, y_src, surface_image.width);
+            y_src += surface_image.pitches[0];
+            y_dst += surface_image.width;
+        }
+
+        /* UV plane copy */
+        if (surface_image.format.fourcc == VA_FOURCC_YV12||
+            surface_image.format.fourcc == VA_FOURCC_I420){
+            for (row = 0; row < surface_image.height /2; row ++){
+                memcpy(v_dst, v_src, surface_image.width/2);
+                memcpy(u_dst, u_src, surface_image.width/2);
+
+                v_dst += surface_image.width/2;
+                u_dst += surface_image.width/2;
+
+                if (surface_image.format.fourcc == VA_FOURCC_YV12){
+                    v_src += surface_image.pitches[1];
+                    u_src += surface_image.pitches[2];
+                 } else {
+                    v_src += surface_image.pitches[2];
+                    u_src += surface_image.pitches[1];
+                 }
+             }
+         } else if (surface_image.format.fourcc == VA_FOURCC_NV12){
+             for (row = 0; row < surface_image.height / 2; row++) {
+                 for (col = 0; col < surface_image.width /2; col++) {
+                     u_dst[col] = u_src[col * 2];
+                     v_dst[col] = u_src[col * 2 + 1];
+                  }
+
+                  u_src += surface_image.pitches[1];
+                  u_dst += (surface_image.width / 2);
+                  v_dst += (surface_image.width / 2);
+             }
+         }
+
+         /* write frame to file */
+         do {
+             n_items = fwrite(newImageBuffer, y_size * 3 / 2, 1, fp);
+         } while (n_items != 1);
+
+     } else {
+         printf("Not supported YUV surface fourcc !!! \n");
+         return VA_STATUS_ERROR_INVALID_SURFACE;
+     }
+
+     if (newImageBuffer){
+         free(newImageBuffer);
+         newImageBuffer = NULL;
+     }
+
+     vaUnmapBuffer(va_dpy, surface_image.buf);
+     vaDestroyImage(va_dpy, surface_image.image_id);
+
+     return VA_STATUS_SUCCESS;
+}
+
+static VAStatus
+denoise_filter_init(VABufferID *filter_param_buf_id)
+{
+    VAStatus va_status = VA_STATUS_SUCCESS;
+    VAProcFilterParameterBuffer denoise_param;
+    VABufferID denoise_param_buf_id;
+    float intensity;
+
+    VAProcFilterCap denoise_caps;
+    uint32_t num_denoise_caps = 1;
+    va_status = vaQueryVideoProcFilterCaps(va_dpy, context_id,
+                                           VAProcFilterNoiseReduction,
+                                           &denoise_caps, &num_denoise_caps);
+    CHECK_VASTATUS(va_status,"vaQueryVideoProcFilterCaps");
+
+    if (read_value_float(g_config_file_fd, "DENOISE_INTENSITY", &intensity)) {
+        printf("Read denoise intensity failed, use default value");
+        intensity = denoise_caps.range.default_value;
+    }
+    intensity = adjust_to_range(&denoise_caps.range, intensity);
+
+    denoise_param.type  = VAProcFilterNoiseReduction;
+    denoise_param.value = intensity;
+
+    printf("Denoise intensity: %f\n", intensity);
+
+    va_status = vaCreateBuffer(va_dpy, context_id,
+                               VAProcFilterParameterBufferType, sizeof(denoise_param), 1,
+                               &denoise_param, &denoise_param_buf_id);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    *filter_param_buf_id = denoise_param_buf_id;
+
+    return va_status;
+}
+
+static VAStatus
+deinterlace_filter_init(VABufferID *filter_param_buf_id)
+{
+    VAStatus va_status = VA_STATUS_SUCCESS;
+    VAProcFilterParameterBufferDeinterlacing deinterlacing_param;
+    VABufferID deinterlacing_param_buf_id;
+    char algorithm_str[MAX_LEN], flags_str[MAX_LEN];
+    uint32_t i;
+
+    /* read and check whether configured deinterlace algorithm is supported */
+    deinterlacing_param.algorithm  = VAProcDeinterlacingBob;
+    if (!read_value_string(g_config_file_fd, "DEINTERLACING_ALGORITHM", algorithm_str)) {
+        printf("Deinterlacing algorithm in config: %s \n", algorithm_str);
+        if (!strcmp(algorithm_str, "VAProcDeinterlacingBob"))
+            deinterlacing_param.algorithm  = VAProcDeinterlacingBob;
+        else if (!strcmp(algorithm_str, "VAProcDeinterlacingWeave"))
+            deinterlacing_param.algorithm  = VAProcDeinterlacingWeave;
+        else if (!strcmp(algorithm_str, "VAProcDeinterlacingMotionAdaptive"))
+            deinterlacing_param.algorithm  = VAProcDeinterlacingMotionAdaptive;
+        else if (!strcmp(algorithm_str, "VAProcDeinterlacingMotionCompensated"))
+            deinterlacing_param.algorithm  = VAProcDeinterlacingMotionCompensated;
+    } else {
+        printf("Read deinterlace algorithm failed, use default algorithm");
+        deinterlacing_param.algorithm  = VAProcDeinterlacingBob;
+    }
+
+    VAProcFilterCapDeinterlacing deinterlacing_caps[VAProcDeinterlacingCount];
+    uint32_t num_deinterlacing_caps = VAProcDeinterlacingCount;
+    va_status = vaQueryVideoProcFilterCaps(va_dpy, context_id,
+                                           VAProcFilterDeinterlacing,
+                                           &deinterlacing_caps, &num_deinterlacing_caps);
+    CHECK_VASTATUS(va_status,"vaQueryVideoProcFilterCaps");
+
+    for (i = 0; i < VAProcDeinterlacingCount; i ++)
+       if (deinterlacing_caps[i].type == deinterlacing_param.algorithm)
+         break;
+
+    if (i == VAProcDeinterlacingCount) {
+        printf("Deinterlacing algorithm: %d is not supported by driver, \
+                use defautl algorithm :%d \n",
+                deinterlacing_param.algorithm,
+                VAProcDeinterlacingBob);
+        deinterlacing_param.algorithm = VAProcDeinterlacingBob;
+    }
+
+    /* read and check the deinterlace flags */
+    deinterlacing_param.flags = 0;
+    if (!read_value_string(g_config_file_fd, "DEINTERLACING_FLAG", flags_str)) {
+        if (strstr(flags_str, "VA_DEINTERLACING_BOTTOM_FIELD_FIRST"))
+            deinterlacing_param.flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST;
+        if (strstr(flags_str, "VA_DEINTERLACING_BOTTOM_FIELD"))
+            deinterlacing_param.flags |= VA_DEINTERLACING_BOTTOM_FIELD;
+        if (strstr(flags_str, "VA_DEINTERLACING_ONE_FIELD"))
+            deinterlacing_param.flags |= VA_DEINTERLACING_ONE_FIELD;
+    }
+
+    deinterlacing_param.type  = VAProcFilterDeinterlacing;
+
+    /* create deinterlace fitler buffer */
+    va_status = vaCreateBuffer(va_dpy, context_id,
+                               VAProcFilterParameterBufferType, sizeof(deinterlacing_param), 1,
+                               &deinterlacing_param, &deinterlacing_param_buf_id);
+    CHECK_VASTATUS(va_status, "vaCreateBuffer");
+
+    *filter_param_buf_id = deinterlacing_param_buf_id;
+
+    return va_status;
+}
+
+static VAStatus
+sharpening_filter_init(VABufferID *filter_param_buf_id)
+{
+    VAStatus va_status;
+    VAProcFilterParameterBuffer sharpening_param;
+    VABufferID sharpening_param_buf_id;
+    float intensity;
+
+    VAProcFilterCap sharpening_caps;
+    uint32_t num_sharpening_caps = 1;
+    va_status = vaQueryVideoProcFilterCaps(va_dpy, context_id,
+                VAProcFilterSharpening,
+                &sharpening_caps, &num_sharpening_caps);
+    CHECK_VASTATUS(va_status,"vaQueryVideoProcFilterCaps");
+
+    if(read_value_float(g_config_file_fd, "SHARPENING_INTENSITY", &intensity)) {
+        printf("Read sharpening intensity failed, use default value.");
+        intensity = sharpening_caps.range.default_value;
+    }
+
+    intensity = adjust_to_range(&sharpening_caps.range, intensity);
+    printf("Sharpening intensity: %f\n", intensity);
+    sharpening_param.value = intensity;
+
+    sharpening_param.type  = VAProcFilterSharpening;
+
+    /* create sharpening fitler buffer */
+    va_status = vaCreateBuffer(va_dpy, context_id,
+                               VAProcFilterParameterBufferType, sizeof(sharpening_param), 1,
+                               &sharpening_param, &sharpening_param_buf_id);
+
+    *filter_param_buf_id = sharpening_param_buf_id;
+
+    return va_status;
+}
+
+static VAStatus
+color_balance_filter_init(VABufferID *filter_param_buf_id)
+{
+    VAStatus va_status;
+    VAProcFilterParameterBufferColorBalance color_balance_param[4];
+    VABufferID color_balance_param_buf_id;
+    float value;
+    uint32_t i, count;
+    int8_t status;
+
+    VAProcFilterCapColorBalance color_balance_caps[VAProcColorBalanceCount];
+    unsigned int num_color_balance_caps = VAProcColorBalanceCount;
+    va_status = vaQueryVideoProcFilterCaps(va_dpy, context_id,
+                                           VAProcFilterColorBalance,
+                                           &color_balance_caps, &num_color_balance_caps);
+    CHECK_VASTATUS(va_status,"vaQueryVideoProcFilterCaps");
+
+    count = 0;
+    printf("Color balance params: ");
+    for (i = 0; i < num_color_balance_caps; i++) {
+        if (color_balance_caps[i].type == VAProcColorBalanceHue) {
+            color_balance_param[count].attrib  = VAProcColorBalanceHue;
+            status = read_value_float(g_config_file_fd, "COLOR_BALANCE_HUE", &value);
+            printf("Hue: ");
+        } else if (color_balance_caps[i].type == VAProcColorBalanceSaturation) {
+            color_balance_param[count].attrib  = VAProcColorBalanceSaturation;
+            status = read_value_float(g_config_file_fd, "COLOR_BALANCE_SATURATION", &value);
+            printf("Saturation: ");
+        } else if (color_balance_caps[i].type == VAProcColorBalanceBrightness) {
+            color_balance_param[count].attrib  = VAProcColorBalanceBrightness;
+            status = read_value_float(g_config_file_fd, "COLOR_BALANCE_BRIGHTNESS", &value);
+            printf("Brightness: ");
+        } else if (color_balance_caps[i].type == VAProcColorBalanceContrast) {
+            color_balance_param[count].attrib  = VAProcColorBalanceContrast;
+            status = read_value_float(g_config_file_fd, "COLOR_BALANCE_CONTRAST", &value);
+            printf("Contrast: ");
+        } else {
+            continue;
+        }
+
+        if (status)
+            value = color_balance_caps[i].range.default_value;
+        else
+            value = adjust_to_range(&color_balance_caps[i].range, value);
+
+        color_balance_param[count].value = value;
+        color_balance_param[count].type  = VAProcFilterColorBalance;
+        count++;
+
+        printf("%4f,  ", value);
+    }
+    printf("\n");
+
+    va_status = vaCreateBuffer(va_dpy, context_id,
+                               VAProcFilterParameterBufferType, sizeof(color_balance_param), 4,
+                               color_balance_param, &color_balance_param_buf_id);
+
+    *filter_param_buf_id = color_balance_param_buf_id;
+
+    return va_status;
+}
+
+static VAStatus
+blending_state_init(VABlendState *state)
+{
+    VAStatus va_status = VA_STATUS_SUCCESS;
+    char blending_flags_str[MAX_LEN];
+    float global_alpha;
+    uint32_t min_luma, max_luma;
+
+    /* read and check blend state */
+    state->flags = 0;
+    if (!read_value_string(g_config_file_fd, "BLENDING_FLAGS", blending_flags_str)){
+        if (strstr(blending_flags_str, "VA_BLEND_GLOBAL_ALPHA")) {
+           if (read_value_float(g_config_file_fd, "BLENDING_GLOBAL_ALPHA", &global_alpha)) {
+               global_alpha = 1.0  ;
+               printf("Use default global alpha : %4f \n", global_alpha);
+           }
+           state->flags |= VA_BLEND_GLOBAL_ALPHA;
+           state->global_alpha = global_alpha;
+        }
+        if (strstr(blending_flags_str, "VA_BLEND_LUMA_KEY")) {
+            if (read_value_uint8(g_config_file_fd, "BLENDING_MIN_LUMA", &g_blending_min_luma)) {
+                g_blending_min_luma = 1;
+                printf("Use default min luma : %3d \n", g_blending_min_luma);
+            }
+            if (read_value_uint8(g_config_file_fd, "BLENDING_MAX_LUMA", &g_blending_max_luma)) {
+                g_blending_max_luma = 254;
+                printf("Use default max luma : %3d \n", g_blending_max_luma);
+            }
+            state->flags |= VA_BLEND_LUMA_KEY;
+            state->min_luma = g_blending_min_luma * 1.0 / 256;
+            state->max_luma = g_blending_max_luma * 1.0 / 256;
+        }
+
+        printf("Blending type = %s, alpha = %f, min_luma = %3d, max_luma = %3d \n",
+              blending_flags_str, global_alpha, min_luma, max_luma);
+    }
+
+    VAProcPipelineCaps pipeline_caps;
+    va_status = vaQueryVideoProcPipelineCaps(va_dpy, context_id,
+                NULL, 0, &pipeline_caps);
+    CHECK_VASTATUS(va_status,"vaQueryVideoProcPipelineCaps");
+
+    if (!pipeline_caps.blend_flags){
+        printf("Blending is not supported in driver! \n");
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+    }
+
+    if (! (pipeline_caps.blend_flags & state->flags)) {
+        printf("Driver do not support current blending flags: %d", state->flags);
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+    }
+
+    return va_status;
+}
+
+static VAStatus
+video_frame_process(VAProcFilterType filter_type,
+                    uint32_t frame_idx,
+                    VASurfaceID in_surface_id,
+                    VASurfaceID out_surface_id)
+{
+    VAStatus va_status;
+    VAProcPipelineParameterBuffer pipeline_param;
+    VARectangle surface_region, output_region;
+    VABufferID pipeline_param_buf_id = VA_INVALID_ID;
+    VABufferID filter_param_buf_id = VA_INVALID_ID;
+    VABlendState state ;
+    uint32_t filter_count = 1;
+
+    /* create denoise_filter buffer id */
+    switch(filter_type){
+      case VAProcFilterNoiseReduction:
+           denoise_filter_init(&filter_param_buf_id);
+           break;
+      case VAProcFilterDeinterlacing:
+           deinterlace_filter_init(&filter_param_buf_id);
+           break;
+      case VAProcFilterSharpening:
+           sharpening_filter_init(&filter_param_buf_id);
+           break;
+      case VAProcFilterColorBalance:
+           color_balance_filter_init(&filter_param_buf_id);
+           break;
+      default :
+           filter_count = 0;
+         break;
+    }
+
+    /* Fill pipeline buffer */
+    surface_region.x = 0;
+    surface_region.y = 0;
+    surface_region.width = g_in_pic_width;
+    surface_region.height = g_in_pic_height;
+    output_region.x = 0;
+    output_region.y = 0;
+    output_region.width = g_out_pic_width;
+    output_region.height = g_out_pic_height;
+
+    memset(&pipeline_param, 0, sizeof(pipeline_param));
+    pipeline_param.surface = in_surface_id;
+    pipeline_param.surface_region = &surface_region;
+    pipeline_param.output_region = &output_region;
+
+    pipeline_param.filter_flags = 0;
+    pipeline_param.filters      = &filter_param_buf_id;
+    pipeline_param.num_filters  = filter_count;
+
+    /* Blending related state */
+    if (g_blending_enabled){
+        blending_state_init(&state);
+        pipeline_param.blend_state = &state;
+    }
+
+    va_status = vaCreateBuffer(va_dpy,
+                               context_id,
+                               VAProcPipelineParameterBufferType,
+                               sizeof(pipeline_param),
+                               1,
+                               &pipeline_param,
+                               &pipeline_param_buf_id);
+    CHECK_VASTATUS(va_status, "vaCreateBuffer");
+
+    va_status = vaBeginPicture(va_dpy,
+                               context_id,
+                               out_surface_id);
+    CHECK_VASTATUS(va_status, "vaBeginPicture");
+
+    va_status = vaRenderPicture(va_dpy,
+                                context_id,
+                                &pipeline_param_buf_id,
+                                1);
+    CHECK_VASTATUS(va_status, "vaRenderPicture");
+
+    va_status = vaEndPicture(va_dpy, context_id);
+    CHECK_VASTATUS(va_status, "vaEndPicture");
+
+    if (filter_param_buf_id != VA_INVALID_ID)
+        vaDestroyBuffer(va_dpy,filter_param_buf_id);
+
+    if (pipeline_param_buf_id != VA_INVALID_ID)
+        vaDestroyBuffer(va_dpy,pipeline_param_buf_id);
+
+    return va_status;
+}
+
+static VAStatus
+vpp_context_create()
+{
+    VAStatus va_status = VA_STATUS_SUCCESS;
+    uint32_t i;
+
+    /* VA driver initialization */
+    va_dpy = va_open_display();
+    int32_t major_ver, minor_ver;
+    va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
+    assert(va_status == VA_STATUS_SUCCESS);
+
+    /* Check whether VPP is supported by driver */
+    VAEntrypoint entrypoints[5];
+    int32_t num_entrypoints;
+    num_entrypoints = vaMaxNumEntrypoints(va_dpy);
+    va_status = vaQueryConfigEntrypoints(va_dpy,
+                                         VAProfileNone,
+                                         entrypoints,
+                                         &num_entrypoints);
+    CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
+
+    for	(i = 0; i < num_entrypoints; i++) {
+        if (entrypoints[i] == VAEntrypointVideoProc)
+            break;
+    }
+
+    if (i == num_entrypoints) {
+        printf("VPP is not supported by driver\n");
+        assert(0);
+    }
+
+    /* Render target surface format check */
+    VAConfigAttrib attrib;
+    attrib.type = VAConfigAttribRTFormat;
+    va_status = vaGetConfigAttributes(va_dpy,
+                                      VAProfileNone,
+                                      VAEntrypointVideoProc,
+                                      &attrib,
+                                     1);
+    CHECK_VASTATUS(va_status, "vaGetConfigAttributes");
+    if ((attrib.value != g_out_format)) {
+        printf("RT format %d is not supported by VPP !\n",g_out_format);
+        assert(0);
+    }
+
+    /* Create surface/config/context for VPP pipeline */
+    va_status = create_surface(&g_in_surface_id, g_in_pic_width, g_in_pic_height,
+                                g_in_fourcc, g_in_format);
+    CHECK_VASTATUS(va_status, "vaCreateSurfaces for input");
+
+    va_status = create_surface(&g_out_surface_id, g_out_pic_width, g_out_pic_height,
+                                g_out_fourcc, g_out_format);
+    CHECK_VASTATUS(va_status, "vaCreateSurfaces for output");
+
+    va_status = vaCreateConfig(va_dpy,
+                               VAProfileNone,
+                               VAEntrypointVideoProc,
+                               &attrib,
+                               1,
+                               &config_id);
+    CHECK_VASTATUS(va_status, "vaCreateConfig");
+
+    /* Source surface format check */
+    uint32_t num_surf_attribs = VASurfaceAttribCount;
+    VASurfaceAttrib * surf_attribs = (VASurfaceAttrib*)
+              malloc(sizeof(VASurfaceAttrib) * num_surf_attribs);
+    if (!surf_attribs)
+       assert(0);
+
+    va_status = vaQuerySurfaceAttributes(va_dpy,
+                                        config_id,
+                                        surf_attribs,
+                                        &num_surf_attribs);
+
+    if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) {
+        surf_attribs = (VASurfaceAttrib*)realloc(surf_attribs,
+                        sizeof(VASurfaceAttrib) * num_surf_attribs);
+         if (!surf_attribs)
+             assert(0);
+         va_status = vaQuerySurfaceAttributes(va_dpy,
+                                              config_id,
+                                              surf_attribs,
+                                              &num_surf_attribs);
+    }
+    CHECK_VASTATUS(va_status, "vaQuerySurfaceAttributes");
+
+    for (i = 0; i < num_surf_attribs; i++) {
+        if (surf_attribs[i].type == VASurfaceAttribPixelFormat &&
+            surf_attribs[i].value.value.i == g_in_fourcc)
+            break;
+    }
+    free(surf_attribs);
+
+    if (i == num_surf_attribs) {
+        printf("Input fourCC %d  is not supported by VPP !\n", g_in_fourcc);
+        assert(0);
+    }
+
+    va_status = vaCreateContext(va_dpy,
+                                config_id,
+                                g_out_pic_width,
+                                g_out_pic_height,
+                                VA_PROGRESSIVE,
+                                &g_out_surface_id,
+                                1,
+                                &context_id);
+    CHECK_VASTATUS(va_status, "vaCreateContext");
+
+
+    /* Validate  whether currect filter is supported */
+    if (g_filter_type != VAProcFilterNone) {
+        uint32_t supported_filter_num = VAProcFilterCount;
+        VAProcFilterType supported_filter_types[VAProcFilterCount];
+
+        va_status = vaQueryVideoProcFilters(va_dpy,
+                                            context_id,
+                                            supported_filter_types,
+                                            &supported_filter_num);
+
+        CHECK_VASTATUS(va_status, "vaQueryVideoProcFilters");
+
+        for (i = 0; i < supported_filter_num; i++){
+            if (supported_filter_types[i] == g_filter_type)
+                break;
+        }
+
+        if (i == supported_filter_num) {
+            printf("VPP filter type %s is not supported by driver !\n", g_filter_type_name);
+            assert(0);
+        }
+    }
+
+    return va_status;
+}
+
+static void
+vpp_context_destroy()
+{
+    /* Release resource */
+    vaDestroySurfaces(va_dpy, &g_in_surface_id, 1);
+    vaDestroySurfaces(va_dpy, &g_out_surface_id, 1);
+    vaDestroyContext(va_dpy, context_id);
+    vaDestroyConfig(va_dpy, config_id);
+
+    vaTerminate(va_dpy);
+    va_close_display(va_dpy);
+}
+
+static int8_t
+parse_fourcc_and_format(char *str, uint32_t *fourcc, uint32_t *format)
+{
+    if (!strcmp(str, "YV12")){
+        *fourcc = VA_FOURCC('Y', 'V', '1', '2');
+        *format = VA_RT_FORMAT_YUV420;
+    } else if(!strcmp(str, "I420")){
+        *fourcc = VA_FOURCC('I', '4', '2', '0');
+        *format = VA_RT_FORMAT_YUV420;
+    } else if(!strcmp(str, "NV12")){
+        *fourcc = VA_FOURCC('N', 'V', '1', '2');
+        *format = VA_RT_FORMAT_YUV420;
+    } else{
+        printf("Not supported format: %s! Currently only support following format: %s\n",
+         str, "YV12, I420, NV12");
+        assert(0);
+    }
+    return 0;
+}
+
+static int8_t
+parse_basic_parameters()
+{
+    char str[MAX_LEN];
+
+    /* Read src frame file information */
+    read_value_string(g_config_file_fd, "SRC_FILE_NAME", g_src_file_name);
+    read_value_uint32(g_config_file_fd, "SRC_FRAME_WIDTH", &g_in_pic_width);
+    read_value_uint32(g_config_file_fd, "SRC_FRAME_HEIGHT", &g_in_pic_height);
+    read_value_string(g_config_file_fd, "SRC_FRAME_FORMAT", str);
+    parse_fourcc_and_format(str, &g_in_fourcc, &g_in_format);
+
+    /* Read dst frame file information */
+    read_value_string(g_config_file_fd, "DST_FILE_NAME", g_dst_file_name);
+    read_value_uint32(g_config_file_fd, "DST_FRAME_WIDTH", &g_out_pic_width);
+    read_value_uint32(g_config_file_fd, "DST_FRAME_HEIGHT",&g_out_pic_height);
+    read_value_string(g_config_file_fd, "DST_FRAME_FORMAT", str);
+    parse_fourcc_and_format(str, &g_out_fourcc, &g_out_format);
+
+    read_value_uint32(g_config_file_fd, "FRAME_SUM", &g_frame_count);
+
+    /* Read filter type */
+    if (read_value_string(g_config_file_fd, "FILTER_TYPE", g_filter_type_name)){
+        printf("Read filter type error !\n");
+        assert(0);
+    }
+
+    if (!strcmp(g_filter_type_name, "VAProcFilterNoiseReduction"))
+        g_filter_type = VAProcFilterNoiseReduction;
+    else if (!strcmp(g_filter_type_name, "VAProcFilterDeinterlacing"))
+        g_filter_type = VAProcFilterDeinterlacing;
+    else if (!strcmp(g_filter_type_name, "VAProcFilterSharpening"))
+        g_filter_type = VAProcFilterSharpening;
+    else if (!strcmp(g_filter_type_name, "VAProcFilterColorBalance"))
+        g_filter_type = VAProcFilterColorBalance;
+    else if (!strcmp(g_filter_type_name, "VAProcFilterNone"))
+        g_filter_type = VAProcFilterNone;
+    else {
+        printf("Unsupported filter type :%s \n", g_filter_type_name);
+        return -1;
+    }
+
+    /* Check whether blending is enabled */
+    if (read_value_uint8(g_config_file_fd, "BLENDING_ENABLED", &g_blending_enabled))
+        g_blending_enabled = 0;
+
+    if (g_blending_enabled)
+        printf("Blending will be done \n");
+
+    if (g_in_pic_width != g_out_pic_width ||
+        g_in_pic_height != g_out_pic_height)
+        printf("Scaling will be done : from %4d x %4d to %4d x %4d \n",
+                g_in_pic_width, g_in_pic_height,
+                g_out_pic_width, g_out_pic_height);
+
+    if (g_in_fourcc != g_out_fourcc)
+        printf("Format conversion will be done: from %d to %d \n",
+               g_in_fourcc, g_out_fourcc);
+
+    return 0;
+}
+
+int32_t main(int32_t argc, char *argv[])
+{
+    VAStatus va_status;
+    uint32_t i;
+
+    if (argc != 2){
+        printf("Input error! please specify the configure file \n");
+        return -1;
+    }
+
+    /* Parse the configure file for video process*/
+    strcpy(g_config_file_name, argv[1]);
+    if (NULL == (g_config_file_fd = fopen(g_config_file_name, "r"))){
+        printf("Open configure file %s failed!\n",g_config_file_name);
+        assert(0);
+    }
+
+    /* Parse basic parameters */
+    if (parse_basic_parameters()){
+        printf("Parse parameters in configure file error\n");
+        assert(0);
+    }
+
+    va_status = vpp_context_create();
+    if (va_status != VA_STATUS_SUCCESS) {
+        printf("vpp context create failed \n");
+        assert(0);
+    }
+
+    /* Video frame fetch, process and store */
+    if (NULL == (g_src_file_fd = fopen(g_src_file_name, "r"))){
+        printf("Open SRC_FILE_NAME: %s failed, please specify it in config file: %s !\n",
+                g_src_file_name, g_config_file_name);
+        assert(0);
+    }
+
+    if (NULL == (g_dst_file_fd = fopen(g_dst_file_name, "w"))){
+        printf("Open DST_FILE_NAME: %s failed, please specify it in config file: %s !\n",
+               g_dst_file_name, g_config_file_name);
+        assert(0);
+    }
+
+    printf("\nStart to process, processing type is %s ...\n", g_filter_type_name);
+    struct timeval start_time, end_time;
+    gettimeofday(&start_time, NULL);
+
+    for (i = 0; i < g_frame_count; i ++){
+        if (g_blending_enabled) {
+            construct_nv12_mask_surface(g_in_surface_id, g_blending_min_luma, g_blending_max_luma);
+            upload_yv12_frame_to_yuv_surface(g_src_file_fd, g_out_surface_id);
+        } else {
+            upload_yv12_frame_to_yuv_surface(g_src_file_fd, g_in_surface_id);
+        }
+
+        video_frame_process(g_filter_type, i, g_in_surface_id, g_out_surface_id);
+        store_yuv_surface_to_yv12_frame(g_dst_file_fd, g_out_surface_id);
+    }
+
+    gettimeofday(&end_time, NULL);
+    float duration = (end_time.tv_sec - start_time.tv_sec) +
+                     (end_time.tv_usec - start_time.tv_usec)/1000000.0;
+    printf("Finish processing, performance: \n" );
+    printf("%d frames processed in: %f s, ave time = %.6fs \n",g_frame_count, duration, duration/g_frame_count);
+
+    if (g_src_file_fd)
+       fclose(g_src_file_fd);
+
+    if (g_dst_file_fd)
+       fclose(g_dst_file_fd);
+
+    if (g_config_file_fd)
+       fclose(g_config_file_fd);
+
+    vpp_context_destroy();
+
+    return 0;
+}
+
diff --git a/va/Android.mk b/va/Android.mk
index 3f9c24c..eae7993 100755
--- a/va/Android.mk
+++ b/va/Android.mk
@@ -23,27 +23,27 @@
 # For libva
 # =====================================================
 
-ifeq ($(INTEL_VA),true)
-
 LOCAL_PATH:= $(call my-dir)
 
+ifeq ($(ENABLE_IMG_GRAPHICS),true)
+
 LIBVA_DRIVERS_PATH = /system/lib
-
 include $(CLEAR_VARS)
 
-#LIBVA_MINOR_VERSION := 31
-#LIBVA_MAJOR_VERSION := 0 
-
 LOCAL_SRC_FILES := \
 	va.c \
 	va_trace.c \
 	va_fool.c
 
-LOCAL_CFLAGS += \
+LOCAL_CFLAGS := \
 	-DANDROID \
-	-DVA_DRIVERS_PATH="\"$(LIBVA_DRIVERS_PATH)\""
+	-DVA_DRIVERS_PATH="\"$(LIBVA_DRIVERS_PATH)\"" \
+	-DLOG_TAG=\"libva\" \
+	-DANDROID_ALOG
 
-LOCAL_C_INCLUDES += \
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/..
+
+LOCAL_C_INCLUDES := \
 	$(TARGET_OUT_HEADERS)/libva \
 	$(LOCAL_PATH)/x11 \
 	$(LOCAL_PATH)/..
@@ -51,17 +51,22 @@
 LOCAL_COPY_HEADERS := \
 	va.h \
 	va_version.h \
+	va_dec_hevc.h \
+	va_dec_jpeg.h \
+	va_dec_vp8.h \
+	va_dec_vp9.h \
 	va_enc.h \
 	va_enc_h264.h \
+	va_enc_jpeg.h \
+	va_enc_vp8.h \
 	va_backend.h \
-	x11/va_dricommon.h \
+	va_drmcommon.h \
 	va_vpp.h \
-	va_dec_vp8.h \
-	va_dec_jpeg.h \
-	va_backend_vpp.h
+	va_backend_vpp.h \
+	va_enc_mpeg2.h \
 
 LOCAL_COPY_HEADERS_TO := libva/va
-
+LOCAL_CFLAGS += -Werror
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libva
 
@@ -83,23 +88,25 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-	android/va_android.cpp
+	android/va_android.cpp \
+	drm/va_drm_utils.c
 
-LOCAL_CFLAGS += \
-	-DANDROID 
+LOCAL_CFLAGS := \
+	-DANDROID -DLOG_TAG=\"libva-android\"
 
-LOCAL_C_INCLUDES += \
+LOCAL_C_INCLUDES := \
 	$(TARGET_OUT_HEADERS)/libva \
-	$(LOCAL_PATH)/x11
+	$(TARGET_OUT_HEADERS)/libdrm \
+	$(LOCAL_PATH)/drm
 
 LOCAL_COPY_HEADERS_TO := libva/va
 
 LOCAL_COPY_HEADERS := va_android.h		
-
+LOCAL_CFLAGS += -Werror
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libva-android
 
-LOCAL_SHARED_LIBRARIES := libva
+LOCAL_SHARED_LIBRARIES := libva libdrm
 
 include $(BUILD_SHARED_LIBRARY)
 
@@ -112,17 +119,17 @@
 LOCAL_SRC_FILES := \
 	egl/va_egl.c
 
-LOCAL_CFLAGS += \
-	-DANDROID
+LOCAL_CFLAGS := \
+	-DANDROID -DLOG_TAG=\"libva-egl\"
 
-LOCAL_C_INCLUDES += \
+LOCAL_C_INCLUDES := \
 	$(TARGET_OUT_HEADERS)/libva \
 	$(LOCAL_PATH)/x11
 
 LOCAL_COPY_HEADERS_TO := libva/va
 
 LOCAL_COPY_HEADERS := egl/va_egl.h egl/va_backend_egl.h
-
+LOCAL_CFLAGS += -Werror
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libva-egl
 
@@ -138,9 +145,9 @@
 
 LOCAL_SRC_FILES := va_tpi.c
 
-LOCAL_CFLAGS += -DANDROID
+LOCAL_CFLAGS := -DANDROID -DLOG_TAG=\"libva-tpi\"
 
-LOCAL_C_INCLUDES += \
+LOCAL_C_INCLUDES := \
 	$(TARGET_OUT_HEADERS)/libva \
 	$(LOCAL_PATH)/..
 
@@ -151,9 +158,10 @@
 	va_backend_tpi.h
 
 LOCAL_SHARED_LIBRARIES := libva
-
+LOCAL_CFLAGS += -Werror
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libva-tpi
 
 include $(BUILD_SHARED_LIBRARY)
-endif
+
+endif # $(ENABLE_IMG_GRAPHICS),true)
diff --git a/va/Makefile.am b/va/Makefile.am
index 8919c47..13ea35a 100644
--- a/va/Makefile.am
+++ b/va/Makefile.am
@@ -26,6 +26,7 @@
 	$(LIBVA_CFLAGS) \
 	-I$(top_srcdir) \
 	-I$(top_srcdir)/va/x11 \
+	-I$(top_srcdir)/va/vendor/intel \
 	-DVA_DRIVERS_PATH="\"$(LIBVA_DRIVERS_PATH)\""
 
 LDADD = \
@@ -44,15 +45,19 @@
 	va_backend_tpi.h	\
 	va_backend_vpp.h	\
 	va_compat.h		\
+	va_dec_hevc.h		\
 	va_dec_jpeg.h		\
 	va_dec_vp8.h		\
-	va_dummy.h		\
+	va_dec_vp9.h		\
+	va_drmcommon.h		\
 	va_enc.h		\
 	va_enc_h264.h		\
+	va_enc_jpeg.h		\
+	va_enc_vp8.h		\
+	va_enc_mpeg2.h		\
 	va_tpi.h		\
 	va_version.h		\
 	va_vpp.h		\
-	va_x11.h		\
 	$(NULL)
 
 libva_source_h_priv = \
@@ -78,25 +83,38 @@
 lib_LTLIBRARIES			+= libva-tpi.la
 libva_tpi_la_SOURCES		= va_tpi.c
 libva_tpi_la_LDFLAGS		= $(LDADD) -no-undefined
-libva_tpi_la_DEPENDENCIES	= $(libvacorelib) 
-libva_tpi_la_LIBADD		= $(libvacorelib) -ldl
+libva_tpi_la_DEPENDENCIES	= libva.la 
+libva_tpi_la_LIBADD		= libva.la -ldl
 
+if USE_DRM
+SUBDIRS				+= drm
+lib_LTLIBRARIES			+= libva-drm.la
+libva_drm_la_SOURCES		=
+libva_drm_la_LDFLAGS		= $(LDADD)
+libva_drm_la_DEPENDENCIES	= libva.la drm/libva_drm.la
+libva_drm_la_LIBADD		= libva.la drm/libva_drm.la \
+	$(LIBVA_LIBS) $(DRM_LIBS) -ldl
+endif
+
+if USE_X11
 SUBDIRS				+= x11
 lib_LTLIBRARIES			+= libva-x11.la
+libva_source_h			+= va_x11.h
 libva_x11_la_SOURCES		= 
 libva_x11_la_LDFLAGS		= $(LDADD)
-libva_x11_la_DEPENDENCIES	= $(libvacorelib) x11/libva_x11.la
-libva_x11_la_LIBADD		= $(libvacorelib) x11/libva_x11.la \
-	$(LIBVA_LIBS) $(X11_LIBS) $(XEXT_LIBS) $(DRM_LIBS) $(XFIXES_LIBS) -ldl
+libva_x11_la_DEPENDENCIES	= libva.la x11/libva_x11.la
+libva_x11_la_LIBADD		= libva.la x11/libva_x11.la \
+	$(LIBVA_LIBS) $(X11_LIBS) $(XEXT_LIBS) $(XFIXES_LIBS) $(DRM_LIBS) -ldl
+endif
 
 if USE_GLX
 SUBDIRS				+= glx
 lib_LTLIBRARIES			+= libva-glx.la
 libva_glx_la_SOURCES		=
 libva_glx_la_LDFLAGS		= $(LDADD)
-libva_glx_la_DEPENDENCIES	= $(libvacorelib) glx/libva_glx.la libva-x11.la
-libva_glx_la_LIBADD		= $(libvacorelib) glx/libva_glx.la libva-x11.la \
-	$(GL_DEPS_LIBS) -ldl
+libva_glx_la_DEPENDENCIES	= libva.la glx/libva_glx.la libva-x11.la
+libva_glx_la_LIBADD		= libva.la glx/libva_glx.la libva-x11.la \
+	$(GLX_LIBS) -ldl
 endif
 
 if USE_EGL
@@ -104,22 +122,23 @@
 lib_LTLIBRARIES			+= libva-egl.la
 libva_egl_la_SOURCES		=
 libva_egl_la_LDFLAGS		= $(LDADD)
-libva_egl_la_DEPENDENCIES	= $(libvacorelib) egl/libva_egl.la libva-x11.la
-libva_egl_la_LIBADD		= $(libvacorelib) egl/libva_egl.la libva-x11.la \
-	$(GL_DEPS_LIBS) -ldl
+libva_egl_la_DEPENDENCIES	= libva.la egl/libva_egl.la 
+libva_egl_la_LIBADD		= libva.la egl/libva_egl.la \
+	$(EGL_LIBS) -ldl
 endif
 
-if BUILD_DUMMY_BACKEND
-SUBDIRS				+= dummy
-lib_LTLIBRARIES			+= libva-dummy.la
-libva_dummy_la_SOURCES		= 
-libva_dummy_la_LDFLAGS		= $(LDADD)
-libva_dummy_la_DEPENDENCIES	= $(libvacorelib) dummy/libva_dummy.la
-libva_dummy_la_LIBADD		= $(libvacorelib) dummy/libva_dummy.la \
-	$(LIBVA_LIBS) $(DRM_LIBS)
+if USE_WAYLAND
+SUBDIRS				+= wayland
+lib_LTLIBRARIES			+= libva-wayland.la
+libva_wayland_la_SOURCES	=
+libva_wayland_la_LDFLAGS	= $(LDADD)
+libva_wayland_la_DEPENDENCIES	= libva.la wayland/libva_wayland.la
+libva_wayland_la_LIBADD		= libva.la wayland/libva_wayland.la \
+	$(WAYLAND_LIBS) $(DRM_LIBS) -ldl
 endif
 
-DIST_SUBDIRS = x11 glx egl dummy
+
+DIST_SUBDIRS = x11 glx egl drm wayland
 
 DISTCLEANFILES = \
 	va_version.h		\
@@ -127,4 +146,5 @@
 
 EXTRA_DIST = \
 	va_version.h.in		\
+	libva.syms		\
 	$(NULL)
diff --git a/va/android/drmtest.c b/va/android/drmtest.c
deleted file mode 100644
index 444ef47..0000000
--- a/va/android/drmtest.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright © 2007 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <fnmatch.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include "drmtest.h"
-
-#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
-#include <libudev.h>
-
-static int is_master(int fd)
-{
-	drm_client_t client;
-	int ret;
-
-	/* Check that we're the only opener and authed. */
-	client.idx = 0;
-	ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
-	assert (ret == 0);
-	if (!client.auth)
-		return 0;
-	client.idx = 1;
-	ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
-	if (ret != -1 || errno != EINVAL)
-		return 0;
-
-	return 1;
-}
-
-/** Open the first DRM device matching the criteria */
-int drm_open_matching(const char *pci_glob, int flags, int *vendor_id, int *device_id)
-{
-	struct udev *udev;
-	struct udev_enumerate *e;
-	struct udev_device *device, *parent;
-        struct udev_list_entry *entry;
-	const char *pci_id, *path;
-        char *tmp;
-	int fd;
-
-        *vendor_id = 0;
-        *device_id = 0;
-        
-	udev = udev_new();
-	if (udev == NULL) {
-		fprintf(stderr, "failed to initialize udev context\n");
-                return -1;
-		//abort();
-	}
-
-	fd = -1;
-	e = udev_enumerate_new(udev);
-	udev_enumerate_add_match_subsystem(e, "drm");
-        udev_enumerate_scan_devices(e);
-        udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
-		path = udev_list_entry_get_name(entry);
-		device = udev_device_new_from_syspath(udev, path);
-		parent = udev_device_get_parent(device);
-		/* Filter out KMS output devices. */
-		if (strcmp(udev_device_get_subsystem(parent), "pci") != 0)
-			continue;
-		pci_id = udev_device_get_property_value(parent, "PCI_ID");
-		if (fnmatch(pci_glob, pci_id, 0) != 0)
-			continue;
-		fd = open(udev_device_get_devnode(device), O_RDWR);
-		if (fd < 0)
-			continue;
-		if ((flags & DRM_TEST_MASTER) && !is_master(fd)) {
-			close(fd);
-			fd = -1;
-			continue;
-		}
-
-		break;
-	}
-        udev_enumerate_unref(e);
-	udev_unref(udev);
-
-        *vendor_id = (int) strtol(pci_id, &tmp, 16);
-        *device_id = (int) strtol((tmp+1), NULL, 16);
-        
-	return fd;
-}
-
-int drm_open_any(int *vendor_id, int *device_id)
-{
-        int fd = drm_open_matching("*:*", 0, vendor_id, device_id);
-
-	if (fd < 0) {
-		fprintf(stderr, "failed to open any drm device\n");
-		//abort();
-	}
-
-	return fd;
-}
-
-/**
- * Open the first DRM device we can find where we end up being the master.
- */
-int drm_open_any_master(void)
-{
-        int vendor_id, device_id;
-	int fd = drm_open_matching("*:*", DRM_TEST_MASTER, &vendor_id, &device_id);
-
-	if (fd < 0) {
-		fprintf(stderr, "failed to open any drm device\n");
-		abort();
-	}
-
-	return fd;
-
-}
diff --git a/va/android/drmtest.h b/va/android/drmtest.h
deleted file mode 100644
index 5f10f08..0000000
--- a/va/android/drmtest.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright © 2007 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
-
-#include "xf86drm.h"
-
-#define DRM_TEST_MASTER 0x01
-
-int drm_open_any(int *vendor_id, int *device_id);
-int drm_open_any_master(void);
-int drm_open_matching(const char *pci_glob, int flags, int *vendor_id, int *device_id);
diff --git a/va/android/va_android.cpp b/va/android/va_android.cpp
index 4f935de..3e220a6 100644
--- a/va/android/va_android.cpp
+++ b/va/android/va_android.cpp
@@ -23,29 +23,25 @@
  */
 
 #define _GNU_SOURCE 1
+#include "sysdeps.h"
 #include "va.h"
 #include "va_backend.h"
 #include "va_trace.h"
 #include "va_fool.h"
 #include "va_android.h"
-#include "va_dricommon.h" /* needs some helper functions from this file */
-#include <stdio.h>
-#include <stdlib.h>
+#include "va_drmcommon.h"
+#include "va_drm_utils.h"
 #include <stdarg.h>
-#include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <dlfcn.h>
 #include <errno.h>
-#ifndef ANDROID
-#include <libudev.h>
-#include "drmtest.h"
-#endif
+
 
 #define CHECK_SYMBOL(func) { if (!func) printf("func %s not found\n", #func); return VA_STATUS_ERROR_UNKNOWN; }
-#define DEVICE_NAME "/dev/card0"
+#define DEVICE_NAME "/dev/dri/card0"
 
 static int open_device (char *dev_name)
 {
@@ -89,116 +85,51 @@
     VADisplayContextP pDisplayContext
 )
 {
-    struct dri_state *dri_state;
+    struct drm_state *drm_state;
 
     if (pDisplayContext == NULL)
         return;
 
     /* close the open-ed DRM fd */
-    dri_state = (struct dri_state *)pDisplayContext->pDriverContext->dri_state;
-    close(dri_state->fd);
+    drm_state = (struct drm_state *)pDisplayContext->pDriverContext->drm_state;
+    close(drm_state->fd);
 
-    free(pDisplayContext->pDriverContext->dri_state);
+    free(pDisplayContext->pDriverContext->drm_state);
     free(pDisplayContext->pDriverContext);
     free(pDisplayContext);
 }
 
-#ifdef ANDROID
 static VAStatus va_DisplayContextGetDriverName (
     VADisplayContextP pDisplayContext,
     char **driver_name
 )
 {
-    VADriverContextP ctx = pDisplayContext->pDriverContext;
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
-    char *driver_name_env;
-    int vendor_id, device_id;
-    
-    struct {
-        int vendor_id;
-        int device_id;
-        char driver_name[64];
-    } devices[] = {
-        { 0x8086, 0x4100, "pvr" },
-        { 0x8086, 0x0130, "pvr" },
-        { 0x1010, 0x1cf2, "pvr" },
-        { 0x0,    0x0,    "\0" },
-    };
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    struct drm_state * drm_state = (struct drm_state *)ctx->drm_state;
 
-    memset(dri_state, 0, sizeof(*dri_state));
-    dri_state->fd = open_device((char *)DEVICE_NAME);
-    
-    if (dri_state->fd < 0) {
+    memset(drm_state, 0, sizeof(*drm_state));
+    drm_state->fd = open_device((char *)DEVICE_NAME);
+
+    if (drm_state->fd < 0) {
         fprintf(stderr,"can't open DRM devices\n");
         return VA_STATUS_ERROR_UNKNOWN;
     }
+    drm_state->auth_type = VA_DRM_AUTH_CUSTOM;
 
-    /* TBD: other vendor driver names */
-    vendor_id = devices[0].vendor_id;
-    device_id = devices[0].device_id;
-    *driver_name = strdup(devices[0].driver_name);
-        
-    dri_state->driConnectedFlag = VA_DUMMY;
-
-    return VA_STATUS_SUCCESS;
-}
-#else
-static VAStatus va_DisplayContextGetDriverName (
-    VADisplayContextP pDisplayContext,
-    char **driver_name
-)
-{
-    VADriverContextP ctx = pDisplayContext->pDriverContext;
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
-    char *driver_name_env;
-    int vendor_id, device_id;
-    int i = 0;
-    
-    struct {
-        int vendor_id;
-        int device_id;
-        char driver_name[64];
-    } devices[] = {
-        { 0x8086, 0x4100, "pvr" },
-        { 0x8086, 0x0130, "pvr" },
-        { 0x1010, 0x1cf2, "pvr" },
-        { 0x0,    0x0,    "\0" },
-    };
-
-    memset(dri_state, 0, sizeof(*dri_state));
-    dri_state->fd = drm_open_any(&vendor_id, &device_id);
-    
-    if (dri_state->fd < 0) {
-        fprintf(stderr,"can't open DRM devices\n");
+    if (driver_name == NULL)
         return VA_STATUS_ERROR_UNKNOWN;
+
+    if (strncmp((char *)ctx->native_dpy, "libva_driver_name=", 18) == 0) {
+            *driver_name = strdup((char *)ctx->native_dpy + 18);
+        if (*driver_name == NULL)
+            return VA_STATUS_ERROR_ALLOCATION_FAILED;
+        else
+            return VA_STATUS_SUCCESS;
+    } else {
+        return VA_DRM_GetDriverName(ctx, driver_name);
     }
-    
-    /* TBD: other vendor driver names */
-
-    while (devices[i].device_id != 0) {
-        if ((devices[i].vendor_id == vendor_id) &&
-            (devices[i].device_id == device_id))
-            break;
-        i++;
-    }
-
-    if (devices[i].device_id != 0)
-        *driver_name = strdup(devices[i].driver_name);
-    else {
-        fprintf(stderr,"device (0x%04x:0x%04x) is not supported\n",
-                vendor_id, device_id);
-        
-        return VA_STATUS_ERROR_UNKNOWN;
-    }            
-
-    printf("DRM device is opened, loading driver %s for device 0x%04x:0x%04x\n",
-           driver_name, vendor_id, device_id);
-    
-    dri_state->driConnectedFlag = VA_DUMMY;
-
-    return VA_STATUS_SUCCESS;
 }
-#endif
+
 
 VADisplay vaGetDisplay (
     void *native_dpy /* implementation specific */
@@ -213,21 +144,22 @@
     if (!dpy)
     {
         /* create new entry */
-        VADriverContextP pDriverContext;
-        struct dri_state *dri_state;
+        VADriverContextP pDriverContext = 0;
+        struct drm_state *drm_state = 0;
         pDisplayContext = (VADisplayContextP)calloc(1, sizeof(*pDisplayContext));
         pDriverContext  = (VADriverContextP)calloc(1, sizeof(*pDriverContext));
-        dri_state       = (struct dri_state*)calloc(1, sizeof(*dri_state));
-        if (pDisplayContext && pDriverContext && dri_state)
+        drm_state       = (struct drm_state*)calloc(1, sizeof(*drm_state));
+        if (pDisplayContext && pDriverContext && drm_state)
         {
             pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC;          
 
             pDriverContext->native_dpy       = (void *)native_dpy;
+            pDriverContext->display_type     = VA_DISPLAY_ANDROID;
             pDisplayContext->pDriverContext  = pDriverContext;
             pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
             pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
             pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
-            pDriverContext->dri_state 	     = dri_state;
+            pDriverContext->drm_state 	     = drm_state;
             dpy                              = (VADisplay)pDisplayContext;
         }
         else
@@ -236,8 +168,8 @@
                 free(pDisplayContext);
             if (pDriverContext)
                 free(pDriverContext);
-            if (dri_state)
-                free(dri_state);
+            if (drm_state)
+                free(drm_state);
         }
     }
   
@@ -248,7 +180,6 @@
 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
 
 
-#ifdef ANDROID
 extern "C"  {
     extern int fool_postp; /* do nothing for vaPutSurface if set */
     extern int trace_flag; /* trace vaPutSurface parameters */
@@ -274,7 +205,7 @@
 VAStatus vaPutSurface (
     VADisplay dpy,
     VASurfaceID surface,
-    sp<ISurface> draw, /* Android Surface/Window */
+    sp<ANativeWindow> draw, /* Android Native Window */
     short srcx,
     short srcy,
     unsigned short srcw,
@@ -292,10 +223,10 @@
 
     if (fool_postp)
         return VA_STATUS_SUCCESS;
-/*
+
     if (draw == NULL)
         return VA_STATUS_ERROR_UNKNOWN;
-*/
+
     CHECK_DISPLAY(dpy);
     ctx = CTX(dpy);
 
@@ -307,24 +238,4 @@
                                      destx, desty, destw, desth,
                                      cliprects, number_cliprects, flags );
 }
-#else
-VAStatus vaPutSurface (
-    VADisplay dpy,
-    VASurfaceID surface,
-    void  *draw,
-    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 */
-)
-{
-    return VA_STATUS_SUCCESS;
-}
-#endif
+
diff --git a/va/android/va_dummy.c b/va/android/va_dummy.c
deleted file mode 120000
index b47bd16..0000000
--- a/va/android/va_dummy.c
+++ /dev/null
@@ -1 +0,0 @@
-va_android.cpp
\ No newline at end of file
diff --git a/va/android/Makefile.am b/va/drm/Makefile.am
similarity index 60%
copy from va/android/Makefile.am
copy to va/drm/Makefile.am
index 8e532ac..b860ff5 100644
--- a/va/android/Makefile.am
+++ b/va/drm/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 Intel Corporation. All Rights Reserved.
+# Copyright (C) 2012 Intel Corporation. All Rights Reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the
@@ -20,13 +20,39 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-AM_CFLAGS = -DLINUX -I$(top_srcdir)/va -I$(top_srcdir)/va/x11 $(DRM_CFLAGS)
+INCLUDES = \
+	-DLINUX			\
+	-I$(top_srcdir)		\
+	-I$(top_srcdir)/va	\
+	$(DRM_CFLAGS)		\
+	$(NULL)
 
-noinst_LTLIBRARIES = libva_dummy.la	
+source_c = \
+	va_drm.c		\
+	va_drm_auth.c		\
+	va_drm_utils.c		\
+	$(NULL)
 
-libva_dummy_la_LIBADD = $(LIBVA_LIBS) -ldl -ludev
+source_h = \
+	va_drm.h		\
+	$(NULL)
 
-libva_dummyincludedir = ${includedir}/va
+source_h_priv = \
+	va_drm_auth.h		\
+	va_drm_auth_x11.h	\
+	va_drm_utils.h		\
+	$(NULL)
 
-libva_dummy_la_SOURCES = va_dummy.c drmtest.c
+if USE_X11
+source_c			+= va_drm_auth_x11.c
+INCLUDES			+= $(X11_CFLAGS)
+endif
 
+noinst_LTLIBRARIES		= libva_drm.la
+libva_drmincludedir		= ${includedir}/va
+libva_drminclude_HEADERS	= $(source_h)
+libva_drm_la_SOURCES		= $(source_c)
+noinst_HEADERS			= $(source_h_priv)
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/va/drm/va_drm.c b/va/drm/va_drm.c
new file mode 100644
index 0000000..25bf8bb
--- /dev/null
+++ b/va/drm/va_drm.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "sysdeps.h"
+#include <xf86drm.h>
+#include "va_drm.h"
+#include "va_backend.h"
+#include "va_drmcommon.h"
+#include "va_drm_auth.h"
+#include "va_drm_utils.h"
+
+static int
+va_DisplayContextIsValid(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP const pDriverContext = pDisplayContext->pDriverContext;
+
+    return (pDriverContext &&
+            pDriverContext->display_type == VA_DISPLAY_DRM);
+}
+
+static void
+va_DisplayContextDestroy(VADisplayContextP pDisplayContext)
+{
+    if (!pDisplayContext)
+        return;
+
+    free(pDisplayContext->pDriverContext->drm_state);
+    free(pDisplayContext->pDriverContext);
+    free(pDisplayContext);
+}
+
+static VAStatus
+va_DisplayContextGetDriverName(
+    VADisplayContextP pDisplayContext,
+    char            **driver_name_ptr
+)
+{
+
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    struct drm_state * const drm_state = ctx->drm_state;
+    drm_magic_t magic;
+    VAStatus status;
+    int ret;
+
+    status = VA_DRM_GetDriverName(ctx, driver_name_ptr);
+    if (status != VA_STATUS_SUCCESS)
+        return status;
+
+    ret = drmGetMagic(drm_state->fd, &magic);
+    if (ret < 0)
+        return VA_STATUS_ERROR_OPERATION_FAILED;
+
+    if (!va_drm_is_authenticated(drm_state->fd)) {
+        if (!va_drm_authenticate(drm_state->fd, magic))
+            return VA_STATUS_ERROR_OPERATION_FAILED;
+        if (!va_drm_is_authenticated(drm_state->fd))
+            return VA_STATUS_ERROR_OPERATION_FAILED;
+    }
+
+    drm_state->auth_type = VA_DRM_AUTH_CUSTOM;
+
+    return VA_STATUS_SUCCESS;
+}
+
+VADisplay
+vaGetDisplayDRM(int fd)
+{
+    VADisplayContextP pDisplayContext = NULL;
+    VADriverContextP  pDriverContext  = NULL;
+    struct drm_state *drm_state       = NULL;
+
+    if (fd < 0)
+        return NULL;
+
+    /* Create new entry */
+    /* XXX: handle cache? */
+    drm_state = calloc(1, sizeof(*drm_state));
+    if (!drm_state)
+        goto error;
+    drm_state->fd = fd;
+
+    pDriverContext = calloc(1, sizeof(*pDriverContext));
+    if (!pDriverContext)
+        goto error;
+    pDriverContext->native_dpy   = NULL;
+    pDriverContext->display_type = VA_DISPLAY_DRM;
+    pDriverContext->drm_state    = drm_state;
+
+    pDisplayContext = calloc(1, sizeof(*pDisplayContext));
+    if (!pDisplayContext)
+        goto error;
+
+    pDisplayContext->vadpy_magic     = VA_DISPLAY_MAGIC;
+    pDisplayContext->pDriverContext  = pDriverContext;
+    pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
+    pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
+    pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
+    return pDisplayContext;
+
+error:
+    free(pDisplayContext);
+    free(pDriverContext);
+    free(drm_state);
+    return NULL;
+}
diff --git a/va/drm/va_drm.h b/va/drm/va_drm.h
new file mode 100644
index 0000000..9af3cc8
--- /dev/null
+++ b/va/drm/va_drm.h
@@ -0,0 +1,61 @@
+/*
+ * va_drm.h - Raw DRM API
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_DRM_H
+#define VA_DRM_H
+
+#include <va/va.h>
+
+/**
+ * \file va_drm.h
+ * \brief The raw DRM API
+ *
+ * This file contains the \ref api_drm "Raw DRM API".
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Returns a VA display derived from the specified DRM connection.
+ *
+ * This function returns a (possibly cached) VA display from the
+ * specified DRM connection @fd.
+ *
+ * @param[in]   fd      the DRM connection descriptor
+ * @return the VA display
+ */
+VADisplay
+vaGetDisplayDRM(int fd);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_DRM_H */
diff --git a/va/drm/va_drm_auth.c b/va/drm/va_drm_auth.c
new file mode 100644
index 0000000..53794d3
--- /dev/null
+++ b/va/drm/va_drm_auth.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "sysdeps.h"
+#include <unistd.h>
+#include <xf86drm.h>
+#include "va_drm_auth.h"
+#include "va_drm_auth_x11.h"
+
+#if defined __linux__
+# include <sys/syscall.h>
+#endif
+
+/* Checks whether the thread id is the current thread */
+static bool
+is_local_tid(pid_t tid)
+{
+#if defined __linux__
+    /* On Linux systems, drmGetClient() would return the thread ID
+       instead of the actual process ID */
+    return syscall(SYS_gettid) == tid;
+#else
+    return false;
+#endif
+}
+
+/* Checks whether DRM connection is authenticated */
+bool
+va_drm_is_authenticated(int fd)
+{
+    pid_t client_pid;
+    int i, auth, pid, uid;
+    unsigned long magic, iocs;
+    bool is_authenticated = false;
+
+    client_pid = getpid();
+    for (i = 0; !is_authenticated; i++) {
+        if (drmGetClient(fd, i, &auth, &pid, &uid, &magic, &iocs) != 0)
+            break;
+        is_authenticated = auth && (pid == client_pid || is_local_tid(pid));
+    }
+    return is_authenticated;
+}
+
+/* Try to authenticate the DRM connection with the supplied magic id */
+bool
+va_drm_authenticate(int fd, uint32_t magic)
+{
+    /* XXX: try to authenticate through Wayland, etc. */
+#ifdef HAVE_VA_X11
+    if (va_drm_authenticate_x11(fd, magic))
+        return true;
+#endif
+
+    /* Default: root + master privs are needed for the following call */
+    return drmAuthMagic(fd, magic) == 0;
+}
diff --git a/va/drm/va_drm_auth.h b/va/drm/va_drm_auth.h
new file mode 100644
index 0000000..1aa6989
--- /dev/null
+++ b/va/drm/va_drm_auth.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_DRM_AUTH_H
+#define VA_DRM_AUTH_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+DLL_HIDDEN
+bool
+va_drm_is_authenticated(int fd);
+
+DLL_HIDDEN
+bool
+va_drm_authenticate(int fd, uint32_t magic);
+
+#endif /* VA_DRM_AUTH_H */
diff --git a/va/drm/va_drm_auth_x11.c b/va/drm/va_drm_auth_x11.c
new file mode 100644
index 0000000..54e7402
--- /dev/null
+++ b/va/drm/va_drm_auth_x11.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define _GNU_SOURCE 1
+#include "sysdeps.h"
+#include <dlfcn.h>
+#include <X11/Xlib.h>
+#include "va_drm_auth_x11.h"
+
+#define LIBVA_MAJOR_VERSION 1
+
+typedef struct drm_auth_x11             DRMAuthX11;
+typedef struct drm_auth_x11_vtable      DRMAuthX11VTable;
+
+typedef void (*VAGenericFunc)(void);
+typedef Display *(*X11OpenDisplayFunc)(const char *display_name);
+typedef int (*X11CloseDisplayFunc)(Display *display);
+typedef Bool (*VADRI2QueryExtensionFunc)(
+    Display *display, int *event_base, int *error_base);
+typedef Bool (*VADRI2QueryVersionFunc)(
+    Display *display, int *major, int *minor);
+typedef Bool (*VADRI2AuthenticateFunc)(
+    Display *display, XID window, uint32_t magic);
+
+struct drm_auth_x11_vtable {
+    X11OpenDisplayFunc          x11_open_display;
+    X11CloseDisplayFunc         x11_close_display;
+    VADRI2QueryExtensionFunc    va_dri2_query_extension;
+    VADRI2QueryVersionFunc      va_dri2_query_version;
+    VADRI2AuthenticateFunc      va_dri2_authenticate;
+};
+
+struct drm_auth_x11 {
+    void                       *handle; /* libva-x11.so.1 */
+    DRMAuthX11VTable            vtable;
+    Display                    *display;
+    Window                      window;
+};
+
+static bool
+get_symbol(void *handle, void *func_vptr, const char *name)
+{
+    VAGenericFunc func, *func_ptr = func_vptr;
+    const char *error;
+
+    dlerror();
+    func = (VAGenericFunc)dlsym(handle, name);
+    error = dlerror();
+
+    if (error) {
+        fprintf(stderr, "error: failed to resolve %s() function: %s\n",
+                name, error);
+        return false;
+    }
+
+    *func_ptr = func;
+    return true;
+}
+
+static bool
+drm_auth_x11_init(DRMAuthX11 *auth)
+{
+    struct drm_auth_x11_vtable *vtable;
+    char libva_x11_name[16];
+    int ret;
+
+    ret = snprintf(
+        libva_x11_name, sizeof(libva_x11_name),
+        "libva-x11.so.%d", LIBVA_MAJOR_VERSION
+    );
+    if (ret < 0 || ret >= sizeof(libva_x11_name))
+        return false;
+
+    auth->handle = dlopen(libva_x11_name, RTLD_LAZY | RTLD_GLOBAL);
+    if (!auth->handle) {
+        perror("open lib");
+        return false;
+    }
+
+    vtable = &auth->vtable;
+    if (!get_symbol(RTLD_DEFAULT, &vtable->x11_open_display, "XOpenDisplay"))
+        return false;
+    if (!get_symbol(RTLD_DEFAULT, &vtable->x11_close_display, "XCloseDisplay"))
+        return false;
+    if (!get_symbol(auth->handle, &vtable->va_dri2_query_extension,
+                    "VA_DRI2QueryExtension"))
+        return false;
+    if (!get_symbol(auth->handle, &vtable->va_dri2_query_version,
+                    "VA_DRI2QueryVersion"))
+        return false;
+    if (!get_symbol(auth->handle, &vtable->va_dri2_authenticate,
+                    "VA_DRI2Authenticate"))
+        return false;
+
+    auth->display = vtable->x11_open_display(NULL);
+    if (!auth->display)
+        return false;
+
+    auth->window = DefaultRootWindow(auth->display);
+    return true;
+}
+
+static void
+drm_auth_x11_terminate(DRMAuthX11 *auth)
+{
+    if (!auth)
+        return;
+
+    if (auth->display) {
+        auth->vtable.x11_close_display(auth->display);
+        auth->display = NULL;
+        auth->window  = None;
+    }
+
+    if (auth->handle) {
+        dlclose(auth->handle);
+        auth->handle = NULL;
+    }
+}
+
+static bool
+drm_auth_x11_authenticate(DRMAuthX11 *auth, int fd, uint32_t magic)
+{
+    DRMAuthX11VTable * const vtable = &auth->vtable;
+    int evt_base, err_base, v_major, v_minor;
+
+    if (!vtable->va_dri2_query_extension(auth->display, &evt_base, &err_base))
+        return false;
+    if (!vtable->va_dri2_query_version(auth->display, &v_major, &v_minor))
+        return false;
+    if (!vtable->va_dri2_authenticate(auth->display, auth->window, magic))
+        return false;
+    return true;
+}
+
+/* Try to authenticate the DRM connection with the supplied magic through X11 */
+bool
+va_drm_authenticate_x11(int fd, uint32_t magic)
+{
+    DRMAuthX11 auth;
+    bool success = false;
+
+    memset(&auth, 0, sizeof(auth));
+    if (!drm_auth_x11_init(&auth))
+        goto end;
+    success = drm_auth_x11_authenticate(&auth, fd, magic);
+
+end:
+    drm_auth_x11_terminate(&auth);
+    return success;
+}
diff --git a/va/drm/va_drm_auth_x11.h b/va/drm/va_drm_auth_x11.h
new file mode 100644
index 0000000..530eeed
--- /dev/null
+++ b/va/drm/va_drm_auth_x11.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_DRM_AUTH_X11_H
+#define VA_DRM_AUTH_X11_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+DLL_HIDDEN
+bool
+va_drm_authenticate_x11(int fd, uint32_t magic);
+
+#endif /* VA_DRM_AUTH_X11_H */
diff --git a/va/drm/va_drm_utils.c b/va/drm/va_drm_utils.c
new file mode 100644
index 0000000..f3ffd6b
--- /dev/null
+++ b/va/drm/va_drm_utils.c
@@ -0,0 +1,79 @@
+/*
+ * va_drm_utils.c - VA/DRM Utilities
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "sysdeps.h"
+#include <xf86drm.h>
+#include "va_drm_utils.h"
+#include "va_drmcommon.h"
+
+struct driver_name_map {
+    const char *key;
+    int         key_len;
+    const char *name;
+};
+
+static const struct driver_name_map g_driver_name_map[] = {
+    { "i915",       4, "i965"   }, // Intel OTC GenX driver
+    { "pvrsrvkm",   8, "pvr"    }, // Intel UMG PVR driver
+    { "emgd",       4, "emgd"   }, // Intel ECG PVR driver
+    { NULL, }
+};
+
+/* Returns the VA driver name for the active display */
+VAStatus
+VA_DRM_GetDriverName(VADriverContextP ctx, char **driver_name_ptr)
+{
+    struct drm_state * const drm_state = ctx->drm_state;
+    drmVersionPtr drm_version;
+    char *driver_name = NULL;
+    const struct driver_name_map *m;
+
+    *driver_name_ptr = NULL;
+
+    if (!drm_state || drm_state->fd < 0)
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+
+    drm_version = drmGetVersion(drm_state->fd);
+    if (!drm_version)
+        return VA_STATUS_ERROR_UNKNOWN;
+
+    for (m = g_driver_name_map; m->key != NULL; m++) {
+        if (drm_version->name_len >= m->key_len &&
+            strncmp(drm_version->name, m->key, m->key_len) == 0)
+            break;
+    }
+    drmFreeVersion(drm_version);
+
+    if (!m->name)
+        return VA_STATUS_ERROR_UNKNOWN;
+
+    driver_name = strdup(m->name);
+    if (!driver_name)
+        return VA_STATUS_ERROR_ALLOCATION_FAILED;
+
+    *driver_name_ptr = driver_name;
+    return VA_STATUS_SUCCESS;
+}
diff --git a/va/drm/va_drm_utils.h b/va/drm/va_drm_utils.h
new file mode 100644
index 0000000..0cb361e
--- /dev/null
+++ b/va/drm/va_drm_utils.h
@@ -0,0 +1,73 @@
+/*
+ * va_drm_utils.h - VA/DRM Utilities
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_DRM_UTILS_H
+#define VA_DRM_UTILS_H
+
+#include <va/va_backend.h>
+
+/**
+ * \file va_drm_utils.h
+ * \brief VA/DRM Utilities
+ *
+ * This file contains VA/DRM utility functions. The API herein defined is
+ * internal to libva. Users include the VA/DRM API itself or VA/Android,
+ * should it be based on DRM.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Returns the VA driver name for the active display.
+ *
+ * This functions returns a newly allocated buffer in @driver_name_ptr that
+ * contains the VA driver name for the active display. Active display means
+ * the display obtained with any of the vaGetDisplay*() functions.
+ *
+ * The VADriverContext.drm_state structure must be valid, i.e. allocated
+ * and containing an open DRM connection descriptor. The DRM connection
+ * does *not* need to be authenticated as it only performs a call to
+ * drmGetVersion().
+ *
+ * @param[in]   ctx     the pointer to a VADriverContext
+ * @param[out]  driver_name_ptr the newly allocated buffer containing
+ *     the VA driver name
+ * @return VA_STATUS_SUCCESS if operation is successful, or another
+ *     #VAStatus value otherwise.
+ */
+DLL_HIDDEN
+VAStatus
+VA_DRM_GetDriverName(VADriverContextP ctx, char **driver_name_ptr);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_DRM_UTILS_H */
diff --git a/va/dummy b/va/dummy
deleted file mode 120000
index 1fd74d1..0000000
--- a/va/dummy
+++ /dev/null
@@ -1 +0,0 @@
-android
\ No newline at end of file
diff --git a/va/egl/Makefile.am b/va/egl/Makefile.am
index c02daa7..7f3f954 100644
--- a/va/egl/Makefile.am
+++ b/va/egl/Makefile.am
@@ -20,7 +20,12 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-INCLUDES = -DLINUX -I$(top_srcdir) -I$(top_srcdir)/va -I$(top_srcdir)/va/x11
+INCLUDES = \
+	-DLINUX			\
+	-I$(top_srcdir)		\
+	-I$(top_srcdir)/va	\
+	$(EGL_CFLAGS)		\
+	$(NULL)
 
 source_c = \
 	va_egl.c		
diff --git a/va/glx/Makefile.am b/va/glx/Makefile.am
index 05cfbce..79d8594 100644
--- a/va/glx/Makefile.am
+++ b/va/glx/Makefile.am
@@ -20,7 +20,14 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-INCLUDES = -DLINUX -I$(top_srcdir) -I$(top_srcdir)/va -I$(top_srcdir)/va/x11
+INCLUDES = \
+	-DLINUX			\
+	-I$(top_srcdir)		\
+	-I$(top_srcdir)/va	\
+	-I$(top_srcdir)/va/x11	\
+	$(X11_CFLAGS)		\
+	$(GLX_CFLAGS)		\
+	$(NULL)
 
 source_c = \
 	va_glx.c		\
diff --git a/va/glx/va_glx.c b/va/glx/va_glx.c
index 1812ef5..e03847e 100644
--- a/va/glx/va_glx.c
+++ b/va/glx/va_glx.c
@@ -98,6 +98,7 @@
     if (!pDriverContextGLX)
         goto error;
 
+    pDriverContext->display_type  = VA_DISPLAY_GLX;
     pDisplayContextGLX->vaDestroy = pDisplayContext->vaDestroy;
     pDisplayContext->vaDestroy    = va_DisplayContextDestroy;
     pDisplayContext->opaque       = pDisplayContextGLX;
diff --git a/va/glx/va_glx_impl.c b/va/glx/va_glx_impl.c
index 049be09..4307001 100644
--- a/va/glx/va_glx_impl.c
+++ b/va/glx/va_glx_impl.c
@@ -151,12 +151,12 @@
     dlerror();
     get_proc_func = (GLXGetProcAddressProc)
         dlsym(RTLD_DEFAULT, "glXGetProcAddress");
-    if (!dlerror())
+    if (!dlerror() && get_proc_func)
         return get_proc_func;
 
     get_proc_func = (GLXGetProcAddressProc)
         dlsym(RTLD_DEFAULT, "glXGetProcAddressARB");
-    if (!dlerror())
+    if (!dlerror() && get_proc_func)
         return get_proc_func;
 
     return get_proc_address_default;
@@ -876,19 +876,25 @@
     gl_get_current_context(&old_cs);
     new_cs = gl_create_context(ctx, &old_cs);
     if (!new_cs)
-        return VA_STATUS_ERROR_ALLOCATION_FAILED;
+        goto error;
     if (!gl_set_current_context(new_cs, NULL))
-        return VA_STATUS_ERROR_OPERATION_FAILED;
+        goto error;
 
     pSurfaceGLX = create_surface(ctx, target, texture);
     if (!pSurfaceGLX)
-        return VA_STATUS_ERROR_ALLOCATION_FAILED;
+        goto error;
 
     pSurfaceGLX->gl_context = new_cs;
     *gl_surface = pSurfaceGLX;
 
     gl_set_current_context(&old_cs, NULL);
     return VA_STATUS_SUCCESS;
+
+error:
+    if (new_cs)
+        gl_destroy_context(new_cs);
+
+    return VA_STATUS_ERROR_ALLOCATION_FAILED;    
 }
 
 static VAStatus
diff --git a/va/sysdeps.h b/va/sysdeps.h
index 0752b17..786a4d0 100644
--- a/va/sysdeps.h
+++ b/va/sysdeps.h
@@ -31,6 +31,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <string.h>
 #include <stdint.h>
 #include <assert.h>
@@ -39,6 +40,40 @@
 # define Bool  int
 # define True  1
 # define False 0
+
+/* Macros generated from configure */
+# define LIBVA_VERSION_S "1.2.0.pre1"
+
+/* Android logging utilities */
+# include <utils/Log.h>
+
+# ifdef ANDROID_ALOG
+#  define va_log_error(buffer)  do { ALOGE("%s", buffer); } while (0)
+#  define va_log_info(buffer)   do { ALOGI("%s", buffer); } while (0)
+# elif ANDROID_LOG
+#  define va_log_error(buffer)  do { LOGE("%s", buffer); } while (0)
+#  define va_log_info(buffer)   do { LOGI("%s", buffer); } while (0)
+# endif
+#endif
+
+#ifndef va_log_error
+#define va_log_error(buffer) do {                       \
+        fprintf(stderr, "libva error: %s", buffer);     \
+    } while (0)
+#endif
+
+#ifndef va_log_info
+#define va_log_info(buffer) do {                        \
+        fprintf(stderr, "libva info: %s", buffer);      \
+    } while (0)
+#endif
+
+#if defined __GNUC__ && defined HAVE_GNUC_VISIBILITY_ATTRIBUTE
+# define DLL_HIDDEN __attribute__((visibility("hidden")))
+# define DLL_EXPORT __attribute__((visibility("default")))
+#else
+# define DLL_HIDDEN
+# define DLL_EXPORT
 #endif
 
 #endif /* SYSDEPS_H */
diff --git a/va/va.c b/va/va.c
index d4f728a..3ea8503 100755
--- a/va/va.c
+++ b/va/va.c
@@ -87,10 +87,10 @@
         fclose(fp);
 
     /* no setting in config file, use env setting */
-    if (getenv(env)) {
+    value = getenv(env);
+    if (value) {
         if (env_value)
-            strncpy(env_value, getenv(env), 1024);
-
+            strncpy(env_value, value, 1024);
         return 0;
     }
     
@@ -105,49 +105,79 @@
 
 void va_errorMessage(const char *msg, ...)
 {
+    char buf[512], *dynbuf;
     va_list args;
+    int n, len;
 
-    fprintf(stderr, "libva error: ");
     va_start(args, msg);
-    vfprintf(stderr, msg, args);
+    len = vsnprintf(buf, sizeof(buf), msg, args);
     va_end(args);
+
+    if (len >= (int)sizeof(buf)) {
+        dynbuf = malloc(len + 1);
+        if (!dynbuf)
+            return;
+        va_start(args, msg);
+        n = vsnprintf(dynbuf, len + 1, msg, args);
+        va_end(args);
+        if (n == len)
+            va_log_error(dynbuf);
+        free(dynbuf);
+    }
+    else if (len > 0)
+        va_log_error(buf);
 }
 
 void va_infoMessage(const char *msg, ...)
 {
+    char buf[512], *dynbuf;
     va_list args;
+    int n, len;
 
-    fprintf(stderr, "libva: ");
     va_start(args, msg);
-    vfprintf(stderr, msg, args);
+    len = vsnprintf(buf, sizeof(buf), msg, args);
     va_end(args);
+
+    if (len >= (int)sizeof(buf)) {
+        dynbuf = malloc(len + 1);
+        if (!dynbuf)
+            return;
+        va_start(args, msg);
+        n = vsnprintf(dynbuf, len + 1, msg, args);
+        va_end(args);
+        if (n == len)
+            va_log_info(dynbuf);
+        free(dynbuf);
+    }
+    else if (len > 0)
+        va_log_info(buf);
 }
 
-static Bool va_checkVtable(void *ptr, char *function)
+static bool va_checkVtable(void *ptr, char *function)
 {
     if (!ptr) {
         va_errorMessage("No valid vtable entry for va%s\n", function);
-        return False;
+        return false;
     }
-    return True;
+    return true;
 }
 
-static Bool va_checkMaximum(int value, char *variable)
+static bool va_checkMaximum(int value, char *variable)
 {
     if (!value) {
         va_errorMessage("Failed to define max_%s in init\n", variable);
-        return False;
+        return false;
     }
-    return True;
+    return true;
 }
 
-static Bool va_checkString(const char* value, char *variable)
+static bool va_checkString(const char* value, char *variable)
 {
     if (!value) {
         va_errorMessage("Failed to define str_%s in init\n", variable);
-        return False;
+        return false;
     }
-    return True;
+    return true;
 }
 
 static inline int
@@ -185,6 +215,13 @@
         char *driver_path = (char *) malloc( strlen(driver_dir) +
                                              strlen(driver_name) +
                                              strlen(DRIVER_EXTENSION) + 2 );
+        if (!driver_path) {
+            va_errorMessage("%s L%d Out of memory!n",
+                                __FUNCTION__, __LINE__);
+            free(search_path);    
+            return VA_STATUS_ERROR_ALLOCATION_FAILED;
+        }
+
         strncpy( driver_path, driver_dir, strlen(driver_dir) + 1);
         strncat( driver_path, "/", strlen("/") );
         strncat( driver_path, driver_name, strlen(driver_name) );
@@ -212,7 +249,7 @@
                 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
                 { 0, 33 },
                 { 0, 32 },
-                { -1, }
+                { -1, 0}
             };
 
             for (i = 0; compatible_versions[i].major >= 0; i++) {
@@ -252,7 +289,7 @@
                 }
                 ctx->vtable_vpp = vtable_vpp;
 
-                if (init_func && (VA_STATUS_SUCCESS == vaStatus))
+                if (init_func && VA_STATUS_SUCCESS == vaStatus)
                     vaStatus = (*init_func)(ctx);
 
                 if (VA_STATUS_SUCCESS == vaStatus) {
@@ -270,7 +307,7 @@
                     CHECK_VTABLE(vaStatus, ctx, CreateConfig);
                     CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
                     CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
-                    //CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
+                    CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
                     CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
                     CHECK_VTABLE(vaStatus, ctx, CreateContext);
                     CHECK_VTABLE(vaStatus, ctx, DestroyContext);
@@ -420,24 +457,30 @@
 
     va_infoMessage("VA-API version %s\n", VA_VERSION_S);
 
+    vaStatus = va_getDriverName(dpy, &driver_name);
+    va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
+
     driver_name_env = getenv("LIBVA_DRIVER_NAME");
-    if (driver_name_env && geteuid() == getuid()) {
+    if ((VA_STATUS_SUCCESS == vaStatus) &&
+        driver_name_env && (geteuid() == getuid())) {
         /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
+        if (driver_name) /* memory is allocated in va_getDriverName */
+            free(driver_name);
+        
         driver_name = strdup(driver_name_env);
         vaStatus = VA_STATUS_SUCCESS;
         va_infoMessage("User requested driver '%s'\n", driver_name);
-    } else {
-        vaStatus = va_getDriverName(dpy, &driver_name);
-        va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
     }
 
-    if (VA_STATUS_SUCCESS == vaStatus) {
+    if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) {
         vaStatus = va_openDriver(dpy, driver_name);
         va_infoMessage("va_openDriver() returns %d\n", vaStatus);
 
         *major_version = VA_MAJOR_VERSION;
         *minor_version = VA_MINOR_VERSION;
-    }
+    } else
+        va_errorMessage("va_getDriverName() failed with %s,driver_name=%s\n",
+                        vaErrorStr(vaStatus), driver_name);
 
     if (driver_name)
         free(driver_name);
@@ -472,15 +515,15 @@
   free(old_ctx->vtable_vpp);
   old_ctx->vtable_vpp = NULL;
 
-  if (VA_STATUS_SUCCESS == vaStatus)
-      pDisplayContext->vaDestroy(pDisplayContext);
-
   VA_TRACE_LOG(va_TraceTerminate, dpy);
 
   va_TraceEnd(dpy);
 
   va_FoolEnd(dpy);
 
+  if (VA_STATUS_SUCCESS == vaStatus)
+      pDisplayContext->vaDestroy(pDisplayContext);
+
   return vaStatus;
 }
 
@@ -590,7 +633,6 @@
 {
   VADriverContextP ctx;
   VAStatus vaStatus = VA_STATUS_SUCCESS;
-  int ret = 0;
   
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
@@ -598,7 +640,7 @@
   vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
 
   /* record the current entrypoint for further trace/fool determination */
-  VA_TRACE_FUNC(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
+  VA_TRACE_ALL(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
   VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
   
   return vaStatus;
@@ -632,12 +674,148 @@
   return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
 }
 
+/* XXX: this is a slow implementation that will be removed */
+static VAStatus
+va_impl_query_surface_attributes(
+    VADriverContextP    ctx,
+    VAConfigID          config,
+    VASurfaceAttrib    *out_attribs,
+    unsigned int       *out_num_attribs_ptr
+)
+{
+    VASurfaceAttrib *attribs = NULL;
+    unsigned int num_attribs, n;
+    VASurfaceAttrib *out_attrib;
+    unsigned int out_num_attribs;
+    VAImageFormat *image_formats = NULL;
+    int num_image_formats, i;
+    VAStatus va_status;
+
+    /* List of surface attributes to query */
+    struct va_surface_attrib_map {
+        VASurfaceAttribType type;
+        VAGenericValueType  value_type;
+    };
+    static const struct va_surface_attrib_map attribs_map[] = {
+        { VASurfaceAttribMinWidth,      VAGenericValueTypeInteger },
+        { VASurfaceAttribMaxWidth,      VAGenericValueTypeInteger },
+        { VASurfaceAttribMinHeight,     VAGenericValueTypeInteger },
+        { VASurfaceAttribMaxHeight,     VAGenericValueTypeInteger },
+        { VASurfaceAttribMemoryType,    VAGenericValueTypeInteger },
+        { VASurfaceAttribNone, }
+    };
+
+    if (!out_attribs || !out_num_attribs_ptr)
+        return VA_STATUS_ERROR_INVALID_PARAMETER;
+    if (!ctx->vtable->vaGetSurfaceAttributes)
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+
+    num_image_formats = ctx->max_image_formats;
+    image_formats = malloc(num_image_formats * sizeof(*image_formats));
+    if (!image_formats) {
+        va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
+        goto end;
+    }
+
+    va_status = ctx->vtable->vaQueryImageFormats(
+        ctx, image_formats, &num_image_formats);
+    if (va_status != VA_STATUS_SUCCESS)
+        goto end;
+
+    num_attribs = VASurfaceAttribCount + num_image_formats;
+    attribs = malloc(num_attribs * sizeof(*attribs));
+    if (!attribs) {
+        va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
+        goto end;
+    }
+
+    /* Initialize with base surface attributes, except pixel-formats */
+    for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
+        VASurfaceAttrib * const attrib = &attribs[n];
+        attrib->type = attribs_map[n].type;
+        attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
+        attrib->value.type = attribs_map[n].value_type;
+    }
+
+    /* Append image formats */
+    for (i = 0; i < num_image_formats; i++) {
+        VASurfaceAttrib * const attrib = &attribs[n];
+        attrib->type = VASurfaceAttribPixelFormat;
+        attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
+        attrib->value.type = VAGenericValueTypeInteger;
+        attrib->value.value.i = image_formats[i].fourcc;
+        if (++n == num_attribs) {
+            va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
+            goto end;
+        }
+    }
+    num_attribs = n;
+
+    va_status = ctx->vtable->vaGetSurfaceAttributes(
+        ctx, config, attribs, num_attribs);
+    if (va_status != VA_STATUS_SUCCESS)
+        goto end;
+
+    /* Remove invalid entries */
+    out_num_attribs = 0;
+    for (n = 0; n < num_attribs; n++) {
+        VASurfaceAttrib * const attrib = &attribs[n];
+
+        if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
+            continue;
+
+        // Accept all surface attributes that are not pixel-formats
+        if (attrib->type != VASurfaceAttribPixelFormat) {
+            out_num_attribs++;
+            continue;
+        }
+
+        // Drop invalid pixel-format attribute
+        if (!attrib->value.value.i) {
+            attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
+            continue;
+        }
+
+        // Check for duplicates
+        int is_duplicate = 0;
+        for (i = n - 1; i >= 0 && !is_duplicate; i--) {
+            const VASurfaceAttrib * const prev_attrib = &attribs[i];
+            if (prev_attrib->type != VASurfaceAttribPixelFormat)
+                break;
+            is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
+        }
+        if (is_duplicate)
+            attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
+        else
+            out_num_attribs++;
+    }
+
+    if (*out_num_attribs_ptr < out_num_attribs) {
+        *out_num_attribs_ptr = out_num_attribs;
+        va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
+        goto end;
+    }
+
+    out_attrib = out_attribs;
+    for (n = 0; n < num_attribs; n++) {
+        const VASurfaceAttrib * const attrib = &attribs[n];
+        if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
+            continue;
+        *out_attrib++ = *attrib;
+    }
+
+end:
+    free(attribs);
+    free(image_formats);
+    return va_status;
+}
+
 VAStatus
-vaGetSurfaceAttributes(
+vaQuerySurfaceAttributes(
     VADisplay           dpy,
     VAConfigID          config,
     VASurfaceAttrib    *attrib_list,
-    unsigned int        num_attribs
+    unsigned int       *num_attribs
 )
 {
     VADriverContextP ctx;
@@ -648,11 +826,15 @@
     if (!ctx)
         return VA_STATUS_ERROR_INVALID_DISPLAY;
 
-    if (!ctx->vtable->vaGetSurfaceAttributes)
-        return VA_STATUS_ERROR_UNIMPLEMENTED;
+    if (!ctx->vtable->vaQuerySurfaceAttributes)
+        vaStatus = va_impl_query_surface_attributes(ctx, config,
+                                                    attrib_list, num_attribs);
+    else
+        vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
+                                                         attrib_list, num_attribs);
 
-    vaStatus = ctx->vtable->vaGetSurfaceAttributes(ctx, config,
-                                                   attrib_list, num_attribs);
+    VA_TRACE_LOG(va_TraceQuerySurfaceAttributes, dpy, config, attrib_list, num_attribs);
+
     return vaStatus;
 }
 
@@ -677,16 +859,14 @@
         return VA_STATUS_ERROR_INVALID_DISPLAY;
 
     if (ctx->vtable->vaCreateSurfaces2)
-        return ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
+        vaStatus = ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
                                               surfaces, num_surfaces,
                                               attrib_list, num_attribs);
-
-    if (attrib_list && num_attribs > 0)
-        return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
-
-    vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
-                                             num_surfaces, surfaces);
-
+    else if (attrib_list && num_attribs > 0)
+        vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
+    else
+        vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
+                                                 num_surfaces, surfaces);
     VA_TRACE_LOG(va_TraceCreateSurfaces,
                  dpy, width, height, format, num_surfaces, surfaces,
                  attrib_list, num_attribs);
@@ -702,10 +882,17 @@
 )
 {
   VADriverContextP ctx;
+  VAStatus vaStatus;
+  
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
 
-  return ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
+  VA_TRACE_LOG(va_TraceDestroySurfaces,
+               dpy, surface_list, num_surfaces);
+  
+  vaStatus = ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
+  
+  return vaStatus;
 }
 
 VAStatus vaCreateContext (
@@ -729,7 +916,7 @@
                                       flag, render_targets, num_render_targets, context );
 
   /* keep current encode/decode resoluton */
-  VA_TRACE_FUNC(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
+  VA_TRACE_ALL(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
 
   return vaStatus;
 }
@@ -757,15 +944,19 @@
 )
 {
   VADriverContextP ctx;
+  VAStatus vaStatus;
+  
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
-  int ret = 0;
 
   VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
-  if (ret)
-      return VA_STATUS_SUCCESS;
 
-  return ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
+  vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
+
+  VA_TRACE_LOG(va_TraceCreateBuffer,
+               dpy, context, type, size, num_elements, data, buf_id);
+  
+  return vaStatus;
 }
 
 VAStatus vaBufferSetNumElements (
@@ -777,8 +968,8 @@
   VADriverContextP ctx;
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
-  
-  VA_FOOL_RETURN();
+
+  VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
   
   return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
 }
@@ -792,18 +983,15 @@
 {
   VADriverContextP ctx;
   VAStatus va_status;
-  int ret = 0;
   
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
-
+  
   VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
-  if (ret)
-      return VA_STATUS_SUCCESS;
   
   va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
 
-  VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
+  VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf);
   
   return va_status;
 }
@@ -816,11 +1004,8 @@
   VADriverContextP ctx;
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
-  int ret = 0;
 
-  VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
-  if (ret)
-      return VA_STATUS_SUCCESS;
+  VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
 
   return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
 }
@@ -834,31 +1019,31 @@
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
 
-  VA_FOOL_RETURN();
+  VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
+
+  VA_TRACE_LOG(va_TraceDestroyBuffer,
+               dpy, buffer_id);
   
   return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
 }
 
 VAStatus vaBufferInfo (
     VADisplay dpy,
-    VAContextID context,	/* in */
+    VAContextID __maybe_unused context,	/* in */
     VABufferID buf_id,		/* in */
     VABufferType *type,		/* out */
     unsigned int *size,		/* out */
     unsigned int *num_elements	/* out */
 )
 {
-  VADriverContextP ctx;
-  int ret = 0;
-  
-  CHECK_DISPLAY(dpy);
-  ctx = CTX(dpy);
+    VADriverContextP ctx;
 
-  VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
-  if (ret)
-      return VA_STATUS_SUCCESS;
-  
-  return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
+    CHECK_DISPLAY(dpy);
+    ctx = CTX(dpy);
+
+    VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
+
+    return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
 }
 
 VAStatus vaBeginPicture (
@@ -873,8 +1058,8 @@
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
 
-  VA_TRACE_FUNC(va_TraceBeginPicture, dpy, context, render_target);
-  VA_FOOL_RETURN();
+  VA_TRACE_ALL(va_TraceBeginPicture, dpy, context, render_target);
+  VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
   
   va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
   
@@ -894,7 +1079,7 @@
   ctx = CTX(dpy);
 
   VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
-  VA_FOOL_RETURN();
+  VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
 
   return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
 }
@@ -910,11 +1095,12 @@
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
 
-  if (fool_codec == 0)
-      va_status = ctx->vtable->vaEndPicture( ctx, context );
+  VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
+
+  va_status = ctx->vtable->vaEndPicture( ctx, context );
 
   /* dump surface content */
-  VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
+  VA_TRACE_ALL(va_TraceEndPicture, dpy, context, 1);
 
   return va_status;
 }
diff --git a/va/va.h b/va/va.h
index c0616eb..75a4bc0 100755
--- a/va/va.h
+++ b/va/va.h
@@ -24,7 +24,7 @@
 /*
  * Video Acceleration (VA) API Specification
  *
- * Rev. 0.32.2
+ * Rev. 0.30
  * <jonathan.bian@intel.com>
  *
  * Revision History:
@@ -61,9 +61,6 @@
  *                                        screen relative rather than source video relative.
  * rev 0.32.0 (01/13/2011 Xiang Haihao) - Add profile into VAPictureParameterBufferVC1
  *                                        update VAAPI to 0.32.0
- * rev 0.32.1 (05/04/2011)              - Linux VA encoding API extension proposal
- *
- * rev 0.32.2 (07/05/2011 Jonathan Bian/Andrey Yakovenko) - Video Processing interface 
  *
  * Acknowledgements:
  *  Some concepts borrowed from XvMC and XvImage.
@@ -81,12 +78,19 @@
 #ifndef _VA_H_
 #define _VA_H_
 
+#include <stdint.h>
 #include <va/va_version.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#ifdef __GNUC__
+# define __maybe_unused __attribute__((__unused__))
+#else
+# define __maybe_unused
+#endif
+
 /**
  * \mainpage Video Acceleration (VA) API
  *
@@ -182,6 +186,8 @@
 #define VA_STATUS_ERROR_INVALID_FILTER_CHAIN    0x00000021
 /** \brief Indicate HW busy (e.g. run multiple encoding simultaneously). */
 #define VA_STATUS_ERROR_HW_BUSY	                0x00000022
+/** \brief An invalid blend state was supplied. */
+#define VA_STATUS_ERROR_INVALID_BLEND_STATE     0x00000023
 #define VA_STATUS_ERROR_UNKNOWN			0xFFFFFFFF
 
 /* De-interlacing flags for vaPutSurface() */
@@ -205,9 +211,11 @@
 #define VA_CLEAR_DRAWABLE       0x00000008
 
 /* Color space conversion flags for vaPutSurface() */
+#define VA_SRC_COLOR_MASK       0x000000f0
 #define VA_SRC_BT601            0x00000010
 #define VA_SRC_BT709            0x00000020
 #define VA_SRC_SMPTE_240        0x00000040
+#define VA_SRC_BT2020           0x00000080
 
 /* Scaling flags for vaPutSurface() */
 #define VA_FILTER_SCALING_DEFAULT       0x00000000
@@ -217,10 +225,45 @@
 #define VA_FILTER_SCALING_MASK          0x00000f00
 
 /*
+ * The upper 16 bits are reserved for VPP filter fast path usage.
+ * Flag to enable auto noise reduction.
+ */
+#define VA_FILTER_NOISEREDUCTION_AUTO   0x00010000
+
+/*
+ * This is to indicate that the color-space conversion uses full range or reduced range.
+ * VA_SOURCE_RANGE_FULL(Full range): Y/Cb/Cr is in [0, 255]. It is mainly used
+ *      for JPEG/JFIF formats. The combination with the BT601 flag means that
+ *      JPEG/JFIF color-space conversion matrix is used.
+ * VA_SOURCE_RANGE_REDUCED(Reduced range): Y is in [16, 235] and Cb/Cr is in [16, 240].
+ *      It is mainly used for the YUV->RGB color-space conversion in SDTV/HDTV/UHDTV.
+ */
+#define VA_SOURCE_RANGE_MASK            0x00020000
+#define VA_SOURCE_RANGE_FULL            0x00020000
+#define VA_SOURCE_RANGE_REDUCED         0x00000000
+/*
  * Returns a short english description of error_status
  */
 const char *vaErrorStr(VAStatus error_status);
 
+typedef struct _VARectangle
+{
+    short x;
+    short y;
+    unsigned short width;
+    unsigned short height;
+} VARectangle;
+
+/** \brief Generic motion vector data structure. */
+typedef struct _VAMotionVector {
+    /** \mv0[0]: horizontal motion vector for past reference */
+    /** \mv0[1]: vertical motion vector for past reference */
+    /** \mv1[0]: horizontal motion vector for future reference */
+    /** \mv1[1]: vertical motion vector for future reference */
+    unsigned short  mv0[2];  /* past reference */
+    unsigned short  mv1[2];  /* future reference */
+} VAMotionVector;
+
 /*
  * Initialization:
  * A display must be obtained by calling vaGetDisplay() before calling
@@ -228,7 +271,7 @@
  * native window system.
  * For X Windows, native_dpy would be from XOpenDisplay()
  */
-typedef void* NativeDisplay;	/* window system dependent */
+typedef void* VANativeDisplay;	/* window system dependent */
 
 int vaDisplayIsValid(VADisplay dpy);
     
@@ -274,6 +317,8 @@
 /* Currently defined profiles */
 typedef enum
 {
+    /** \brief Profile ID used for video processing. */
+    VAProfileNone                       = -1,
     VAProfileMPEG2Simple		= 0,
     VAProfileMPEG2Main			= 1,
     VAProfileMPEG4Simple		= 2,
@@ -286,13 +331,15 @@
     VAProfileVC1Main			= 9,
     VAProfileVC1Advanced		= 10,
     VAProfileH263Baseline		= 11,
-    VAProfileJPEGBaseline		= 12,
-    VAProfileH264ConstrainedBaseline 	= 13,
-    VAProfileH264MultiviewHigh		= 14,
-    VAProfileH264StereoHigh		= 15,
-    /** \brief Profile ID used for video processing. */
-    VAProfileNone			= 16,
-    VAProfileVP8Version0_3		= 17,
+    VAProfileJPEGBaseline               = 12,
+    VAProfileH264ConstrainedBaseline    = 13,
+    VAProfileVP8Version0_3              = 14,
+    VAProfileH264MultiviewHigh          = 15,
+    VAProfileH264StereoHigh             = 16,
+    VAProfileHEVCMain                   = 17,
+    VAProfileHEVCMain10                 = 18,
+    VAProfileVP9Version0                = 19,
+    VAProfileAVS                        = 20,
     VAProfileMax
 } VAProfile;
 
@@ -308,7 +355,59 @@
     VAEntrypointDeblocking	= 5,
     VAEntrypointEncSlice	= 6,	/* slice level encode */
     VAEntrypointEncPicture 	= 7,	/* pictuer encode, JPEG, etc */
+    /*
+     * For an implementation that supports a low power/high performance variant
+     * for slice level encode, it can choose to expose the 
+     * VAEntrypointEncSliceLP entrypoint. Certain encoding tools may not be 
+     * available with this entrypoint (e.g. interlace, MBAFF) and the 
+     * application can query the encoding configuration attributes to find 
+     * out more details if this entrypoint is supported.
+     */
+    VAEntrypointEncSliceLP 	= 8,
     VAEntrypointVideoProc       = 10,   /**< Video pre/post-processing. */
+
+    /**
+     * \brief Intel specific entrypoints start at 1001
+     */
+    /**
+     * \brief VAEntrypointEncFEIIntel
+     *
+     * The purpose of FEI (Flexible Encoding Infrastructure) is to allow applications to 
+     * have more controls and trade off quality for speed with their own IPs. A pre-processing 
+     * function for getting some statistics and motion vectors is added 
+     * and some extra controls for Encode pipeline are provided. 
+     * The application can optionally call the statistics function
+     * to get motion vectors and statistics before calling encode function. 
+     * The application can also optionally provide input to VME for extra 
+     * encode control and get the output from VME. Application can chose to 
+     * modify the VME output/PAK input during encoding, but the performance 
+     * impact is significant.
+     *
+     * On top of the existing buffers for normal encode, there will be 
+     * one extra input buffer (VAEncMiscParameterIntelFEIFrameControl) and 
+     * three extra output buffers (VAIntelEncFEIMVBufferType, VAIntelEncFEIModeBufferType 
+     * and VAIntelEncFEIDistortionBufferType) for VAEntrypointIntelEncFEI entry function. 
+     * If separate PAK is set, two extra input buffers 
+     * (VAIntelEncFEIMVBufferType, VAIntelEncFEIModeBufferType) are needed for PAK input. 
+     *
+     **/
+    VAEntrypointEncFEIIntel     = 1001,
+    /**
+     * \brief VAEntrypointStatisticsIntel
+     *
+     * Statistics, like variances, distortions, motion vectors can be obtained 
+     * via this entry point. Checking whether Statistics is supported can be 
+     * performed with vaQueryConfigEntrypoints() and the profile argument 
+     * set to #VAProfileNone. If Statistics entry point is supported, 
+     * then the list of returned entry-points will include #VAEntrypointIntelStatistics. 
+     * Supported pixel format, maximum resolution and statistics specific attributes 
+     * can be obtained via normal attribute query. 
+     * One input buffer (VAIntelStatsStatisticsParameterBufferType) and one or two 
+     * output buffers (VAIntelStatsStatisticsBufferType and VAIntelStatsMotionVectorBufferType) 
+     * are needed for this entry point.
+     *
+     **/
+    VAEntrypointStatisticsIntel,
     VAEntrypointMax
 } VAEntrypoint;
 
@@ -322,6 +421,29 @@
     VAConfigAttribEncryption		= 4,
     VAConfigAttribRateControl		= 5,
 
+    /** @name Attributes for decoding */
+    /**@{*/
+    /**
+     * \brief Slice Decoding mode. Read/write.
+     *
+     * This attribute determines what mode the driver supports for slice
+     * decoding, through vaGetConfigAttributes(); and what mode the user
+     * will be providing to the driver, through vaCreateConfig(), if the
+     * driver supports those. If this attribute is not set by the user then
+     * it is assumed that VA_DEC_SLICE_MODE_NORMAL mode is used. 
+     *
+     * See \c VA_DEC_SLICE_MODE_xxx for the list of slice decoding modes.
+     */
+    VAConfigAttribDecSliceMode		= 6,
+   /**
+     * \brief JPEG decoding attribute. Read-only.
+     *
+     * This attribute exposes a number of capabilities of the underlying
+     * JPEG implementation. The attribute value is partitioned into fields as defined in the 
+     * VAConfigAttribValDecJPEG union.
+     */
+    VAConfigAttribDecJPEG             = 7,
+
     /** @name Attributes for encoding */
     /**@{*/
     /**
@@ -391,8 +513,118 @@
      * through VAEncSliceParameterBufferH264::macroblock_info.
      */
     VAConfigAttribEncMacroblockInfo     = 16,
+    /**
+     * \brief Auto reference frame management. Read-only
+     *
+     * This attribute determines whether the driver supports auto reference management
+     *
+     * If driver supports, application only needs to set scratch reference surfaces
+     * via VAPictureParameterBufferH264:ReferenceFrames. The scratch surfaces number is
+     * determined by the maximum number of RefPicList0 and RefPicList0 which can be queried from
+     * VAConfigAttribEncMaxRefFrames. Application doesn't need to set VAPictureParameterBufferH264:CurrPic
+     * and VAEncSliceParameterBufferH264:RefPicList. Driver will manage the reference frames internally
+     * and choose the best reference frames. Which scratch surface is used for reconstructed frame and which
+     * surfaces are used for reference frames will be fedback via VACodedBufferSegment
+     */
+    VAConfigAttribEncAutoReference     = 17,
+    /**
+     * \brief Maximum picture width. Read-only.
+     *
+     * This attribute determines the maximum picture width the driver supports
+     * for a given configuration.
+     */
+    VAConfigAttribMaxPictureWidth     = 18,
+    /**
+     * \brief Maximum picture height. Read-only.
+     *
+     * This attribute determines the maximum picture height the driver supports
+     * for a given configuration.
+     */
+    VAConfigAttribMaxPictureHeight    = 19,
+    /**
+     * \brief JPEG encoding attribute. Read-only.
+     *
+     * This attribute exposes a number of capabilities of the underlying
+     * JPEG implementation. The attribute value is partitioned into fields as defined in the 
+     * VAConfigAttribValEncJPEG union.
+     */
+    VAConfigAttribEncJPEG             = 20,
+    /**
+     * \brief Encoding quality range attribute. Read-only.
+     *
+     * This attribute conveys whether the driver supports different quality level settings
+     * for encoding. A value less than or equal to 1 means that the encoder only has a single
+     * quality setting, and a value greater than 1 represents the number of quality levels 
+     * that can be configured. e.g. a value of 2 means there are two distinct quality levels. 
+     */
+    VAConfigAttribEncQualityRange     = 21,
+    /**
+     * \brief Encoding quantization attribute. Read-only.
+     *
+     * This attribute conveys whether the driver supports certain types of quantization methods
+     * for encoding (e.g. trellis).
+     */
+    VAConfigAttribEncQuantization     = 22,
+    /**
+     * \brief Encoding intra refresh attribute. Read-only.
+     *
+     * This attribute conveys whether the driver supports certain types of intra refresh methods
+     * for encoding (e.g. adaptive intra refresh or rolling intra refresh). 
+     */
+    VAConfigAttribEncIntraRefresh     = 23,
+    /**
+     * \brief Encoding skip frame attribute. Read-only.
+     *
+     * This attribute conveys whether the driver supports sending skip frame parameters 
+     * (VAEncMiscParameterTypeSkipFrame) to the encoder's rate control, when the user has 
+     * externally skipped frames.  It is a boolean value 0 - unsupported, 1 - supported.
+     */
+    VAConfigAttribEncSkipFrame        = 24,
+    /**
+     * \brief Encoding region-of-interest (ROI) attribute. Read-only.
+     *
+     * This attribute conveys whether the driver supports region-of-interest (ROI) encoding,
+     * based on user provided ROI rectangles.  The attribute value returned indicates the number
+     * of regions that are supported.  e.g. A value of 0 means ROI encoding is not supported.
+     * If ROI encoding is supported, the ROI information is passed to the driver using
+     * VAEncMiscParameterTypeRoi.
+     */
+    VAConfigAttribEncRoi              = 25,
+    /**
+     * \brief Encoding extended rate control attribute. Read-only.
+     *
+     * This attribute conveys whether the driver supports any extended rate control features
+     * The attribute value is partitioned into fields as defined in the 
+     * VAConfigAttribValEncRateControlExt union.
+     */
+    VAConfigAttribEncRateControlExt   = 26,
+    /**
+     * \brief Intel specific attributes start at 1001 
+     */
+    /**
+     * \brief Encode function type.
+     *
+     * This attribute conveys whether the driver supports different function types for encode. 
+     * It can be ENC, PAK, or ENC + PAK. Currently it is for FEI entry point only. 
+     * Default is ENC + PAK.
+     */
+    VAConfigAttribEncFunctionTypeIntel = 1001,
+    /**
+     * \brief Maximum number of MV predictors. Read-only.
+     *
+     * This attribute determines the maximum number of MV predictors the driver 
+     * can support to encode a single frame. 0 means no MV predictor is supported.
+     */
+    VAConfigAttribEncMVPredictorsIntel,
+    /**
+     * \brief Statistics attribute. Read-only.
+     *
+     * This attribute exposes a number of capabilities of the VAEntrypointStatistics entry 
+     * point. The attribute value is partitioned into fields as defined in the 
+     * VAConfigAttribValStatistics union.
+     */
+    VAConfigAttribStatisticsIntel,
     /**@}*/
-
     VAConfigAttribTypeMax
 } VAConfigAttribType;
 
@@ -411,6 +643,12 @@
 #define VA_RT_FORMAT_YUV420	0x00000001	
 #define VA_RT_FORMAT_YUV422	0x00000002
 #define VA_RT_FORMAT_YUV444	0x00000004
+#define VA_RT_FORMAT_YUV411	0x00000008
+#define VA_RT_FORMAT_YUV400	0x00000010
+#define VA_RT_FORMAT_RGB16	0x00010000
+#define VA_RT_FORMAT_RGB32	0x00020000
+/* RGBP covers RGBP and BGRP fourcc */ 
+#define VA_RT_FORMAT_RGBP	0x00100000
 #define VA_RT_FORMAT_PROTECTED	0x80000000
 
 /** @name Attribute values for VAConfigAttribRateControl */
@@ -427,6 +665,33 @@
 #define VA_RC_CQP                       0x00000010
 /** \brief Variable bitrate with peak rate higher than average bitrate. */
 #define VA_RC_VBR_CONSTRAINED           0x00000020
+/** \brief Intelligent Constant Quality. Provided an initial ICQ_quality_factor, 
+ *  adjusts QP at a frame and MB level based on motion to improve subjective quality. */
+#define VA_RC_ICQ			0x00000040
+/** \brief Macroblock based rate control.  Per MB control is decided 
+ *  internally in the encoder. It may be combined with other RC modes, except CQP. */
+#define VA_RC_MB                        0x00000080
+
+/**@}*/
+
+/** @name Attribute values for VAConfigAttribDecSliceMode */
+/**@{*/
+/** \brief Driver supports normal mode for slice decoding */
+#define VA_DEC_SLICE_MODE_NORMAL       0x00000001
+/** \brief Driver supports base mode for slice decoding */
+#define VA_DEC_SLICE_MODE_BASE         0x00000002
+
+/** @name Attribute values for VAConfigAttribDecJPEG */
+/**@{*/
+typedef union _VAConfigAttribValDecJPEG {
+    /** \brief Set to (1 << VA_ROTATION_xxx) for supported rotation angles. */
+    unsigned int rotation;
+    /** \brief Reserved for future use. */
+    unsigned int reserved[3]; 
+} VAConfigAttribValDecJPEG;
+/** \brief Driver supports subsample mode for slice decoding */
+#define VA_DEC_SLICE_MODE_SUBSAMPLE    0x00000004
+
 /**@}*/
 
 /** @name Attribute values for VAConfigAttribEncPackedHeaders */
@@ -441,6 +706,8 @@
 #define VA_ENC_PACKED_HEADER_SLICE      0x00000004
 /** \brief Driver supports misc packed headers. e.g. SEI for H.264. */
 #define VA_ENC_PACKED_HEADER_MISC       0x00000008
+/** \brief Driver supports raw packed header, see VAEncPackedHeaderRawData */
+#define VA_ENC_PACKED_HEADER_RAW_DATA   0x0000000C
 /**@}*/
 
 /** @name Attribute values for VAConfigAttribEncInterlaced */
@@ -465,8 +732,116 @@
 #define VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS        0x00000001
 /** \brief Driver supports an arbitrary number of rows per slice. */
 #define VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS    0x00000002
+/** \brief Driver supports any number of rows per slice but they must be the same 
+	for all slices except for the last one, which must be equal or smaller 
+	to the previous slices. */
+#define VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS    		0x00000004
+/** \brief Driver supports a maximum slice size requested by the app.  
+	The size is sent in VAEncMiscParameterMaxSliceSize. */
+#define VA_ENC_SLICE_STRUCTURE_MAX_SLICE_SIZE           0x00000008
 /**@}*/
 
+/** \brief Attribute value for VAConfigAttribEncJPEG */
+typedef union _VAConfigAttribValEncJPEG {
+    struct {
+        /** \brief set to 1 for arithmatic coding. */
+        unsigned int arithmatic_coding_mode : 1;
+        /** \brief set to 1 for progressive dct. */
+        unsigned int progressive_dct_mode : 1;
+        /** \brief set to 1 for non-interleaved. */
+        unsigned int non_interleaved_mode : 1;
+        /** \brief set to 1 for differential. */
+        unsigned int differential_mode : 1;
+        unsigned int max_num_components : 3;
+        unsigned int max_num_scans : 4;
+        unsigned int max_num_huffman_tables : 3;
+        unsigned int max_num_quantization_tables : 3;
+    } bits;
+    unsigned int value;
+} VAConfigAttribValEncJPEG;
+
+/** @name Attribute values for VAConfigAttribEncQuantization */
+/**@{*/
+/** \brief Driver does not support special types of quantization */
+#define VA_ENC_QUANTIZATION_NONE                        0x00000000
+/** \brief Driver supports trellis quantization */
+#define VA_ENC_QUANTIZATION_TRELLIS_SUPPORTED           0x00000001
+/**@}*/
+
+/** @name Attribute values for VAConfigAttribEncIntraRefresh */
+/**@{*/
+/** \brief Driver does not support intra refresh */
+#define VA_ENC_INTRA_REFRESH_NONE                       0x00000000
+/** \brief Driver supports column based rolling intra refresh */
+#define VA_ENC_INTRA_REFRESH_ROLLING_COLUMN             0x00000001
+/** \brief Driver supports row based rolling intra refresh */
+#define VA_ENC_INTRA_REFRESH_ROLLING_ROW                0x00000002
+/** \brief Driver supports adaptive intra refresh */
+#define VA_ENC_INTRA_REFRESH_ADAPTIVE                   0x00000010
+/** \brief Driver supports cyclic intra refresh */
+#define VA_ENC_INTRA_REFRESH_CYCLIC                     0x00000020
+
+/**@}*/
+
+/** \brief Attribute value for VAConfigAttribEncRateControlExt */
+typedef union _VAConfigAttribValEncRateControlExt {
+    struct {
+        /** \brief The number of temporal layers with layer specific bit-rate targets
+         * that are supported. The application will send multiple
+         * VAEncMiscParameterRateControl and VAEncMiscParameterFrameRate structures
+         * for each layer, using the temporal_id field as the layer identifier.
+         * If per temporal layer rate control is not supported, 
+         * num_temporal_layers_minus1 will be 0 and the temporal_id field in
+         * VAEncMiscParameterRateControl and VAEncMiscParameterFrameRate will be ignored.
+         */
+     unsigned int num_temporal_layers_minus1 : 8;
+     unsigned int reserved                   : 24;
+     } bits;
+     unsigned int value;
+} VAConfigAttribValEncRateControlExt;
+
+/**
+ * \brief Intel specific attribute definitions
+ */
+/** @name Attribute values for VAConfigAttribEncFunctionTypeIntel
+ *
+ * The desired type should be passed to driver when creating the configuration. 
+ * If VA_ENC_FUNCTION_ENC_PAK is set, VA_ENC_FUNCTION_ENC and VA_ENC_FUNCTION_PAK 
+ * will be ignored if set also.  VA_ENC_FUNCTION_ENC and VA_ENC_FUNCTION_PAK operations 
+ * shall be called separately if ENC and PAK (VA_ENC_FUNCTION_ENC | VA_ENC_FUNCTION_PAK) 
+ * is set for configuration. VA_ENC_FUNCTION_ENC_PAK is recommended for best performance.
+ * If only VA_ENC_FUNCTION_ENC is set, there will be no bitstream output. 
+ * If VA_ENC_FUNCTION_ENC_PAK is not set and VA_ENC_FUNCTION_PAK is set, then two extra 
+ * input buffers for PAK are needed: VAEncFEIMVBufferType and VAEncFEIModeBufferType.
+ **/
+/**@{*/
+/** \brief Only default is supported */
+#define VA_ENC_FUNCTION_DEFAULT_INTEL                         0x00000000
+/** \brief ENC only is supported */
+#define VA_ENC_FUNCTION_ENC_INTEL                             0x00000001
+/** \brief PAK only is supported */
+#define VA_ENC_FUNCTION_PAK_INTEL                             0x00000002
+/** \brief ENC_PAK is supported */
+#define VA_ENC_FUNCTION_ENC_PAK_INTEL                         0x00000004
+
+/**@}*/
+
+/** \brief Attribute value for VAConfigAttribStatisticsIntel */
+typedef union _VAConfigAttribValStatisticsIntel {
+    struct {
+        /** \brief Max number of past reference frames that are supported. */
+        unsigned int	max_num_past_references   : 4;
+        /** \brief Max number of future reference frames that are supported. */
+        unsigned int	max_num_future_references : 4;
+        /** \brief Number of output surfaces that are supported */
+        unsigned int	num_outputs               : 3;
+        /** \brief Interlaced content is supported */
+        unsigned int    interlaced                : 1;
+        unsigned int	reserved                  : 20;
+    } bits;
+    unsigned int value;
+} VAConfigAttribValStatisticsIntel;
+
 /*
  * if an attribute is not applicable for a given
  * profile/entrypoint pair, then set the value to the following 
@@ -649,7 +1024,7 @@
      * zero and drops the \c VA_SURFACE_ATTRIB_SETTABLE flag.
      */
     VASurfaceAttribPixelFormat,
-    /** \brief Minimal width in pixels (int, read/write). */
+    /** \brief Minimal width in pixels (int, read-only). */
     VASurfaceAttribMinWidth,
     /** \brief Maximal width in pixels (int, read-only). */
     VASurfaceAttribMaxWidth,
@@ -657,6 +1032,13 @@
     VASurfaceAttribMinHeight,
     /** \brief Maximal height in pixels (int, read-only). */
     VASurfaceAttribMaxHeight,
+    /** \brief Surface memory type expressed in bit fields (int, read/write). */
+    VASurfaceAttribMemoryType,
+    /** \brief External buffer descriptor (pointer, write). */
+    VASurfaceAttribExternalBufferDescriptor,
+    /** \brief Surface usage hint, gives the driver a hint of intended usage 
+     *  to optimize allocation (e.g. tiling) (int, read/write). */
+    VASurfaceAttribUsageHint,
     /** \brief Number of surface attributes. */
     VASurfaceAttribCount
 } VASurfaceAttribType;
@@ -671,38 +1053,123 @@
     VAGenericValue      value;
 } VASurfaceAttrib;
 
+/** 
+ * @name VASurfaceAttribMemoryType values in bit fields. 
+ * Bit 0:7 are reserved for generic types, Bit 31:28 are reserved for 
+ * Linux DRM, Bit 23:20 are reserved for Android. DRM and Android specific
+ * types are defined in DRM and Android header files.
+ */
+/**@{*/
+/** \brief VA memory type (default) is supported. */
+#define VA_SURFACE_ATTRIB_MEM_TYPE_VA			0x00000001
+/** \brief V4L2 buffer memory type is supported. */
+#define VA_SURFACE_ATTRIB_MEM_TYPE_V4L2			0x00000002
+/** \brief User pointer memory type is supported. */
+#define VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR		0x00000004
+/**@}*/
+
+/** 
+ * \brief VASurfaceAttribExternalBuffers structure for 
+ * the VASurfaceAttribExternalBufferDescriptor attribute.
+ */
+typedef struct _VASurfaceAttribExternalBuffers {
+    /** \brief pixel format in fourcc. */
+    unsigned int pixel_format;
+    /** \brief width in pixels. */
+    unsigned int width;
+    /** \brief height in pixels. */
+    unsigned int height;
+    /** \brief total size of the buffer in bytes. */
+    unsigned int data_size;
+    /** \brief number of planes for planar layout */
+    unsigned int num_planes;
+    /** \brief pitch for each plane in bytes */
+    unsigned int pitches[4];
+    /** \brief offset for each plane in bytes */
+    unsigned int offsets[4];
+    /** \brief buffer handles or user pointers */
+    unsigned long *buffers;
+    /** \brief number of elements in the "buffers" array */
+    unsigned int num_buffers;
+    /** \brief flags. See "Surface external buffer descriptor flags". */
+    unsigned int flags;
+    /** \brief reserved for passing private data */
+    void *private_data;
+} VASurfaceAttribExternalBuffers;
+
+/** @name VASurfaceAttribExternalBuffers flags */
+/**@{*/
+/** \brief Enable memory tiling */
+#define VA_SURFACE_EXTBUF_DESC_ENABLE_TILING	0x00000001
+/** \brief Memory is cacheable */
+#define VA_SURFACE_EXTBUF_DESC_CACHED		0x00000002
+/** \brief Memory is non-cacheable */
+#define VA_SURFACE_EXTBUF_DESC_UNCACHED		0x00000004
+/** \brief Memory is write-combined */
+#define VA_SURFACE_EXTBUF_DESC_WC		0x00000008
+/** \brief Memory is protected */
+#define VA_SURFACE_EXTBUF_DESC_PROTECTED        0x80000000
+
+/** @name VASurfaceAttribUsageHint attribute usage hint flags */
+/**@{*/
+/** \brief Surface usage not indicated. */
+#define VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC 	0x00000000
+/** \brief Surface used by video decoder. */
+#define VA_SURFACE_ATTRIB_USAGE_HINT_DECODER 	0x00000001
+/** \brief Surface used by video encoder. */
+#define VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER 	0x00000002
+/** \brief Surface read by video post-processing. */
+#define VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ 	0x00000004
+/** \brief Surface written by video post-processing. */
+#define VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE 	0x00000008
+/** \brief Surface used for display. */
+#define VA_SURFACE_ATTRIB_USAGE_HINT_DISPLAY 	0x00000010
+
+/**@}*/
+
 /**
- * \brief Get surface attributes for the supplied config.
+ * \brief Queries surface attributes for the supplied config.
  *
- * This function retrieves the surface attributes matching the supplied
- * config. The caller shall provide an \c attrib_list with all attributes
- * to be retrieved. Upon successful return, the attributes in \c attrib_list
- * are updated with the requested value. Unknown attributes or attributes
- * that are not supported for the given config will have their \c flags
- * field set to \c VA_SURFACE_ATTRIB_NOT_SUPPORTED.
+ * Unlike vaGetSurfaceAttributes(), this function queries for all
+ * supported attributes for the supplied VA @config. In particular, if
+ * the underlying hardware supports the creation of VA surfaces in
+ * various formats, then this function will enumerate all pixel
+ * formats that are supported.
+ *
+ * The \c attrib_list array is allocated by the user and \c
+ * num_attribs shall be initialized to the number of allocated
+ * elements in that array. Upon successful return, the actual number
+ * of attributes will be overwritten into \c num_attribs. Otherwise,
+ * \c VA_STATUS_ERROR_MAX_NUM_EXCEEDED is returned and \c num_attribs
+ * is adjusted to the number of elements that would be returned if
+ * enough space was available.
+ *
+ * Note: it is perfectly valid to pass NULL to the \c attrib_list
+ * argument when vaQuerySurfaceAttributes() is used to determine the
+ * actual number of elements that need to be allocated.
  *
  * @param[in] dpy               the VA display
  * @param[in] config            the config identifying a codec or a video
  *     processing pipeline
- * @param[in,out] attrib_list   the list of attributes on input, with at
- *     least \c type fields filled in, and possibly \c value fields whenever
- *     necessary. The updated list of attributes and flags on output
- * @param[in] num_attribs       the number of attributes supplied in the
- *     \c attrib_list array
+ * @param[out] attrib_list      the output array of #VASurfaceAttrib elements
+ * @param[in,out] num_attribs   the number of elements allocated on
+ *      input, the number of elements actually filled in output
  */
 VAStatus
-vaGetSurfaceAttributes(
+vaQuerySurfaceAttributes(
     VADisplay           dpy,
     VAConfigID          config,
     VASurfaceAttrib    *attrib_list,
-    unsigned int        num_attribs
+    unsigned int       *num_attribs
 );
 
 /**
  * \brief Creates an array of surfaces
  *
  * Creates an array of surfaces. The optional list of attributes shall
- * be constructed and verified through vaGetSurfaceAttributes().
+ * be constructed and validated through vaGetSurfaceAttributes() or
+ * constructed based based on what the underlying hardware could
+ * expose through vaQuerySurfaceAttributes().
  *
  * @param[in] dpy               the VA display
  * @param[in] format            the desired surface format. See \c VA_RT_FORMAT_*
@@ -809,6 +1276,8 @@
     VAEncPackedHeaderDataBufferType     = 26,
     VAEncMiscParameterBufferType	= 27,
     VAEncMacroblockParameterBufferType	= 28,
+    VAEncMacroblockMapBufferType        = 29,
+    VAEncQpBufferType                   = 30,
 /* Following are video processing buffer types */
     /**
      * \brief Video processing pipeline parameter buffer.
@@ -830,6 +1299,19 @@
      * color balance (#VAProcFilterParameterBufferColorBalance), etc.
      */
     VAProcFilterParameterBufferType     = 42,
+    VAParsePictureParameterBufferType   = 43,
+    VAParseSliceHeaderGroupBufferType   = 44,
+
+    /**
+     * \brief Intel specific buffer types start at 1001
+     */
+    VAEncFEIMVBufferTypeIntel                 = 1001,
+    VAEncFEIModeBufferTypeIntel,
+    VAEncFEIDistortionBufferTypeIntel,
+    VAStatsStatisticsParameterBufferTypeIntel,
+    VAStatsStatisticsBufferTypeIntel,
+    VAStatsMotionVectorBufferTypeIntel,
+
     VABufferTypeMax
 } VABufferType;
 
@@ -838,11 +1320,29 @@
     VAEncMiscParameterTypeFrameRate 	= 0,
     VAEncMiscParameterTypeRateControl  	= 1,
     VAEncMiscParameterTypeMaxSliceSize	= 2,
+    /** \brief Buffer type used for Adaptive intra refresh */
     VAEncMiscParameterTypeAIR    	= 3,
     /** \brief Buffer type used to express a maximum frame size (in bits). */
     VAEncMiscParameterTypeMaxFrameSize  = 4,
     /** \brief Buffer type used for HRD parameters. */
     VAEncMiscParameterTypeHRD           = 5,
+    VAEncMiscParameterTypeQualityLevel  = 6,
+    /** \brief Buffer type used for Rolling intra refresh */
+    VAEncMiscParameterTypeRIR           = 7,
+    VAEncMiscParameterTypeQuantization  = 8,
+    /** \brief Buffer type used for sending skip frame parameters to the encoder's
+      * rate control, when the user has externally skipped frames. */
+    VAEncMiscParameterTypeSkipFrame     = 9,
+    /** \brief Buffer type used for region-of-interest (ROI) parameters. */
+    VAEncMiscParameterTypeROI           = 10,
+    /** \brief Buffer type used for Cyclic intra refresh */
+    VAEncMiscParameterTypeCIR           = 11,
+    /** \brief Buffer type used for temporal layer structure */
+    VAEncMiscParameterTypeTemporalLayerStructure   = 12,
+
+    /* Intel specific types start at 1001 */
+    /* VAEntrypointEncFEIIntel */
+    VAEncMiscParameterTypeFEIFrameControlIntel = 1001 
 } VAEncMiscParameterType;
 
 /** \brief Packed header type. */
@@ -853,6 +1353,15 @@
     VAEncPackedHeaderPicture    = 2,
     /** \brief Packed slice header. */
     VAEncPackedHeaderSlice      = 3,
+    /** 
+     * \brief Packed raw header. 
+     * 
+     * Packed raw data header can be used by the client to insert a header  
+     * into the bitstream data buffer at the point it is passed, the driver 
+     * will handle the raw packed header based on "has_emulation_bytes" field
+     * in the packed header parameter structure.
+     */
+    VAEncPackedHeaderRawData    = 4,
     /** \brief Misc packed header. See codec-specific definitions. */
     VAEncPackedHeaderMiscMask   = 0x80000000,
 } VAEncPackedHeaderType;
@@ -890,6 +1399,17 @@
     unsigned int data[0];
 } VAEncMiscParameterBuffer;
 
+/** \brief Temporal Structure*/
+typedef struct _VAEncMiscParameterTemporalLayerStructure
+{
+    /* The number of temporal layers */
+    uint32_t number_of_layers;
+    /* this is Length of the sequence defining frame layer membership. Should be 1-32 */
+    uint32_t periodicity;
+    /*This is Array indicating the layer id for each frame in a sequence of length ts_periodicity.*/
+    uint32_t layer_id[32];
+} VAEncMiscParameterTemporalLayerStructure;
+
 
 /** \brief Rate control parameters */
 typedef struct _VAEncMiscParameterRateControl
@@ -905,9 +1425,13 @@
      * then the rate control will guarantee the target bit-rate over a 500 ms window
      */
     unsigned int window_size;
-    /* initial QP at I frames */
+    /* initial_qp: initial QP for the first I frames
+     * min_qp/max_qp: minimal and maximum QP frames
+     * If set them to 0, encoder chooses the best QP according to rate control
+     */
     unsigned int initial_qp;
     unsigned int min_qp;
+    unsigned int max_qp;
     unsigned int basic_unit_size;
     union
     {
@@ -916,14 +1440,33 @@
             unsigned int reset : 1;
             unsigned int disable_frame_skip : 1; /* Disable frame skip in rate control mode */
             unsigned int disable_bit_stuffing : 1; /* Disable bit stuffing in rate control mode */
+            unsigned int mb_rate_control : 4; /* Control VA_RC_MB 0: default, 1: enable, 2: disable, other: reserved*/
+            /*
+             * The temporal layer that the rate control parameters are specified for.
+             */ 
+            unsigned int temporal_id : 8; 
+            unsigned int reserved : 17;
         } bits;
         unsigned int value;
     } rc_flags;
+    unsigned int ICQ_quality_factor; /* Initial ICQ quality factor: 1-51. */
 } VAEncMiscParameterRateControl;
 
 typedef struct _VAEncMiscParameterFrameRate
 {
     unsigned int framerate;
+    union 
+    {
+        struct
+        {
+            /*
+             * The temporal id the framerate parameters are specified for.
+             */
+            unsigned int temporal_id : 8; 
+            unsigned int reserved : 24;
+         } bits;
+         unsigned int value;
+     } framerate_flags;
 } VAEncMiscParameterFrameRate;
 
 /*
@@ -936,16 +1479,96 @@
     unsigned int max_slice_size;
 } VAEncMiscParameterMaxSliceSize;
 
+/*
+ * \brief Cyclic intra refresh data structure for encoding.
+ */
+typedef struct _VAEncMiscParameterCIR
+{
+    /** \brief  the number of consecutive macroblocks to be coded as intra */
+    unsigned int cir_num_mbs;
+} VAEncMiscParameterCIR;
+
+/*
+ * \brief Adaptive intra refresh data structure for encoding.
+ */
 typedef struct _VAEncMiscParameterAIR
 {
+    /** \brief the minimum number of macroblocks to refresh in a frame */
     unsigned int air_num_mbs;
+    /**
+     * \brief threshhold of blockmatching criterion (typically SAD)
+     *
+     * Macroblocks above that threshold are marked as candidates and
+     * on subsequent frames a number of these candidates are coded as Intra
+     * Generally the threshhold need to be set and tuned to an appropriate level
+     * according to the feedback of coded frame.
+     */
     unsigned int air_threshold;
-    unsigned int air_auto; /* if set to 1 then hardware auto-tune the AIR threshold */
+    /** \brief if set to 1 then hardware auto-tune the AIR threshold */
+    unsigned int air_auto;
 } VAEncMiscParameterAIR;
 
+/*
+ * \brief Rolling intra refresh data structure for encoding.
+ */
+typedef struct _VAEncMiscParameterRIR
+{
+    union
+    {
+        struct
+	/**
+	 * \brief Indicate if intra refresh is enabled in column/row. 
+	 *
+	 * App should query VAConfigAttribEncIntraRefresh to confirm RIR support 
+	 * by the driver before sending this structure. The following RIR restrictions
+	 * apply:
+	 *  - No field encoding.
+	 *  - No B frames.
+	 *  - No multiple references.
+	 */
+        {
+	    /* \brief enable RIR in column */
+            unsigned int enable_rir_column : 1;
+	    /* \brief enable RIR in row */
+            unsigned int enable_rir_row : 1;
+	    unsigned int reserved : 30;
+        } bits;
+        unsigned int value;
+    } rir_flags;
+    /** 
+     * \brief Indicates the column or row location in MB. It is ignored if 
+     * rir_flags is 0. 
+     */
+    unsigned short intra_insertion_location;
+    /** 
+     * \brief Indicates the number of columns or rows in MB. It is ignored if 
+     * rir_flags is 0.
+     */
+    unsigned short intra_insert_size;
+    /** 
+     * \brief indicates the Qp difference for inserted intra columns or rows. 
+     * App can use this to adjust intra Qp based on bitrate & max frame size.
+     */
+    char qp_delta_for_inserted_intra;
+	
+} VAEncMiscParameterRIR;
+
 typedef struct _VAEncMiscParameterHRD
 {
+   /**
+    * \brief This value indicates the amount of data that will
+    * be buffered by the decoding application prior to beginning playback
+    */
     unsigned int initial_buffer_fullness;       /* in bits */
+   /**
+    * \brief This value indicates the amount of data that the
+    * encoder should try to maintain in the decoder's buffer
+    */
+    unsigned int optimal_buffer_fullness;       /* in bits */
+    /**
+     * \brief This value indicates the amount of data that
+     * may be buffered by the decoding application
+     */
     unsigned int buffer_size;                   /* in bits */
 } VAEncMiscParameterHRD;
 
@@ -965,6 +1588,107 @@
     unsigned int                max_frame_size;
 } VAEncMiscParameterBufferMaxFrameSize;
 
+/**
+ * \brief Encoding quality level.
+ *
+ * The encoding quality could be set through this structure, if the implementation  
+ * supports multiple quality levels. The quality level set through this structure is 
+ * persistent over the entire coded sequence, or until a new structure is being sent.
+ * The quality level range can be queried through the VAConfigAttribEncQualityRange 
+ * attribute. A lower value means higher quality, and a value of 1 represents the highest 
+ * quality. The quality level setting is used as a trade-off between quality and speed/power 
+ * consumption, with higher quality corresponds to lower speed and higher power consumption. 
+ */
+typedef struct _VAEncMiscParameterBufferQualityLevel {
+    /** \brief Encoding quality level setting. */
+    unsigned int                quality_level;
+} VAEncMiscParameterBufferQualityLevel;
+
+/**
+ * \brief Quantization settings for encoding.
+ *
+ * Some encoders support special types of quantization such as trellis, and this structure
+ * can be used by the app to control these special types of quantization by the encoder.
+ */
+typedef struct _VAEncMiscParameterQuantization
+{
+    union
+    {
+    /* if no flags is set then quantization is determined by the driver */
+        struct
+        {
+	    /* \brief disable trellis for all frames/fields */
+            unsigned int disable_trellis : 1; 
+	    /* \brief enable trellis for I frames/fields */
+            unsigned int enable_trellis_I : 1; 
+	    /* \brief enable trellis for P frames/fields */
+            unsigned int enable_trellis_P : 1; 
+	    /* \brief enable trellis for B frames/fields */
+            unsigned int enable_trellis_B : 1; 
+            unsigned int reserved : 28;
+        } bits;
+        unsigned int value;
+    } quantization_flags;
+} VAEncMiscParameterQuantization;
+
+/**
+ * \brief Encoding skip frame.
+ *
+ * The application may choose to skip frames externally to the encoder (e.g. drop completely or 
+ * code as all skip's). For rate control purposes the encoder will need to know the size and number 
+ * of skipped frames.  Skip frame(s) indicated through this structure is applicable only to the 
+ * current frame.  It is allowed for the application to still send in packed headers for the driver to 
+ * pack, although no frame will be encoded (e.g. for HW to encrypt the frame).  
+ */
+typedef struct _VAEncMiscParameterSkipFrame {
+    /** \brief Indicates skip frames as below.
+      * 0: Encode as normal, no skip.
+      * 1: One or more frames were skipped prior to the current frame, encode the current frame as normal.  
+      * 2: The current frame is to be skipped, do not encode it but pack/encrypt the packed header contents
+      *    (all except VAEncPackedHeaderSlice) which could contain actual frame contents (e.g. pack the frame 
+      *    in VAEncPackedHeaderPicture).  */
+    unsigned char               skip_frame_flag;
+    /** \brief The number of frames skipped prior to the current frame.  Valid when skip_frame_flag = 1. */
+    unsigned char               num_skip_frames;
+    /** \brief When skip_frame_flag = 1, the size of the skipped frames in bits.   When skip_frame_flag = 2, 
+      * the size of the current skipped frame that is to be packed/encrypted in bits. */
+    unsigned int                size_skip_frames;
+} VAEncMiscParameterSkipFrame;
+
+/**
+ * \brief Encoding region-of-interest (ROI).
+ *
+ * The encoding ROI can be set through this structure, if the implementation
+ * supports ROI input. The ROI set through this structure is applicable only to the
+ * current frame.  The number of supported ROIs can be queried through the
+ * VAConfigAttribEncRoi.  The encoder will use the ROI information to adjust the QP
+ * values of the MB's that fall within the ROIs.
+ */
+typedef struct _VAEncMiscParameterBufferRoi {
+    /** \brief Number of ROIs being sent.*/
+    unsigned int                num_roi;
+    /** \brief Valid when VAConfigAttribRateControl != VA_RC_CQP, then the encoder's
+     *  rate control will determine actual delta QPs.  Specifies the max/min allowed delta QPs.*/
+    char                        max_delta_qp;
+    char                        min_delta_qp;
+
+    /** \brief Pointer to a VAEncROI array with num_ROI elements.*/
+    struct VAEncROI
+    {
+        /** \brief Defines the ROI boundary in pixels, the driver will map it to appropriate
+         *  codec coding units.  It is relative to the frame coordinates for both frame and field cases. */
+        VARectangle             roi_rectangle;
+        /** \brief When VAConfigAttribRateControl == VA_RC_CQP then roi_value specifes the delta QP that
+         *  will be added on top of the frame level QP.  For other rate control modes, roi_value specifies the
+         *  priority of the ROI region relative to the non-ROI region.  It can positive (more important) or
+         *  negative (less important) values and is compared with non-ROI region (taken as value 0).
+         *  E.g. ROI region with roi_value -3 is less important than the non-ROI region (roi_value implied to be 0)
+         *  which is less important than ROI region with roi_value +2.  For overlapping regions, the roi_value
+         *  that is first in the ROI array will have priority.   */
+        char                    roi_value;
+    } *ROI;
+} VAEncMiscParameterBufferROI;
+
 /* 
  * There will be cases where the bitstream buffer will not have enough room to hold
  * the data for the entire slice, and the following flags will be used in the slice
@@ -986,26 +1710,7 @@
     unsigned int slice_data_flag;	/* see VA_SLICE_DATA_FLAG_XXX definitions */
 } VASliceParameterBufferBase;
 
-
-/****************************
- * JEPG data structure
- ***************************/
-typedef struct _VAQMatrixBufferJPEG
-{
-    int load_lum_quantiser_matrix;
-    int load_chroma_quantiser_matrix;
-    unsigned char lum_quantiser_matrix[64];
-    unsigned char chroma_quantiser_matrix[64];
-} VAQMatrixBufferJPEG;
-
-typedef struct _VAEncPictureParameterBufferJPEG
-{
-    VASurfaceID reconstructed_picture;
-    unsigned short picture_width;
-    unsigned short picture_height;
-    VABufferID coded_buf;
-} VAEncPictureParameterBufferJPEG;
-
+#include <va/va_dec_jpeg.h>
 
 /****************************
  * MPEG-2 data structures
@@ -1179,6 +1884,8 @@
     /* for direct mode prediction */
     short TRB;
     short TRD;
+    unsigned int Tframe;
+    unsigned char vop_quant;
 } VAPictureParameterBufferMPEG4;
 
 /* MPEG-4 Inverse Quantization Matrix Buffer */
@@ -1371,6 +2078,8 @@
         } bits;
         unsigned int value;
     } transform_fields;
+    unsigned char luma_scale2;		/* PICTURE_LAYER::LUMSCALE2 */
+    unsigned char luma_shift2;		/* PICTURE_LAYER::LUMSHIFT2 */
 } VAPictureParameterBufferVC1;
 
 /* VC-1 Bitplane Buffer 
@@ -1413,7 +2122,14 @@
 typedef struct _VAPictureH264
 {
     VASurfaceID picture_id;
+    /*
+     * frame_idx is long_term_frame_idx for long term reference picture,
+     * and frame_num for short term reference picture.
+     */
     unsigned int frame_idx;
+    /* 
+     * see flags below. 
+     */
     unsigned int flags;
     signed int TopFieldOrderCnt;
     signed int BottomFieldOrderCnt;
@@ -1424,6 +2140,7 @@
 #define VA_PICTURE_H264_BOTTOM_FIELD		0x00000004
 #define VA_PICTURE_H264_SHORT_TERM_REFERENCE	0x00000008
 #define VA_PICTURE_H264_LONG_TERM_REFERENCE	0x00000010
+#define VA_PICTURE_H264_NON_EXISTING		0x00000020
 
 /* H.264 Picture Parameter Buffer */
 /* 
@@ -1478,6 +2195,8 @@
         unsigned int value;
     } pic_fields;
     unsigned short frame_num;
+    unsigned char num_ref_idx_l0_default_active_minus1;
+    unsigned char num_ref_idx_l1_default_active_minus1;
 } VAPictureParameterBufferH264;
 
 /* H.264 Inverse Quantization Matrix Buffer */
@@ -1497,7 +2216,20 @@
  * in raster scan order
  */ 
 
-/* H.264 Slice Parameter Buffer */
+/*
+ * H.264 Slice Parameter Buffer for base mode decoding
+ */
+typedef struct _VASliceParameterBufferBaseH264
+{
+    unsigned int slice_data_size;/* number of bytes in the slice data buffer for this slice */
+    /** \brief Byte offset to the NAL Header Unit for this slice. */
+    unsigned int slice_data_offset;
+    unsigned int slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX defintions */
+} VASliceParameterBufferH264Base;
+
+/*
+ * H.264 Slice Parameter Buffer for normal mode decoding
+ */
 typedef struct _VASliceParameterBufferH264
 {
     unsigned int slice_data_size;/* number of bytes in the slice data buffer for this slice */
@@ -1569,6 +2301,7 @@
     } slice_flags;
 } VAEncSliceParameterBuffer;
 
+
 /****************************
  * H.263 specific encode data structures
  ****************************/
@@ -1703,6 +2436,16 @@
 #define VA_CODED_BUF_STATUS_SINGLE_NALU                 0x10000000	
 
 /**
+ * \brief The coded buffer segment contains a private data. 
+ *
+ * This flag indicates that the coded buffer segment contains 
+ * private data. This flag can be used to exchange private data
+ * between the client and the driver. Private data should follow
+ * regular coded data in the coded buffer segement list. 
+ */
+#define VA_CODED_BUF_STATUS_PRIVATE_DATA                 0x80000000	
+
+/**
  * \brief Coded buffer segment.
  *
  * #VACodedBufferSegment is an element of a linked list describing
@@ -1731,7 +2474,124 @@
      */
     void               *next;
 } VACodedBufferSegment;
-     
+
+
+/*
+ * H.264 Parsed Slice Header Group Info
+ * After slice header is parsed by decode hardware,
+ * group slice header buffer will be returned to client.
+ * client will retrieve multiple parsed slice header infos from that buffer
+ */
+
+/* H.264 Parsed Slice Header Info */
+typedef struct _VAParseSliceHeaderGroupBuffer
+{
+	unsigned int size;
+
+	unsigned char nal_ref_idc;
+	unsigned char nal_unit_type;
+	unsigned char slice_type;
+	unsigned char redundant_pic_cnt;
+
+	unsigned short first_mb_in_slice;
+	char slice_qp_delta;
+	char slice_qs_delta;
+
+	unsigned char luma_log2_weight_denom;
+	unsigned char chroma_log2_weight_denom;
+	unsigned char cabac_init_idc;
+        unsigned char reserved8bit;
+
+        unsigned short pic_order_cnt_lsb;
+        unsigned short reserved16bit;
+
+        unsigned short idr_pic_id;
+        unsigned char pic_parameter_set_id;
+	unsigned char colour_plane_id;
+
+	char slice_alpha_c0_offset_div2;
+	char slice_beta_offset_div2;
+	unsigned char slice_group_change_cycle;
+	unsigned char disable_deblocking_filter_idc;
+
+	unsigned int frame_num;
+	int delta_pic_order_cnt_bottom;
+	int delta_pic_order_cnt[2];
+
+	unsigned char num_reorder_cmds[2];
+	unsigned char num_ref_active_minus1[2];
+
+	unsigned int weights_present[2][2];
+
+	unsigned short num_mem_man_ops;
+
+	union {
+		struct {
+			unsigned field_pic_flag                     : 1;
+			unsigned bottom_field_flag                  : 1;
+			unsigned num_ref_idx_active_override_flag   : 1;
+			unsigned direct_spatial_mv_pred_flag        : 1;
+			unsigned no_output_of_prior_pics_flag       : 1;
+			unsigned long_term_reference_flag           : 1;
+			unsigned idr_flag                           : 1;
+			unsigned anchor_pic_flag                    : 1;
+			unsigned inter_view_flag                    : 1;
+		} bits;
+
+		unsigned short value;
+	} flags;
+
+//MVC
+	unsigned short view_id;
+	unsigned char priority_id;
+	unsigned char temporal_id;
+} VAParseSliceHeaderGroupBuffer;
+
+typedef struct _VAParsePictureParameterBuffer {
+    VABufferID frame_buf_id;
+    VABufferID slice_headers_buf_id;
+    unsigned int frame_size;
+    unsigned int slice_headers_size;
+    union {
+        struct {
+            unsigned frame_mbs_only_flag : 1;
+            unsigned pic_order_present_flag : 1;
+            unsigned delta_pic_order_always_zero_flag : 1;
+            unsigned redundant_pic_cnt_present_flag : 1;
+            unsigned weighted_pred_flag : 1;
+            unsigned entropy_coding_mode_flag : 1;
+            unsigned deblocking_filter_control_present_flag : 1;
+            unsigned weighted_bipred_idc : 1;
+        } bits;
+        unsigned int value;
+    } flags;
+
+    union {
+        struct {
+            unsigned char nalu_header_unit_type : 5;
+            unsigned char nalu_header_ref_idc : 2;
+        } bits;
+        unsigned char value;
+    } nalu_header;
+
+    unsigned short expected_pic_parameter_set_id;
+    unsigned char num_slice_groups_minus1;
+    unsigned char slice_group_map_type;
+    unsigned char log2_slice_group_change_cycle;
+    unsigned char chroma_format_idc;
+
+    unsigned char log2_max_pic_order_cnt_lsb_minus4;
+    unsigned char pic_order_cnt_type;
+    unsigned char log2_max_frame_num_minus4;
+    unsigned char idr_flag;
+    unsigned char slice_offset;
+
+    /* additionally */
+    unsigned char residual_colour_transform_flag;
+    unsigned char num_ref_idc_l0_active_minus1;
+    unsigned char num_ref_idc_l1_active_minus1;
+} VAParsePictureParameterBuffer;
+
 /*
  * Map data store of the buffer into the client's address space
  * vaCreateBuffer() needs to be called with "data" set to NULL before
@@ -1851,10 +2711,11 @@
 */
 typedef struct _VASurfaceDecodeMBErrors
 {
-    int status; /* 1 if hardware has returned detailed info below, -1 means this record is invalid */
+    int status; /* 1 if start_mb/end_mb with errors is returned, 2 if num_mb with errors is returned, -1 means this record is invalid */
     unsigned int start_mb; /* start mb address with errors */
-    unsigned int end_mb;  /* end mb address with errors */
+    unsigned int end_mb;   /* end mb address with errors */
     VADecodeErrorType decode_error_type;
+    unsigned int num_mb;   /* number of mbs with errors */
 } VASurfaceDecodeMBErrors;
 
 /*
@@ -1883,11 +2744,20 @@
     ((unsigned long)(unsigned char) (ch0) | ((unsigned long)(unsigned char) (ch1) << 8) | \
     ((unsigned long)(unsigned char) (ch2) << 16) | ((unsigned long)(unsigned char) (ch3) << 24 ))
 
-/* a few common FourCCs */
+/* 
+ * Pre-defined fourcc codes
+ */
 #define VA_FOURCC_NV12		0x3231564E
+#define VA_FOURCC_NV21		0x3132564E
 #define VA_FOURCC_AI44		0x34344149
 #define VA_FOURCC_RGBA		0x41424752
+#define VA_FOURCC_RGBX		0x58424752
 #define VA_FOURCC_BGRA		0x41524742
+#define VA_FOURCC_BGRX		0x58524742
+#define VA_FOURCC_ARGB		0x42475241
+#define VA_FOURCC_XRGB		0x42475258
+#define VA_FOURCC_ABGR          0x52474241
+#define VA_FOURCC_XBGR          0x52474258
 #define VA_FOURCC_UYVY          0x59565955
 #define VA_FOURCC_YUY2          0x32595559
 #define VA_FOURCC_AYUV          0x56555941
@@ -1897,6 +2767,15 @@
 #define VA_FOURCC_IYUV          0x56555949
 #define VA_FOURCC_YV24          0x34325659
 #define VA_FOURCC_YV32          0x32335659
+#define VA_FOURCC_Y800          0x30303859
+#define VA_FOURCC_IMC3          0x33434D49
+#define VA_FOURCC_411P          0x50313134
+#define VA_FOURCC_422H          0x48323234
+#define VA_FOURCC_422V          0x56323234
+#define VA_FOURCC_444P          0x50343434
+#define VA_FOURCC_RGBP          0x50424752
+#define VA_FOURCC_BGRP          0x50524742
+#define VA_FOURCC_411R          0x52313134 /* rotated 411P */
 
 /* byte order */
 #define VA_LSB_FIRST		1
@@ -1935,7 +2814,7 @@
     unsigned int	num_planes;	/* can not be greater than 4 */
     /* 
      * An array indicating the scanline pitch in bytes for each plane.
-     * Each plane may have a different pitch. Maximum 4 planes for planar formats
+     * Each plane may have a different pitch. Maximum 3 planes for planar formats
      */
     unsigned int	pitches[3];
     /* 
@@ -1958,6 +2837,7 @@
     char component_order[4];
     /*
      * Pitch and byte offset for the fourth plane if the image format requires 4 planes
+     * Particular use case is JPEG with CMYK profile
      */
     unsigned int extra_pitch;
     unsigned int extra_offset;
@@ -2214,14 +3094,6 @@
     int num_surfaces
 );
 
-typedef struct _VARectangle
-{
-    short x;
-    short y;
-    unsigned short width;
-    unsigned short height;
-} VARectangle;
-
 /*
  * Display attributes
  * Display attributes are used to control things such as contrast, hue, saturation,
@@ -2230,11 +3102,39 @@
  * before calling vaPutSurface()
  */
 
-/* attribute value for VADisplayAttribRotation   */
+/**
+ * @name Rotation angles
+ *
+ * Those values could be used for VADisplayAttribRotation attribute or
+ * VAProcPipelineParameterBuffer::rotation_state or in VAConfigAttribValDecJPEG. 
+ * The rotation operation is clockwise.
+ */
+/**@{*/
+/** \brief No rotation. */
 #define VA_ROTATION_NONE        0x00000000
+/** \brief Rotation by 90° clockwise. */
 #define VA_ROTATION_90          0x00000001
+/** \brief Rotation by 180° clockwise. */
 #define VA_ROTATION_180         0x00000002
+/** \brief Rotation by 270° clockwise. */
 #define VA_ROTATION_270         0x00000003
+/**@}*/
+
+/**
+ * @name Mirroring directions
+ *
+ * Those values could be used for VADisplayAttribMirror attribute or
+ * VAProcPipelineParameterBuffer::mirror_state.
+ 
+ */
+/**@{*/
+/** \brief No Mirroring. */
+#define VA_MIRROR_NONE              0x00000000
+/** \brief Horizontal Mirroring. */
+#define VA_MIRROR_HORIZONTAL        0x00000001
+/** \brief Vertical Mirroring. */
+#define VA_MIRROR_VERTICAL          0x00000002
+/**@}*/
 
 /* attribute value for VADisplayAttribOutOfLoopDeblock */
 #define VA_OOL_DEBLOCKING_FALSE 0x00000000
diff --git a/va/va_android.h b/va/va_android.h
index f59af86..978becd 100644
--- a/va/va_android.h
+++ b/va/va_android.h
@@ -1,8 +1,36 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
 #ifndef _VA_ANDROID_H_
 #define _VA_ANDROID_H_
 
 #include <va/va.h>
 
+/** \brief Android Gralloc buffer memory type. */
+#define VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC	0x00100000
+/** \brief Android ION buffer memory type. */
+#define VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION		0x00200000
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -20,7 +48,8 @@
 
 #ifdef __cplusplus
 #ifdef ANDROID
-#include <gui/Surface.h>
+#include <system/window.h>
+#include <utils/StrongPointer.h>
 using namespace android;
 
 /*
@@ -33,8 +62,8 @@
  */
 VAStatus vaPutSurface (
     VADisplay dpy,
-    VASurfaceID surface,	
-    sp<ISurface> draw, /* Android Window/Surface */
+    VASurfaceID surface,
+    sp<ANativeWindow> draw, /* Android Native Window */
     short srcx,
     short srcy,
     unsigned short srcw,
diff --git a/va/va_backend.h b/va/va_backend.h
index c92be53..61b9d3a 100755
--- a/va/va_backend.h
+++ b/va/va_backend.h
@@ -30,14 +30,27 @@
 #define _VA_BACKEND_H_
 
 #include <va/va.h>
-#ifndef ANDROID
-#include <X11/Xlib.h>
-#endif
-#include <linux/videodev2.h>
 
 typedef struct VADriverContext *VADriverContextP;
 typedef struct VADisplayContext *VADisplayContextP;
 
+/** \brief VA display types. */
+enum {
+    /** \brief Mask to major identifier for VA display type. */
+    VA_DISPLAY_MAJOR_MASK = 0xf0,
+
+    /** \brief VA/X11 API is used, through vaGetDisplay() entry-point. */
+    VA_DISPLAY_X11      = 0x10,
+    /** \brief VA/GLX API is used, through vaGetDisplayGLX() entry-point. */
+    VA_DISPLAY_GLX      = (VA_DISPLAY_X11 | (1 << 0)),
+    /** \brief VA/Android API is used, through vaGetDisplay() entry-point. */
+    VA_DISPLAY_ANDROID  = 0x20,
+    /** \brief VA/DRM API is used, through vaGetDisplayDRM() entry-point. */
+    VA_DISPLAY_DRM      = 0x30,
+    /** \brief VA/Wayland API is used, through vaGetDisplayWl() entry-point. */
+    VA_DISPLAY_WAYLAND  = 0x40,
+};
+
 struct VADriverVTable
 {
 	VAStatus (*vaTerminate) ( VADriverContextP ctx );
@@ -378,9 +391,10 @@
                 VASurfaceID surface
         );
 
+        /* DEPRECATED */
         VAStatus
         (*vaGetSurfaceAttributes)(
-            VADriverContextP    dpy,
+            VADriverContextP    ctx,
             VAConfigID          config,
             VASurfaceAttrib    *attrib_list,
             unsigned int        num_attribs
@@ -397,6 +411,14 @@
             VASurfaceAttrib    *attrib_list,
             unsigned int        num_attribs
         );
+
+        VAStatus
+        (*vaQuerySurfaceAttributes)(
+            VADriverContextP    dpy,
+            VAConfigID          config,
+            VASurfaceAttrib    *attrib_list,
+            unsigned int       *num_attribs
+        );
 };
 
 struct VADriverContext
@@ -450,8 +472,21 @@
     const char *str_vendor;
 
     void *handle;			/* dlopen handle */
-    
-    void *dri_state;
+
+    /**
+     * \brief DRM state.
+     *
+     * This field holds driver specific data for DRM-based
+     * drivers. This structure is allocated from libva with
+     * calloc(). Do not deallocate from within VA driver
+     * implementations.
+     *
+     * All structures shall be derived from struct drm_state. So, for
+     * instance, this field holds a dri_state structure for VA/X11
+     * drivers that use the DRM protocol.
+     */
+    void *drm_state;
+
     void *glx;				/* opaque for GLX code */
 
     /**
@@ -461,7 +496,19 @@
      */
     struct VADriverVTableVPP *vtable_vpp;
 
-    unsigned long reserved[44];         /* reserve for future add-ins, decrease the subscript accordingly */
+    /** \brief VA display type. */
+    unsigned long display_type;
+
+    /**
+     * The VA/Wayland implementation hooks.
+     *
+     * This structure is intended for drivers that implement the
+     * VA/Wayland API. libVA allocates this structure with calloc()
+     * and owns the resulting memory.
+     */
+    struct VADriverVTableWayland *vtable_wayland;
+
+    unsigned long reserved[42];         /* reserve for future add-ins, decrease the subscript accordingly */
 };
 
 #define VA_DISPLAY_MAGIC 0x56414430 /* VAD0 */
@@ -486,6 +533,8 @@
     );
 
     void *opaque; /* opaque for display extensions (e.g. GLX) */
+    void *vatrace; /* opaque for VA trace context */
+    void *vafool; /* opaque for VA fool context */
 };
 
 typedef VAStatus (*VADriverInit) (
diff --git a/va/va_backend_tpi.h b/va/va_backend_tpi.h
index b96a37e..6b1c85a 100644
--- a/va/va_backend_tpi.h
+++ b/va/va_backend_tpi.h
@@ -36,7 +36,7 @@
 struct VADriverVTableTPI
 {
     VAStatus (*vaCreateSurfacesWithAttribute) (
-        VADisplay dpy,
+        VADriverContextP ctx,
         int width,
         int height,
         int format,
@@ -44,7 +44,7 @@
         VASurfaceID *surfaces,       /* out */
         VASurfaceAttributeTPI *attribute_tpi
         );
-    
+
     VAStatus (*vaPutSurfaceBuf) (
         VADriverContextP ctx,
         VASurfaceID surface,
@@ -64,7 +64,7 @@
         );
 
     VAStatus (*vaSetTimestampForSurface)(
-        VADisplay dpy,
+        VADriverContextP ctx,
         VASurfaceID surface,
         long long timestamp
         );
diff --git a/va/va_dec_hevc.h b/va/va_dec_hevc.h
new file mode 100644
index 0000000..95cf676
--- /dev/null
+++ b/va/va_dec_hevc.h
@@ -0,0 +1,501 @@
+/*
+ * Copyright (c) 2014 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file va_dec_hevc.h
+ * \brief The HEVC decoding API
+ *
+ * This file contains the \ref api_dec_hevc "HEVC decoding API".
+ */
+
+#ifndef VA_DEC_HEVC_H
+#define VA_DEC_HEVC_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup api_dec_hevc HEVC decoding API
+ *
+ * This HEVC decoding API supports Main and Main Still Picture profiles.
+ * And it supports both short slice format and long slice format.
+ *
+ * @{
+ */
+
+
+
+/****************************
+ * HEVC data structures
+ ****************************/
+
+/**
+ * \brief Description of picture properties of those in DPB surfaces.
+ *
+ * If only progressive scan is supported, each surface contains one whole
+ * frame picture.
+ * Otherwise, each surface contains two fields of whole picture.
+ * In this case, two entries of ReferenceFrames[] may share same picture_id
+ * value.
+ */
+typedef struct _VAPictureHEVC
+{
+    /** \brief reconstructed picture buffer surface index
+     * invalid when taking value VA_INVALID_SURFACE.
+     */
+    VASurfaceID             picture_id;
+    /** \brief picture order count.
+     * in HEVC, POCs for top and bottom fields of same picture should
+     * take different values.
+     */
+    int32_t                 PicOrderCnt;
+    /* described below */
+    uint32_t                flags;
+} VAPictureHEVC;
+
+/** flags in VAPictureHEVC could be OR of the following */
+#define VA_PICTURE_HEVC_INVALID                 0x00000001
+/** \brief indication of interlace scan picture.
+ * should take same value for all the pictures in sequence.
+ */
+#define VA_PICTURE_HEVC_FIELD_PIC               0x00000002
+/** \brief polarity of the field picture.
+ * top field takes even lines of buffer surface.
+ * bottom field takes odd lines of buffer surface.
+ */
+#define VA_PICTURE_HEVC_BOTTOM_FIELD            0x00000004
+/** \brief Long term reference picture */
+#define VA_PICTURE_HEVC_LONG_TERM_REFERENCE     0x00000008
+/** \brief RefPicSetStCurrBefore of HEVC spec variable
+ * Number of ReferenceFrames[] entries with this bit set equals
+ * NumPocStCurrBefore.
+ */
+#define VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE      0x00000010
+/** \brief RefPicSetStCurrAfter of HEVC spec variable
+ * Number of ReferenceFrames[] entries with this bit set equals
+ * NumPocStCurrAfter.
+ */
+#define VA_PICTURE_HEVC_RPS_ST_CURR_AFTER       0x00000020
+/** \brief RefPicSetLtCurr of HEVC spec variable
+ * Number of ReferenceFrames[] entries with this bit set equals
+ * NumPocLtCurr.
+ */
+#define VA_PICTURE_HEVC_RPS_LT_CURR             0x00000040
+/**
+ * VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE, VA_PICTURE_HEVC_RPS_ST_CURR_AFTER
+ * and VA_PICTURE_HEVC_RPS_LT_CURR of any picture in ReferenceFrames[] should
+ * be exclusive. No more than one of them can be set for any picture.
+ * Sum of NumPocStCurrBefore, NumPocStCurrAfter and NumPocLtCurr
+ * equals NumPocTotalCurr, which should be equal to or smaller than 8.
+ * Application should provide valid values for both short format and long format.
+ * The pictures in DPB with any of these three flags turned on are referred by
+ * the current picture.
+ */
+
+
+
+
+
+/**
+ * \brief HEVC Decoding Picture Parameter Buffer Structure
+ *
+ * This structure conveys picture level parameters and should be sent once
+ * per frame.
+ *
+ */
+typedef struct  _VADecPictureParameterBufferHEVC
+{
+    /** \brief buffer description of decoded current picture
+     * only VA_PICTURE_HEVC_FIELD_PIC and VA_PICTURE_HEVC_BOTTOM_FIELD
+     * of "flags" fields are meaningful.
+     */
+    VAPictureHEVC           CurrPic;
+    /** \brief buffer description of reference frames in DPB */
+    VAPictureHEVC           ReferenceFrames[15];
+    /** \brief picture width, shall be integer multiple of minimum CB size. */
+    uint16_t                pic_width_in_luma_samples;
+    /** \brief picture height, shall be integer multiple of minimum CB size. */
+    uint16_t                pic_height_in_luma_samples;
+
+
+    union
+    {
+        struct
+        {
+        /** following flags have same syntax and semantic as those in HEVC spec */
+            uint32_t        chroma_format_idc                           : 2;
+            uint32_t        separate_colour_plane_flag                  : 1;
+            uint32_t        pcm_enabled_flag                            : 1;
+            uint32_t        scaling_list_enabled_flag                   : 1;
+            uint32_t        transform_skip_enabled_flag                 : 1;
+            uint32_t        amp_enabled_flag                            : 1;
+            uint32_t        strong_intra_smoothing_enabled_flag         : 1;
+            uint32_t        sign_data_hiding_enabled_flag               : 1;
+            uint32_t        constrained_intra_pred_flag                 : 1;
+            uint32_t        cu_qp_delta_enabled_flag                    : 1;
+            uint32_t        weighted_pred_flag                          : 1;
+            uint32_t        weighted_bipred_flag                        : 1;
+            uint32_t        transquant_bypass_enabled_flag              : 1;
+            uint32_t        tiles_enabled_flag                          : 1;
+            uint32_t        entropy_coding_sync_enabled_flag            : 1;
+            uint32_t        pps_loop_filter_across_slices_enabled_flag  : 1;
+            uint32_t        loop_filter_across_tiles_enabled_flag       : 1;
+            uint32_t        pcm_loop_filter_disabled_flag               : 1;
+            /** set based on sps_max_num_reorder_pics of current temporal layer. */
+            uint32_t        NoPicReorderingFlag                         : 1;
+            /** picture has no B slices */
+            uint32_t        NoBiPredFlag                                : 1;
+
+            uint32_t        ReservedBits                                : 11;
+        } bits;
+        uint32_t            value;
+    } pic_fields;
+
+    /** following parameters have same syntax with those in HEVC spec */
+    /** \brief DPB size for current temporal layer */
+    uint8_t                 sps_max_dec_pic_buffering_minus1;
+    uint8_t                 bit_depth_luma_minus8;
+    uint8_t                 bit_depth_chroma_minus8;
+    uint8_t                 pcm_sample_bit_depth_luma_minus1;
+    uint8_t                 pcm_sample_bit_depth_chroma_minus1;
+    uint8_t                 log2_min_luma_coding_block_size_minus3;
+    uint8_t                 log2_diff_max_min_luma_coding_block_size;
+    uint8_t                 log2_min_transform_block_size_minus2;
+    uint8_t                 log2_diff_max_min_transform_block_size;
+    uint8_t                 log2_min_pcm_luma_coding_block_size_minus3;
+    uint8_t                 log2_diff_max_min_pcm_luma_coding_block_size;
+    uint8_t                 max_transform_hierarchy_depth_intra;
+    uint8_t                 max_transform_hierarchy_depth_inter;
+    int8_t                  init_qp_minus26;
+    uint8_t                 diff_cu_qp_delta_depth;
+    int8_t                  pps_cb_qp_offset;
+    int8_t                  pps_cr_qp_offset;
+    uint8_t                 log2_parallel_merge_level_minus2;
+    uint8_t                 num_tile_columns_minus1;
+    uint8_t                 num_tile_rows_minus1;
+    /**
+     * when uniform_spacing_flag equals 1, application should populate
+     * column_width_minus[], and row_height_minus1[] with approperiate values.
+     */
+    uint16_t                column_width_minus1[19];
+    uint16_t                row_height_minus1[21];
+
+    /**
+     *  The Following Parameters are needed for Short Slice Format Only.
+     *  Only format decoding can ignore them.
+     */
+
+    /**
+     * \brief Parameters needed for parsing slice segment headers
+     */
+    union
+    {
+        struct
+        {
+            /** following parameters have same syntax with those in HEVC spec */
+            uint32_t        lists_modification_present_flag             : 1;
+            uint32_t        long_term_ref_pics_present_flag             : 1;
+            uint32_t        sps_temporal_mvp_enabled_flag               : 1;
+            uint32_t        cabac_init_present_flag                     : 1;
+            uint32_t        output_flag_present_flag                    : 1;
+            uint32_t        dependent_slice_segments_enabled_flag       : 1;
+            uint32_t        pps_slice_chroma_qp_offsets_present_flag    : 1;
+            uint32_t        sample_adaptive_offset_enabled_flag         : 1;
+            uint32_t        deblocking_filter_override_enabled_flag     : 1;
+            uint32_t        pps_disable_deblocking_filter_flag          : 1;
+            uint32_t        slice_segment_header_extension_present_flag : 1;
+
+            /** current picture with NUT between 16 and 21 inclusive */
+            uint32_t        RapPicFlag                                  : 1;
+            /** current picture with NUT between 19 and 20 inclusive */
+            uint32_t        IdrPicFlag                                  : 1;
+            /** current picture has only intra slices */
+            uint32_t        IntraPicFlag                                : 1;
+
+            uint32_t        ReservedBits                                : 18;
+        } bits;
+        uint32_t            value;
+    } slice_parsing_fields;
+
+    /** following parameters have same syntax with those in HEVC spec */
+    uint8_t                 log2_max_pic_order_cnt_lsb_minus4;
+    uint8_t                 num_short_term_ref_pic_sets;
+    uint8_t                 num_long_term_ref_pic_sps;
+    uint8_t                 num_ref_idx_l0_default_active_minus1;
+    uint8_t                 num_ref_idx_l1_default_active_minus1;
+    int8_t                  pps_beta_offset_div2;
+    int8_t                  pps_tc_offset_div2;
+    uint8_t                 num_extra_slice_header_bits;
+
+    /**
+     * \brief number of bits that structure
+     * short_term_ref_pic_set( num_short_term_ref_pic_sets ) takes in slice
+     * segment header when short_term_ref_pic_set_sps_flag equals 0.
+     * if short_term_ref_pic_set_sps_flag equals 1, the value should be 0.
+     * the bit count is calculated after emulation prevention bytes are removed
+     * from bit streams.
+     * This variable is used for accelorater to skip parsing the
+     * short_term_ref_pic_set( num_short_term_ref_pic_sets ) structure.
+     */
+    uint32_t                st_rps_bits;
+
+} VADecPictureParameterBufferHEVC;
+
+
+
+/**
+ * \brief HEVC Slice Parameter Buffer Structure For Short Format
+ *
+ * VASliceParameterBufferBaseHEVC structure should be accompanied by a
+ * slice data buffer, which holds the whole raw slice NAL unit bit streams
+ * including start code prefix and emulation prevention bytes not removed.
+ *
+ * This structure conveys parameters related to slice segment header and should
+ * be sent once per slice.
+ *
+ * For long format, this data structure is not sent by application.
+ *
+ */
+typedef struct  _VASliceParameterBufferBaseHEVC
+{
+    /** @name Codec-independent Slice Parameter Buffer base. */
+
+    /**@{*/
+
+    /** \brief Number of bytes in the slice data buffer for this slice
+     *  counting from and including NAL unit header.
+     */
+    uint32_t                slice_data_size;
+    /** \brief The offset to the NAL unit header for this slice */
+    uint32_t                slice_data_offset;
+    /** \brief Slice data buffer flags. See \c VA_SLICE_DATA_FLAG_XXX. */
+    uint16_t                slice_data_flag;
+    /**@}*/
+
+} VASliceParameterBufferBaseHEVC;
+
+
+
+
+/**
+ * \brief HEVC Slice Parameter Buffer Structure For Long Format
+ *
+ * VASliceParameterBufferHEVC structure should be accompanied by a
+ * slice data buffer, which holds the whole raw slice NAL unit bit streams
+ * including start code prefix and emulation prevention bytes not removed.
+ *
+ * This structure conveys parameters related to slice segment header and should
+ * be sent once per slice.
+ *
+ * For short format, this data structure is not sent by application.
+ *
+ */
+typedef struct  _VASliceParameterBufferHEVC
+{
+    /** @name Codec-independent Slice Parameter Buffer base. */
+
+    /**@{*/
+
+    /** \brief Number of bytes in the slice data buffer for this slice
+     * counting from and including NAL unit header.
+     */
+    uint32_t                slice_data_size;
+    /** \brief The offset to the NAL unit header for this slice */
+    uint32_t                slice_data_offset;
+    /** \brief Slice data buffer flags. See \c VA_SLICE_DATA_FLAG_XXX. */
+    uint16_t                slice_data_flag;
+    /**
+     * \brief Byte offset from NAL unit header to the begining of slice_data().
+     *
+     * This byte offset is relative to and includes the NAL unit header
+     * and represents the number of bytes parsed in the slice_header()
+     * after the removal of any emulation prevention bytes in
+     * there. However, the slice data buffer passed to the hardware is
+     * the original bitstream, thus including any emulation prevention
+     * bytes.
+     * The slice bit stream may or may not include the start code prefix.
+     */
+    uint32_t                slice_data_byte_offset;
+    /** HEVC syntax element. */
+    uint32_t                slice_segment_address;
+    /** \brief index into ReferenceFrames[]
+     * RefPicList[0][] corresponds to RefPicList0[] of HEVC variable.
+     * RefPicList[1][] corresponds to RefPicList1[] of HEVC variable.
+     * value range [0..14, 0xFF], where 0xFF indicates invalid entry.
+     */
+    uint8_t                 RefPicList[2][15];
+    union
+    {
+        uint32_t            value;
+        struct
+        {
+            /** current slice is last slice of picture. */
+            uint32_t        LastSliceOfPic                              : 1;
+    /** HEVC syntax element. */
+            uint32_t        dependent_slice_segment_flag                : 1;
+    /** HEVC syntax element. */
+            uint32_t        slice_type                                  : 2;
+    /** HEVC syntax element. */
+            uint32_t        color_plane_id                              : 2;
+    /** HEVC syntax element. */
+            uint32_t        slice_sao_luma_flag                         : 1;
+    /** HEVC syntax element. */
+            uint32_t        slice_sao_chroma_flag                       : 1;
+    /** HEVC syntax element. */
+            uint32_t        mvd_l1_zero_flag                            : 1;
+    /** HEVC syntax element. */
+            uint32_t        cabac_init_flag                             : 1;
+    /** HEVC syntax element. */
+            uint32_t        slice_temporal_mvp_enabled_flag             : 1;
+    /** HEVC syntax element. */
+            uint32_t        slice_deblocking_filter_disabled_flag       : 1;
+    /** HEVC syntax element. */
+            uint32_t        collocated_from_l0_flag                     : 1;
+    /** HEVC syntax element. */
+            uint32_t        slice_loop_filter_across_slices_enabled_flag : 1;
+            uint32_t        reserved                                    : 18;
+        } fields;
+    } LongSliceFlags;
+
+    /** HEVC syntax element. Collocated Reference Picture Index.
+     * index to RefPicList[0][] or RefPicList[1][].
+     * when slice_temporal_mvp_enabled_flag equals 0, it should take value 0xFF.
+     * value range [0..14, 0xFF].
+     */
+    uint8_t                 collocated_ref_idx;
+    /** HEVC syntax element.
+     * if num_ref_idx_active_override_flag equals 0, host decoder should
+     * set its value to num_ref_idx_l0_default_minus1.
+     */
+    uint8_t                 num_ref_idx_l0_active_minus1;
+    /** HEVC syntax element.
+     * if num_ref_idx_active_override_flag equals 0, host decoder should
+     * set its value to num_ref_idx_l1_default_minus1.
+     */
+    uint8_t                 num_ref_idx_l1_active_minus1;
+    /** HEVC syntax element. */
+    int8_t                  slice_qp_delta;
+    /** HEVC syntax element. */
+    int8_t                  slice_cb_qp_offset;
+    /** HEVC syntax element. */
+    int8_t                  slice_cr_qp_offset;
+    /** HEVC syntax element. */
+    int8_t                  slice_beta_offset_div2;
+    /** HEVC syntax element. */
+    int8_t                  slice_tc_offset_div2;
+    /** HEVC syntax element. */
+    uint8_t                 luma_log2_weight_denom;
+    /** HEVC syntax element. */
+    uint8_t                 delta_chroma_log2_weight_denom;
+    /** HEVC syntax element. */
+    int8_t                  delta_luma_weight_l0[15];
+    /** HEVC syntax element. */
+    int8_t                  luma_offset_l0[15];
+    /** HEVC syntax element. */
+    int8_t                  delta_chroma_weight_l0[15][2];
+    /** corresponds to HEVC spec variable of the same name. */
+    int8_t                  ChromaOffsetL0[15][2];
+    /** HEVC syntax element. */
+    int8_t                  delta_luma_weight_l1[15];
+    /** HEVC syntax element. */
+    int8_t                  luma_offset_l1[15];
+    /** HEVC syntax element. */
+    int8_t                  delta_chroma_weight_l1[15][2];
+    /** corresponds to HEVC spec variable of the same name. */
+    int8_t                  ChromaOffsetL1[15][2];
+    /** HEVC syntax element. */
+    uint8_t                 five_minus_max_num_merge_cand;
+    /**@}*/
+
+} VASliceParameterBufferHEVC;
+
+
+
+/**
+ * \brief HEVC Inverse Quantization Matrix Buffer Structure
+ *
+ * This structure is sent once per frame,
+ * and only when scaling_list_enabled_flag = 1.
+ * When sps_scaling_list_data_present_flag = 0, app still
+ * needs to send in this structure with default matrix values.
+ *
+ * Matrix entries are in raster scan order which follows HEVC spec.
+ */
+typedef struct _VAIQMatrixBufferHEVC
+{
+    /**
+     * \brief scaling lists,
+     * corresponds to same HEVC spec syntax element
+     * ScalingList[ i ][ MatrixID ][ j ].
+     *
+     * \brief 4x4 scaling,
+     * correspongs i = 0, MatrixID is in the range of 0 to 5,
+     * inclusive. And j is in the range of 0 to 15, inclusive.
+     */
+    uint8_t                 ScalingList4x4[6][16];
+    /**
+     * \brief 8x8 scaling,
+     * correspongs i = 1, MatrixID is in the range of 0 to 5,
+     * inclusive. And j is in the range of 0 to 63, inclusive.
+     */
+    uint8_t                 ScalingList8x8[6][64];
+    /**
+     * \brief 16x16 scaling,
+     * correspongs i = 2, MatrixID is in the range of 0 to 5,
+     * inclusive. And j is in the range of 0 to 63, inclusive.
+     */
+    uint8_t                 ScalingList16x16[6][64];
+    /**
+     * \brief 32x32 scaling,
+     * correspongs i = 3, MatrixID is in the range of 0 to 1,
+     * inclusive. And j is in the range of 0 to 63, inclusive.
+     */
+    uint8_t                 ScalingList32x32[2][64];
+    /**
+     * \brief DC values of the 16x16 scaling lists,
+     * corresponds to HEVC spec syntax
+     * scaling_list_dc_coef_minus8[ sizeID - 2 ][ matrixID ] + 8
+     * with sizeID = 2 and matrixID in the range of 0 to 5, inclusive.
+     */
+    uint8_t                 ScalingListDC16x16[6];
+    /**
+     * \brief DC values of the 32x32 scaling lists,
+     * corresponds to HEVC spec syntax
+     * scaling_list_dc_coef_minus8[ sizeID - 2 ][ matrixID ] + 8
+     * with sizeID = 3 and matrixID in the range of 0 to 1, inclusive.
+     */
+    uint8_t                 ScalingListDC32x32[2];
+} VAIQMatrixBufferHEVC;
+
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_DEC_HEVC_H */
diff --git a/va/va_dec_jpeg.h b/va/va_dec_jpeg.h
index 53f1769..685e3ff 100644
--- a/va/va_dec_jpeg.h
+++ b/va/va_dec_jpeg.h
@@ -36,12 +36,12 @@
 extern "C" {
 #endif
 
-#include <va/va_enc.h>
+#include <va/va.h>
 
 /**
  * \defgroup api_dec_jpeg JPEG decoding API
  *
- * WIP: this is work-in-progress API subject to change.
+ * This JPEG decoding API supports Baseline profile only.
  *
  * @{
  */
@@ -52,13 +52,11 @@
  * This structure holds information from the frame header, along with
  * definitions from additional segments.
  */
-typedef struct _VAPictureParameterBufferJPEG {
+typedef struct _VAPictureParameterBufferJPEGBaseline {
     /** \brief Picture width in pixels. */
     unsigned short      picture_width;
     /** \brief Picture height in pixels. */
     unsigned short      picture_height;
-    /** \brief Sample precision (P). */
-    unsigned char       sample_precision;
 
     struct {
         /** \brief Component identifier (Ci). */
@@ -72,19 +70,11 @@
     }                   components[255];
     /** \brief Number of components in frame (Nf). */
     unsigned char       num_components;
-
-    /** @name Cropping (JPEG-2000) */
-    /**@{*/
-    unsigned char   frame_cropping_flag;
-    unsigned short  frame_crop_left_offset;
-    unsigned short  frame_crop_right_offset;
-    unsigned short  frame_crop_top_offset;
-    unsigned short  frame_crop_bottom_offset;
-    /**@}*/
-
-    /** \brief Rotation (JPEG-2000). See \c VA_ROTATION_xxx. */
-    unsigned int        rotation;
-} VAPictureParameterBufferJPEG;
+    /** \brief Input color space 0: YUV, 1: RGB, 2: BGR, others: reserved */
+    unsigned char       color_space;
+    /** \brief Set to VA_ROTATION_* for a single rotation angle reported by VAConfigAttribDecJPEG. */
+    unsigned int 	rotation;
+} VAPictureParameterBufferJPEGBaseline;
 
 /**
  * \brief Quantization table for JPEG decoding.
@@ -97,16 +87,13 @@
  * The #load_quantization_table array can be used as a hint to notify
  * the VA driver implementation about which table(s) actually changed
  * since the last submission of this buffer.
- *
- * WIP: this is work-in-progress API subject to change, and only
- * suitable to Baseline profile.
  */
-typedef struct _VAIQMatrixParameterBufferJPEG {
+typedef struct _VAIQMatrixBufferJPEGBaseline {
     /** \brief Specifies which #quantiser_table is valid. */
     unsigned char       load_quantiser_table[4];
     /** \brief Quanziation tables indexed by table identifier (Tqi). */
     unsigned char       quantiser_table[4][64];
-} VAIQMatrixParameterBufferJPEG;
+} VAIQMatrixBufferJPEGBaseline;
 
 /**
  * \brief Huffman table for JPEG decoding.
@@ -119,11 +106,8 @@
  * The #load_huffman_table array can be used as a hint to notify the
  * VA driver implementation about which table(s) actually changed
  * since the last submission of this buffer.
- *
- * WIP: this is work-in-progress API subject to change, and only
- * suitable to Baseline profile.
  */
-typedef struct _VAHuffmanTableParameterBufferJPEG {
+typedef struct _VAHuffmanTableBufferJPEGBaseline {
     /** \brief Specifies which #huffman_table is valid. */
     unsigned char       load_huffman_table[2];
     /** \brief Huffman tables indexed by table identifier (Th). */
@@ -141,9 +125,11 @@
         unsigned char   num_ac_codes[16];
         /** \brief Value associated with each Huffman code (Vij). */
         unsigned char   ac_values[162];
+        /** \brief Padding to 4-byte boundaries. Must be set to zero. */
+        unsigned char   pad[2];
         /**@}*/
     }                   huffman_table[2];
-} VAHuffmanTableParameterBufferJPEG;
+} VAHuffmanTableBufferJPEGBaseline;
 
 /**
  * \brief Slice parameter for JPEG decoding.
@@ -152,7 +138,7 @@
  * definitions from additional segments. The associated slice data
  * buffer holds all entropy coded segments (ECS) in the scan.
  */
-typedef struct _VASliceParameterBufferJPEG {
+typedef struct _VASliceParameterBufferJPEGBaseline {
     /** @name Codec-independent Slice Parameter Buffer base. */
     /**@{*/
     /** \brief Number of bytes in the slice data buffer for this slice. */
@@ -183,7 +169,7 @@
     unsigned short      restart_interval;
     /** \brief Number of MCUs in a scan. */
     unsigned int        num_mcus;
-} VASliceParameterBufferJPEG;
+} VASliceParameterBufferJPEGBaseline;
 
 /**@}*/
 
diff --git a/va/va_dec_vp8.h b/va/va_dec_vp8.h
index 66b866b..32830cb 100644
--- a/va/va_dec_vp8.h
+++ b/va/va_dec_vp8.h
@@ -43,7 +43,7 @@
  */
 
 /**
- * \brief VPX Bool Coder Context structure
+ * \brief VPX Bool Coder Context structure 
  *
  * This common structure is defined for potential sharing by other VP formats
  *
@@ -51,11 +51,15 @@
 typedef struct _VABoolCoderContextVPX
 {
     /* partition 0 "range" */
-    unsigned short range;
+    unsigned char range;
     /* partition 0 "value" */
-    unsigned int value;
-    /* partition 0 number of shifts before an output byte is available */
-    unsigned short count;
+    unsigned char value;
+    /*
+     * 'partition 0 number of shifts before an output byte is available'
+     * it is the number of remaining bits in 'value' for decoding, range [0, 7].
+     */
+
+    unsigned char count;
 } VABoolCoderContextVPX;
 
 /**
@@ -83,8 +87,8 @@
 
     union {
         struct {
-	    /* same as key_frame in bitstream syntax */
-            unsigned int key_frame			: 1;
+	    /* same as key_frame in bitstream syntax, 0 means a key frame */
+            unsigned int key_frame			: 1; 
 	    /* same as version in bitstream syntax */
             unsigned int version			: 3;
 	    /* same as segmentation_enabled in bitstream syntax */
@@ -94,29 +98,27 @@
 	    /* same as update_segment_feature_data in bitstream syntax */
             unsigned int update_segment_feature_data	: 1;
 	    /* same as filter_type in bitstream syntax */
-            unsigned int filter_type			: 1;
+            unsigned int filter_type			: 1; 
 	    /* same as sharpness_level in bitstream syntax */
-            unsigned int sharpness_level		: 3;
+            unsigned int sharpness_level		: 3; 
 	    /* same as loop_filter_adj_enable in bitstream syntax */
-            unsigned int loop_filter_adj_enable		: 1;
+            unsigned int loop_filter_adj_enable		: 1; 
 	    /* same as mode_ref_lf_delta_update in bitstream syntax */
-            unsigned int mode_ref_lf_delta_update	: 1;
+            unsigned int mode_ref_lf_delta_update	: 1; 
 	    /* same as sign_bias_golden in bitstream syntax */
-            unsigned int sign_bias_golden		: 1;
+            unsigned int sign_bias_golden		: 1; 
 	    /* same as sign_bias_alternate in bitstream syntax */
-            unsigned int sign_bias_alternate		: 1;
+            unsigned int sign_bias_alternate		: 1; 
 	    /* same as mb_no_coeff_skip in bitstream syntax */
-            unsigned int mb_no_coeff_skip		: 1;
-	    /* see section 11.1 for mb_skip_coeff */
-            unsigned int mb_skip_coeff			: 1;
+            unsigned int mb_no_coeff_skip		: 1; 
 	    /* flag to indicate that loop filter should be disabled */
-            unsigned int loop_filter_disable		: 1;
+            unsigned int loop_filter_disable		: 1; 
         } bits;
         unsigned int value;
     } pic_fields;
 
     /*
-     * probabilities of the segment_id decoding tree and same as
+     * probabilities of the segment_id decoding tree and same as 
      * mb_segment_tree_probs in the spec.
      */
     unsigned char mb_segment_tree_probs[3];
@@ -137,46 +139,77 @@
     /* same as prob_gf in bitstream syntax */
     unsigned char prob_gf;
 
-    /*
+    /* 
      * list of 4 probabilities of the luma intra prediction mode decoding
      * tree and same as y_mode_probs in frame header
      */
-    unsigned char y_mode_probs[4];
+    unsigned char y_mode_probs[4]; 
     /*
      * list of 3 probabilities of the chroma intra prediction mode decoding
      * tree and same as uv_mode_probs in frame header
      */
     unsigned char uv_mode_probs[3];
-    /*
-     * updated mv decoding probabilities and same as mv_probs in
+    /* 
+     * updated mv decoding probabilities and same as mv_probs in 
      * frame header
      */
     unsigned char mv_probs[2][19];
 
     VABoolCoderContextVPX bool_coder_ctx;
 
-    /* Partitions */
-    unsigned char num_of_partitions;
-    unsigned int partition_size[9];
+} VAPictureParameterBufferVP8;
 
+/**
+ * \brief VP8 Slice Parameter Buffer Structure
+ *
+ * This structure conveys parameters related to data partitions and should be 
+ * sent once per frame. Slice data buffer of VASliceDataBufferType is used
+ * to send the partition data.
+ *
+ */
+typedef struct  _VASliceParameterBufferVP8
+{
     /*
-     * offset to the first bit of MB from the first byte of slice data buffer
+     * number of bytes in the slice data buffer for the partitions 
+     */
+    unsigned int slice_data_size;
+    /*
+     * offset to the first byte of partition data (control partition)
+     */
+    unsigned int slice_data_offset;
+    /*
+     * see VA_SLICE_DATA_FLAG_XXX definitions
+     */
+    unsigned int slice_data_flag; 
+    /*
+     * offset to the first bit of MB from the first byte of partition data(slice_data_offset)
      */
     unsigned int macroblock_offset;
 
-} VAPictureParameterBufferVP8;
+    /*
+     * Partitions
+     * (1<<log2_nbr_of_dct_partitions)+1, count both control partition (frame header) and toke partition
+     */
+    unsigned char num_of_partitions;
+    /*
+     * partition_size[0] is remaining bytes of control partition after parsed by application.
+     * exclude current byte for the remaining bits in bool_coder_ctx.
+     * exclude the uncompress data chunk since first_part_size 'excluding the uncompressed data chunk'
+     */
+    unsigned int partition_size[9];
+} VASliceParameterBufferVP8;
 
 /**
  * \brief VP8 Coefficient Probability Data Buffer Structure
  *
- * Contains the contents of the token probability table, which may be
- * incrementally modified in the frame header. There are four dimensions to
- * the token probability array. The outermost dimension is indexed by the
- * type of plane being decoded; the next dimension is selected by the
- * position of the coefficient being decoded; the third dimension, * roughly
- * speaking, measures the "local complexity" or extent to which nearby
- * coefficients are non-zero; the fourth, and final, dimension of the token
- * probability array is indexed by the position in the token tree structure,
+ * Contains the contents of the token probability table, which may be 
+ * incrementally modified in the frame header. There are four dimensions to 
+ * the token probability array. The outermost dimension is indexed by the 
+ * type of plane being decoded; the next dimension is selected by the 
+ * position of the coefficient being decoded; the third dimension, * roughly 
+ * speaking, measures the "local complexity" or extent to which nearby 
+ * coefficients are non-zero; the fourth, and final, dimension of the token 
+ * probability array is indexed by the position in the token tree structure, 
  * as are all tree probability arrays. This structure is sent once per frame.
  *
  */
@@ -189,13 +222,14 @@
  * \brief VP8 Inverse Quantization Matrix Buffer Structure
  *
  * Contains quantization indices for yac(0),ydc(1),y2dc(2),y2ac(3),uvdc(4),
- * uvac(5) for each segment (0-3). When segmentation is disabled, only
+ * uvac(5) for each segment (0-3). When segmentation is disabled, only  
  * quantization_index[0][] will be used. This structure is sent once per frame.
  */
 typedef struct _VAIQMatrixBufferVP8
 {
-    /*
+    /* 
      * array first dimensional is segment and 2nd dimensional is Q index
+     * all Q indexs should be clipped to be range [0, 127]
      */
     unsigned short quantization_index[4][6];
 } VAIQMatrixBufferVP8;
diff --git a/va/va_dec_vp9.h b/va/va_dec_vp9.h
new file mode 100755
index 0000000..5503be6
--- /dev/null
+++ b/va/va_dec_vp9.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2007-2014 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file va_dec_vp9.h
+ * \brief The VP9 decoding API
+ *
+ * This file contains the \ref api_dec_vp9 "VP9 decoding API".
+ */
+
+#ifndef VA_DEC_VP9_H
+#define VA_DEC_VP9_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup api_dec_vp9 VP9 decoding API
+ *
+ * This VP9 decoding API supports 8-bit 420 format only.
+ *
+ * @{
+ */
+
+
+
+
+/**
+ * \brief VP9 Decoding Picture Parameter Buffer Structure
+ *
+ * This structure conveys picture level parameters.
+ * App should send a surface with this data structure down to VAAPI once
+ * per frame.
+ *
+ */
+typedef struct  _VADecPictureParameterBufferVP9
+{
+    /**@{*/
+
+    /** \brief picture width
+     *  The value must be multiple of 8.
+     */
+    uint16_t                frame_width;
+    /** \brief picture height
+     *  The value must be multiple of 8.
+     */
+    uint16_t                frame_height;
+
+    /** \brief Surface index of decoded current picture
+     */
+    VASurfaceID             curr_pic;
+    /** \brief Surface indices of reference frames in DPB.
+     *
+     *  Each entry of the list specifies the surface index of the picture
+     *  that is referred by current picture or will be referred by any future
+     *  picture.
+     *  Application who calls this API should update this list based on the
+     *  refreshing information from VP9 bitstream.
+     */
+    VASurfaceID             reference_frames[8];
+
+    union
+    {
+        struct
+        {
+            /** \brief flags for current picture
+             *  same syntax and semantic as those in VP9 code
+             */
+            uint32_t        subsampling_x                               : 1;
+            uint32_t        subsampling_y                               : 1;
+            uint32_t        frame_type                                  : 1;
+            uint32_t        show_frame                                  : 1;
+            uint32_t        error_resilient_mode                        : 1;
+            uint32_t        intra_only                                  : 1;
+            uint32_t        allow_high_precision_mv                     : 1;
+            uint32_t        mcomp_filter_type                           : 3;
+            uint32_t        frame_parallel_decoding_mode                : 1;
+            uint32_t        reset_frame_context                         : 2;
+            uint32_t        refresh_frame_context                       : 1;
+            uint32_t        frame_context_idx                           : 2;
+            uint32_t        segmentation_enabled                        : 1;
+
+            /** \brief corresponds to variable temporal_update in VP9 code.
+             */
+            uint32_t        segmentation_temporal_update                : 1;
+            /** \brief corresponds to variable update_mb_segmentation_map
+             *  in VP9 code.
+             */
+            uint32_t        segmentation_update_map                     : 1;
+
+            /** \brief Index of reference_frames[] and points to the
+             *  LAST reference frame.
+             *  It corresponds to active_ref_idx[0] in VP9 code.
+             */
+            uint32_t        last_ref_frame                              : 3;
+            /** \brief Sign Bias of the LAST reference frame.
+             *  It corresponds to ref_frame_sign_bias[LAST_FRAME] in VP9 code.
+             */
+            uint32_t        last_ref_frame_sign_bias                    : 1;
+            /** \brief Index of reference_frames[] and points to the
+             *  GOLDERN reference frame.
+             *  It corresponds to active_ref_idx[1] in VP9 code.
+             */
+            uint32_t        golden_ref_frame                            : 3;
+            /** \brief Sign Bias of the GOLDERN reference frame.
+             *  Corresponds to ref_frame_sign_bias[GOLDERN_FRAME] in VP9 code.
+             */
+            uint32_t        golden_ref_frame_sign_bias                  : 1;
+            /** \brief Index of reference_frames[] and points to the
+             *  ALTERNATE reference frame.
+             *  Corresponds to active_ref_idx[2] in VP9 code.
+             */
+            uint32_t        alt_ref_frame                               : 3;
+            /** \brief Sign Bias of the ALTERNATE reference frame.
+             *  Corresponds to ref_frame_sign_bias[ALTREF_FRAME] in VP9 code.
+             */
+            uint32_t        alt_ref_frame_sign_bias                     : 1;
+            /** \brief Lossless Mode
+             *  LosslessFlag = base_qindex == 0 &&
+             *                 y_dc_delta_q == 0 &&
+             *                 uv_dc_delta_q == 0 &&
+             *                 uv_ac_delta_q == 0;
+             *  Where base_qindex, y_dc_delta_q, uv_dc_delta_q and uv_ac_delta_q
+             *  are all variables in VP9 code.
+             */
+            uint32_t        lossless_flag                               : 1;
+        } bits;
+        uint32_t            value;
+    } pic_fields;
+
+    /* following parameters have same syntax with those in VP9 code */
+    uint8_t                 filter_level;
+    uint8_t                 sharpness_level;
+
+    /** \brief number of tile rows specified by (1 << log2_tile_rows).
+     *  It corresponds the variable with same name in VP9 code.
+     */
+    uint8_t                 log2_tile_rows;
+    /** \brief number of tile columns specified by (1 << log2_tile_columns).
+     *  It corresponds the variable with same name in VP9 code.
+     */
+    uint8_t                 log2_tile_columns;
+    /** \brief Number of bytes taken up by the uncompressed frame header,
+     *  which corresponds to byte length of function
+     *  read_uncompressed_header() in VP9 code.
+     *  Specifically, it is the byte count from bit stream buffer start to
+     *  the last byte of uncompressed frame header.
+     */
+    uint8_t                 frame_header_length_in_bytes;
+
+    /** \brief The byte count of compressed header the bitstream buffer,
+     *  which corresponds to syntax first_partition_size in code.
+     */
+    uint16_t                first_partition_size;
+
+    /** \brief The byte count of current frame in the bitstream buffer,
+     *  starting from first byte of the buffer.
+     */
+    uint32_t                frame_data_size;
+
+    /** These values are segment probabilities with same names in VP9
+     *  function setup_segmentation(). They should be parsed directly from
+     *  bitstream by application.
+     */
+    uint8_t                 mb_segment_tree_probs[7];
+    uint8_t                 segment_pred_probs[3];
+
+    /** \brief VP9 version number
+     *  value can be 0 or 1.
+     */
+    uint8_t                 version;
+    /**@}*/
+
+} VADecPictureParameterBufferVP9;
+
+
+
+/**
+ * \brief VP9 Segmentation Parameter Data Structure
+ *
+ * This structure conveys per segment parameters.
+ * 8 of this data structure will be included in VASegmentationParameterBufferVP9
+ * and sent to API in a single buffer.
+ *
+ */
+typedef struct  _VASegmentParameterVP9
+{
+    /**@{*/
+
+    union
+    {
+        struct
+        {
+            /** \brief Indicates if per segment reference frame indicator
+             *  is enabled.
+             *  Corresponding to variable feature_enabled when
+             *  j == SEG_LVL_REF_FRAME in function setup_segmentation() VP9 code.
+             */
+            uint16_t        segment_reference_enabled                   : 1;
+            /** \brief Specifies per segment reference indication.
+             *  0: reserved
+             *  1: Last ref
+             *  2: golden
+             *  3: altref
+             *  Value can be derived from variable data when
+             *  j == SEG_LVL_REF_FRAME in function setup_segmentation() VP9 code.
+             */
+            uint16_t        segment_reference                           : 2;
+            /** \brief Indicates if per segment skip feature is enabled.
+             *  Corresponding to variable feature_enabled when
+             *  j == SEG_LVL_SKIP in function setup_segmentation() VP9 code.
+             */
+            uint16_t        segment_reference_skipped                   : 1;
+        } fields;
+        uint16_t            value;
+    } segment_flags;
+
+    /** \brief Specifies the filter level information per segment.
+     *  The value corresponds to variable lfi->lvl[seg][ref][mode] in VP9 code,
+     *  where m is [ref], and n is [mode] in FilterLevel[m][n].
+     */
+    uint8_t                 filter_level[4][2];
+    /** \brief Specifies per segment Luma AC quantization scale.
+     *  Corresponding to y_dequant[qindex][1] in vp9_mb_init_quantizer()
+     *  function of VP9 code.
+     */
+    int16_t                 luma_ac_quant_scale;
+    /** \brief Specifies per segment Luma DC quantization scale.
+     *  Corresponding to y_dequant[qindex][0] in vp9_mb_init_quantizer()
+     *  function of VP9 code.
+     */
+    int16_t                 luma_dc_quant_scale;
+    /** \brief Specifies per segment Chroma AC quantization scale.
+     *  Corresponding to uv_dequant[qindex][1] in vp9_mb_init_quantizer()
+     *  function of VP9 code.
+     */
+    int16_t                 chroma_ac_quant_scale;
+    /** \brief Specifies per segment Chroma DC quantization scale.
+     *  Corresponding to uv_dequant[qindex][0] in vp9_mb_init_quantizer()
+     *  function of VP9 code.
+     */
+    int16_t                 chroma_dc_quant_scale;
+
+    /**@}*/
+
+} VASegmentParameterVP9;
+
+
+
+/**
+ * \brief VP9 Slice Parameter Buffer Structure
+ *
+ * This structure conveys parameters related to segmentation data and should be
+ * sent once per frame.
+ *
+ * When segmentation is disabled, only SegParam[0] has valid values,
+ * all other entries should be populated with 0.
+ * Otherwise, all eight entries should be valid.
+ *
+ * Slice data buffer of VASliceDataBufferType is used
+ * to send the bitstream which should include whole or part of partition 0
+ * (at least compressed header) to the end of frame.
+ *
+ */
+typedef struct _VASliceParameterBufferVP9
+{
+    /**@{*/
+    /**
+     * \brief per segment information
+     */
+    VASegmentParameterVP9   seg_param[8];
+
+    /**@}*/
+
+} VASliceParameterBufferVP9;
+
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_DEC_VP9_H */
diff --git a/va/va_drmcommon.h b/va/va_drmcommon.h
new file mode 100644
index 0000000..76820a3
--- /dev/null
+++ b/va/va_drmcommon.h
@@ -0,0 +1,76 @@
+/*
+ * va_drmcommon.h - Common utilities for DRM-based drivers
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_DRM_COMMON_H
+#define VA_DRM_COMMON_H
+
+/** \brief DRM authentication type. */
+enum {
+    /** \brief Disconnected. */
+    VA_DRM_AUTH_NONE    = 0,
+    /**
+     * \brief Connected. Authenticated with DRI1 protocol.
+     *
+     * @deprecated
+     * This is a deprecated authentication type. All DRI-based drivers have
+     * been migrated to use the DRI2 protocol. Newly written drivers shall
+     * use DRI2 protocol only, or a custom authentication means. e.g. opt
+     * for authenticating on the VA driver side, instead of libva side.
+     */
+    VA_DRM_AUTH_DRI1    = 1,
+    /**
+     * \brief Connected. Authenticated with DRI2 protocol.
+     *
+     * This is only useful to VA/X11 drivers. The libva-x11 library provides
+     * a helper function VA_DRI2Authenticate() for authenticating the
+     * connection. However, DRI2 conformant drivers don't need to call that
+     * function since authentication happens on the libva side, implicitly.
+     */
+    VA_DRM_AUTH_DRI2    = 2,
+    /**
+     * \brief Connected. Authenticated with some alternate raw protocol.
+     *
+     * This authentication mode is mainly used in non-VA/X11 drivers.
+     * Authentication happens through some alternative method, at the
+     * discretion of the VA driver implementation.
+     */
+    VA_DRM_AUTH_CUSTOM  = 3
+};
+
+/** \brief Base DRM state. */
+struct drm_state {
+    /** \brief DRM connection descriptor. */
+    int         fd;
+    /** \brief DRM authentication type. */
+    int         auth_type;
+};
+
+/** \brief Kernel DRM buffer memory type.  */
+#define VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM		0x10000000
+/** \brief DRM PRIME memory type. */
+#define VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME		0x20000000
+
+#endif /* VA_DRM_COMMON_H */
diff --git a/va/va_dummy.h b/va/va_dummy.h
deleted file mode 120000
index 69128f8..0000000
--- a/va/va_dummy.h
+++ /dev/null
@@ -1 +0,0 @@
-va_android.h
\ No newline at end of file
diff --git a/va/va_enc.h b/va/va_enc.h
index becd980..d98b741 100644
--- a/va/va_enc.h
+++ b/va/va_enc.h
@@ -47,6 +47,27 @@
 /** \brief Abstract representation of a bitstream writer. */
 typedef struct _VAEncBitstream VAEncBitstream;
 
+/**
+ * @name Picture flags
+ *
+ * Those flags flags are meant to signal when a picture marks the end
+ * of a sequence, a stream, or even both at once.
+ *
+ * @{
+ */
+/**
+ * \brief Marks the last picture in the sequence.
+ *
+ */
+#define VA_ENC_LAST_PICTURE_EOSEQ       0x01
+/**
+ * \brief Marks the last picture in the stream.
+ *
+ */
+#define VA_ENC_LAST_PICTURE_EOSTREAM    0x02
+/**@}*/
+
+
 /** @name The set of all possible error codes */
 /**@{*/
 /** \brief An invalid bitstream writer handle was supplied. */
diff --git a/va/va_enc_h264.h b/va/va_enc_h264.h
index 6da3f01..6fe7506 100644
--- a/va/va_enc_h264.h
+++ b/va/va_enc_h264.h
@@ -36,6 +36,7 @@
 extern "C" {
 #endif
 
+#include <stdint.h>
 #include <va/va_enc.h>
 
 /**
@@ -57,13 +58,13 @@
  *
  * i.e. the driver appends \c end_of_seq() NAL unit to the encoded frame.
  */
-#define H264_LAST_PICTURE_EOSEQ     0x01
+#define H264_LAST_PICTURE_EOSEQ     VA_ENC_LAST_PICTURE_EOSEQ
 /**
  * \brief Marks the last picture in the stream.
  *
  * i.e. the driver appends \c end_of_stream() NAL unit to the encoded frame.
  */
-#define H264_LAST_PICTURE_EOSTREAM  0x02
+#define H264_LAST_PICTURE_EOSTREAM  VA_ENC_LAST_PICTURE_EOSTREAM
 /**@}*/
 
 /**
@@ -123,7 +124,8 @@
 } VAEncPackedHeaderTypeH264;
 
 /**
- * \brief Sequence parameter for H.264 encoding in main & high profiles.
+ * \brief Sequence parameter for H.264 encoding in baseline, main & high 
+ * profiles.
  *
  * This structure holds information for \c seq_parameter_set_data() as
  * defined by the H.264 specification.
@@ -259,7 +261,8 @@
 } VAEncSequenceParameterBufferH264;
 
 /**
- * \brief Picture parameter for H.264 encoding in main & high profiles.
+ * \brief Picture parameter for H.264 encoding in baseline, main & high 
+ * profiles.
  *
  * This structure holds information for \c pic_parameter_set_rbsp() as
  * defined by the H.264 specification.
@@ -369,7 +372,7 @@
 } VAEncPictureParameterBufferH264;
 
 /**
- * \brief Slice parameter for H.264 encoding in main & high profiles.
+ * \brief Slice parameter for H.264 encoding in baseline, main & high profiles.
  *
  * This structure holds information for \c
  * slice_layer_without_partitioning_rbsp() as defined by the H.264
@@ -524,7 +527,8 @@
 /**@}*/
 
 /**
- * \brief Macroblock parameter for H.264 encoding in main & high profiles.
+ * \brief Macroblock parameter for H.264 encoding in baseline, main & high 
+ * profiles.
  *
  * This structure holds per-macroblock information. The buffer must be
  * allocated with as many elements (macroblocks) as necessary to fit
@@ -582,6 +586,124 @@
     } info;
 } VAEncMacroblockParameterBufferH264;
 
+/**
+ * \brief H.264 Mutiview Coding(MVC) Sequence Parameter Buffer
+ *
+ */
+typedef struct _VAEncSequenceParameterBufferH264_MVC {
+    /** brief Basic common sequence parameter */
+    VAEncSequenceParameterBufferH264 base;
+
+    /** brief Plus 1 specify the max number of views
+     * coded in the video sequence
+     */
+    uint16_t num_views_minus1;
+
+    /** brief Specify the view information in all layers */
+    struct H264SPSExtMVCViewInfo{
+        /** \brief The current view identifier. */
+        uint16_t view_id;
+        /** \brief Specifies the number of view components for inter-view
+         * prediction in the initialized RefPicList0 in decoding
+         * anchor views.
+         */
+        uint8_t  num_anchor_refs_l0;
+        /** \brief Specifies the view_id for inter-view prediction in
+         * the initialized RefPicList0 in decoding anchor views.
+         */
+        uint16_t anchor_ref_l0[15];
+        /** \brief Specifies the number of view components for inter-view
+         * prediction in the initialized RefPicList1 in decoding
+         * anchor views
+         */
+        uint8_t  num_anchor_refs_l1;
+        /** \brief Specifies the view_id for inter-view prediction in
+         * the initialized RefPicList1 in decoding anchor views.
+         */
+        uint16_t anchor_ref_l1[15];
+        /** \brief Specifies the number of view components for inter-view
+         * prediction in the initialized RefPicList0 in decoding
+         * non-anchor views.
+         */
+        uint8_t  num_non_anchor_refs_l0;
+        /** \brief Specifies the view_id for inter-view prediction in
+         * the initialized RefPicList0 in decoding non-anchor views.
+         */
+        uint16_t non_anchor_ref_l0[15];
+        /** \brief Specifies the number of view components for inter-view
+         * prediction in the initialized RefPicList1 in decoding
+         * non-anchor view.
+         */
+        uint8_t  num_non_anchor_refs_l1;
+        /** \brief Specifies the view_id for inter-view prediction in
+         * the initialized RefPicList1 in decoding non-anchor views.
+         */
+        uint16_t non_anchor_ref_l1[15];
+    }* view_list;
+
+    /** brief Plus 1 specifies the number of level values
+     * signalled for the coded video sequence
+     */
+    uint8_t num_level_values_signalled_minus1;
+
+    /** brief Level values operation for a set of the operation
+     * points in the current sequence
+     */
+    struct H264SPSExtMVCLevelValue {
+        /** \brief Specifies the level value signalled for the coded video sequence */
+        uint8_t level_idc;
+
+        /** \brief Plus 1 specifies the number of operation points to
+         *  which the level indicated by level_idc applies
+         */
+        uint16_t num_applicable_ops_minus1;
+
+        /** \brief Represent the specific operation to the view in the video sequence */
+        struct H264SPSExtMVCLevelValueOps {
+            /** \brief Specify a temporal identifier for the NAL unit */
+            uint8_t   temporal_id;
+            /** \brief Specify the number of the views whose level value will be modified */
+            uint16_t  num_target_views_minus1;
+            /** \brief Specify the views whose level value will be modified */
+            uint16_t* target_view_id_list;
+            /** \brief Specify the number of views whose level value can be modified */
+            uint16_t  num_views_minus1;
+        }* level_value_ops_list;
+
+    }* level_value_list;
+
+} VAEncSequenceParameterBufferH264_MVC;
+
+/**
+ * \brief H.264 Multiview Coding(MVC) Picture Parameter Buffer
+ *
+ */
+typedef struct _VAEncPictureParameterBufferH264_MVC
+{
+    /** brief Basic common picture parameter */
+    VAEncPictureParameterBufferH264 base;
+
+    /** brief Specifes the view id for current picture */
+    uint16_t view_id;
+
+    /** brief Specifes whether the picture is one anchor picture */
+    uint8_t  anchor_pic_flag;
+
+    /** brief Specifes whether inter view reference frame
+     * is used to encode current picture.
+     */
+    uint8_t  inter_view_flag;
+} VAEncPictureParameterBufferH264_MVC;
+
+typedef struct _VAEncQpBufferH264 {
+    /*
+     * \brief This structure holds luma Qp per 16x16 macroblock. Buffer size shall be 
+     * sufficient to fit the slice or frame to be encoded depending on if it is a slice level
+     * or frame level encoding.
+     */
+    unsigned char qp_y;
+} VAEncQpBufferH264;
+
 /** \brief Bitstream writer attribute types specific to H.264 encoding. */
 typedef enum {
     /**
@@ -592,35 +714,6 @@
         VAEncBitstreamAttribMiscMask | 1),
 } VAEncBitstreamAttribTypeH264;
 
-typedef struct _VAEncPictureParameterBufferH264MVC {
-    /**
-     * \brief Regular H.264 picture parameters
-     *
-     */
-    VAEncPictureParameterBufferH264 base_picture_param;
-    /**
-     * \brief view id associated with this picture
-     *
-     */
-    unsigned int view_id;
-    /**
-     * \brief same as H.264 MVC syntax element
-     *
-     */
-    unsigned char anchor_picture_flag;
-    /**
-     * \brief same as H.264 MVC syntax element
-     *
-     */
-    unsigned char inter_view_flag;
-
-    /**
-     * \brief Specifies view_id of each element in ReferenceFrames[16]
-     *
-     */
-    unsigned int view_id_dpb[16];
-
-} VAEncPictureParameterBufferH264MVC;
 
 /**
  * \brief Allocates a new H.264 bitstream writer.
diff --git a/va/va_enc_jpeg.h b/va/va_enc_jpeg.h
new file mode 100644
index 0000000..be6b36e
--- /dev/null
+++ b/va/va_enc_jpeg.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2007-2013 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file va_enc_jpeg.h
+ * \brief JPEG encoding API
+ *
+ * This file contains the \ref api_enc_jpeg "JPEG encoding API".
+ */
+
+#ifndef VA_ENC_JPEG_H
+#define VA_ENC_JPEG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup api_enc_jpeg JPEG encoding API
+ *
+ * @{
+ */
+
+/**
+ * \brief JPEG Encoding Picture Parameter Buffer Structure
+ *
+ * This structure conveys picture level parameters.
+ *
+ */
+typedef struct  _VAEncPictureParameterBufferJPEG
+{
+    /** \brief holds reconstructed picture. */
+    VASurfaceID reconstructed_picture;
+    /** \brief picture width. */
+    unsigned short picture_width;
+    /** \brief picture height. */
+    unsigned short picture_height;
+    /** \brief holds coded data. */
+    VABufferID coded_buf;
+
+    /** 
+     * \brief pic_flags
+     *
+     */
+    union {
+        struct {
+            /** 
+             * \brief profile: 
+             * 0 - Baseline, 1 - Extended, 2 - Lossless, 3 - Hierarchical
+             */ 
+            unsigned int profile     : 2;
+            /** 
+             * \brief progressive: 
+             * 0 - sequential, 1 - extended, 2 - progressive
+             */ 
+            unsigned int progressive : 1;
+            /** 
+             * \brief huffman: 
+             * 0 - arithmetic, 1 - huffman
+             */ 
+            unsigned int huffman     : 1;
+            /** 
+             * \brief interleaved: 
+             * 0 - non interleaved, 1 - interleaved
+             */ 
+            unsigned int interleaved : 1;
+            /** 
+             * \brief differential: 
+             * 0 - non differential, 1 - differential
+             */ 
+            unsigned int differential   : 1;
+        } bits;
+        unsigned int value;
+    } pic_flags;
+
+    /** \brief number of bits per sample. */
+    unsigned char    sample_bit_depth;
+    /** \brief total number of scans in image. */
+    unsigned char    num_scan;
+    /** \brief number of image components in frame. */
+    unsigned short   num_components;
+    /** \brief Component identifier (Ci). */
+    unsigned char    component_id[4];
+    /** \brief Quantization table selector (Tqi). */
+    unsigned char    quantiser_table_selector[4];
+    /** \brief number from 1 to 100 that specifies quality of image. */
+    unsigned char    quality;
+
+} VAEncPictureParameterBufferJPEG;
+
+
+/**
+ * \brief Slice parameter for JPEG encoding. 
+ *
+ * This structure conveys slice (scan) level parameters.
+ *
+ */
+typedef struct _VAEncSliceParameterBufferJPEG {
+    /** \brief Restart interval definition (Ri). */
+    unsigned short    restart_interval;
+    /** \brief number of image components in a scan. */
+    unsigned short    num_components;
+    struct {
+        /** \brief Scan component selector (Csj). */
+        unsigned char   component_selector;
+        /** \brief DC entropy coding table selector (Tdj). */
+        unsigned char   dc_table_selector;
+        /** \brief AC entropy coding table selector (Taj). */
+        unsigned char   ac_table_selector;
+    } components[4];
+} VAEncSliceParameterBufferJPEG;
+
+/**
+ * \brief Quantization table for JPEG encoding.
+ *
+ */
+typedef struct _VAQMatrixBufferJPEG
+{
+    /** \brief load luma quantization table. */
+    int load_lum_quantiser_matrix;
+    /** \brief load chroma quantization table. */
+    int load_chroma_quantiser_matrix;
+    /** \brief luma quantization table. */
+    unsigned char lum_quantiser_matrix[64];
+    /** \brief chroma quantization table. */
+    unsigned char chroma_quantiser_matrix[64];
+} VAQMatrixBufferJPEG;
+
+/**@}*/
+
+#include <va/va_dec_jpeg.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_ENC_JPEG_H */
diff --git a/va/va_enc_mpeg2.h b/va/va_enc_mpeg2.h
new file mode 100644
index 0000000..cee974b
--- /dev/null
+++ b/va/va_enc_mpeg2.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file va_enc_mpeg2.h
+ * \brief The MPEG-2 encoding API
+ *
+ * This file contains the \ref api_enc_mpeg2 "MPEG-2 encoding API".
+ */
+
+#ifndef _VA_ENC_MPEG2_H_
+#define _VA_ENC_MPEG2_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <va/va_enc.h>
+
+/**
+ * \defgroup api_enc_mpeg2 MPEG-2 encoding API
+ *
+ * @{
+ */
+
+#define MPEG2_LAST_PICTURE_EOSTREAM  VA_ENC_LAST_PICTURE_EOSTREAM
+
+/**
+ * \brief MPEG-2 Quantization Matrix Buffer
+ *
+ */
+typedef VAIQMatrixBufferMPEG2 VAQMatrixBufferMPEG2;
+
+/**
+ * \brief Packed header types specific to MPEG-2 encoding.
+ *
+ * Types of packed headers generally used for MPEG-2 encoding.
+ */
+typedef enum {
+    /**
+     * \brief Packed Sequence Parameter Set (SPS).
+     *
+     */
+    VAEncPackedHeaderMPEG2_SPS = VAEncPackedHeaderSequence,
+    /**
+     * \brief Packed Picture Parameter Set (PPS).
+     *
+     */
+    VAEncPackedHeaderMPEG2_PPS = VAEncPackedHeaderPicture,
+    /**
+     * \brief Packed slice header.
+     *
+     */
+    VAEncPackedHeaderMPEG2_Slice = VAEncPackedHeaderSlice,
+} VAEncPackedHeaderTypeMPEG2;
+
+/**
+ * \brief Sequence parameter for MPEG-2 encoding
+ *
+ * This structure holds information for \c sequence_header() and
+ * sequence_extension().
+ *
+ * If packed sequence headers mode is used, i.e. if the encoding
+ * pipeline was configured with the #VA_ENC_PACKED_HEADER_SEQUENCE
+ * flag, then the driver expects two more buffers to be provided to
+ * the same \c vaRenderPicture() as this buffer:
+ * - a #VAEncPackedHeaderParameterBuffer with type set to
+ *   VAEncPackedHeaderType::VAEncPackedHeaderSequence ;
+ * - a #VAEncPackedHeaderDataBuffer which holds the actual packed
+ *   header data.
+ *
+ */
+typedef struct _VAEncSequenceParameterBufferMPEG2 {
+    /** \brief Period between I frames. */
+    unsigned int intra_period;
+    /** \brief Period between I/P frames. */
+    unsigned int ip_period;
+    /** \brief Picture width.
+     *
+     * A 14bits unsigned inter, the lower 12bits 
+     * is horizontal_size_value, and the upper 
+     * 2bits is \c horizontal_size_extension
+     *
+     */
+    unsigned short picture_width;
+    /** \brief Picture height.
+     *
+     * A 14bits unsigned inter, the lower 12bits
+     * is vertical_size_value, and the upper 2bits is 
+     * vertical_size_size_extension
+     *
+     */
+    unsigned short picture_height;
+    /**
+     * \brief Initial bitrate set for this sequence in CBR or VBR modes.
+     *
+     * This field represents the initial bitrate value for this
+     * sequence if CBR or VBR mode is used, i.e. if the encoder
+     * pipeline was created with a #VAConfigAttribRateControl
+     * attribute set to either \ref VA_RC_CBR or \ref VA_RC_VBR.
+     *
+     * bits_per_second may be derived from bit_rate.
+     *
+     */
+    unsigned int bits_per_second;
+    /**
+     * \brief Frame rate
+     * 
+     * Derived from frame_rate_value, frame_rate_extension_n and 
+     * frame_rate_extension_d
+     *
+     */
+    float frame_rate;
+    /** \brief Same as the element in sequence_header() */
+    unsigned short aspect_ratio_information;
+    /** \brief Define the size of VBV */
+    unsigned int vbv_buffer_size;
+
+    union {
+        struct {
+            /** \brief Same as the element in Sequence extension() */
+            unsigned int profile_and_level_indication   : 8;
+            /** \brief Same as the element in Sequence extension() */
+            unsigned int progressive_sequence           : 1;
+            /** \brief Same as the element in Sequence extension() */
+            unsigned int chroma_format                  : 2;
+            /** \brief Same as the element in Sequence extension() */
+            unsigned int low_delay                      : 1;
+            /** \brief Same as the element in Sequence extension() */
+            unsigned int frame_rate_extension_n         : 2;
+            /** \brief Same as the element in Sequence extension() */
+            unsigned int frame_rate_extension_d         : 5;
+        } bits;
+        unsigned int value;
+    } sequence_extension;
+
+    /** \brief Flag to indicate the following GOP header are being updated */
+    unsigned int new_gop_header;
+
+    union {
+        struct {
+            /** \brief Time code */
+            unsigned int time_code                      : 25;
+            /** \brief Same as the element in GOP header */
+            unsigned int closed_gop                     : 1;
+            /** \brief SAme as the element in GOP header */
+            unsigned int broken_link                    : 1;
+        } bits;
+        unsigned int value;
+    } gop_header;
+} VAEncSequenceParameterBufferMPEG2;
+
+/**
+ * \brief Picture parameter for MPEG-2 encoding
+ *
+ * This structure holds information for picture_header() and 
+ * picture_coding_extension()
+ *
+ * If packed picture headers mode is used, i.e. if the encoding
+ * pipeline was configured with the #VA_ENC_PACKED_HEADER_PICTURE
+ * flag, then the driver expects two more buffers to be provided to
+ * the same \c vaRenderPicture() as this buffer:
+ * - a #VAEncPackedHeaderParameterBuffer with type set to
+ *   VAEncPackedHeaderType::VAEncPackedHeaderPicture ;
+ * - a #VAEncPackedHeaderDataBuffer which holds the actual packed
+ *   header data.
+ *
+ */
+typedef struct _VAEncPictureParameterBufferMPEG2 {
+    /** \brief Forward reference picture */
+    VASurfaceID forward_reference_picture;
+    /** \brief Backward reference picture */
+    VASurfaceID backward_reference_picture;
+    /** \brief Reconstructed(decoded) picture */
+    VASurfaceID reconstructed_picture;
+    /**
+     * \brief Output encoded bitstream.
+     *
+     * \ref coded_buf has type #VAEncCodedBufferType. It should be
+     * large enough to hold the compressed NAL slice and possibly SPS
+     * and PPS NAL units.
+     */
+    VABufferID coded_buf;
+    /**
+     * \brief Flag to indicate the picture is the last one or not.
+     *
+     * This fields holds 0 if the picture to be encoded is not 
+     * the last one in the stream. Otherwise, it 
+     * is \ref MPEG2_LAST_PICTURE_EOSTREAM.
+     */
+    unsigned char last_picture;
+    /** \brief Picture type */
+    VAEncPictureType picture_type;
+    /** \brief Same as the element in picture_header() */
+    unsigned int temporal_reference;
+    /** \brief Same as the element in picture_header() */
+    unsigned int vbv_delay;
+    /** \brief Same as the element in Picture coding extension */
+    unsigned char f_code[2][2];
+    union {
+        struct {
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int intra_dc_precision             : 2; 
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int picture_structure              : 2; 
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int top_field_first                : 1; 
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int frame_pred_frame_dct           : 1; 
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int concealment_motion_vectors     : 1;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int q_scale_type                   : 1;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int intra_vlc_format               : 1;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int alternate_scan                 : 1;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int repeat_first_field             : 1;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int progressive_frame              : 1;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int composite_display_flag         : 1;
+        } bits;
+        unsigned int value;
+    } picture_coding_extension;
+
+    /* \brief Parameters for composite display
+     *
+     * Valid only when omposite_display_flag is 1
+     */
+    union {
+        struct {
+            /** \brief Same as the element in Picture coding extension */            
+            unsigned int v_axis                         : 1;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int field_sequence                 : 3;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int sub_carrier                    : 1;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int burst_amplitude                : 7;
+            /** \brief Same as the element in Picture coding extension */
+            unsigned int sub_carrier_phase              : 8;
+        } bits;
+        unsigned int value;
+    } composite_display;
+} VAEncPictureParameterBufferMPEG2;
+
+/**
+ * \brief Slice parameter for MPEG-2 encoding
+ *
+ */
+typedef struct _VAEncSliceParameterBufferMPEG2 {
+    /** \brief Starting MB address for this slice. */
+    unsigned int macroblock_address;
+    /** \brief Number of macroblocks in this slice. */
+    unsigned int num_macroblocks;
+    /** \brief Same as the element in slice() */
+    int quantiser_scale_code;
+    /** \brief Flag to indicate intra slice */
+    int is_intra_slice;
+} VAEncSliceParameterBufferMPEG2;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VA_ENC_MPEG2_H_ */
diff --git a/va/va_enc_vp8.h b/va/va_enc_vp8.h
new file mode 100644
index 0000000..6d3023c
--- /dev/null
+++ b/va/va_enc_vp8.h
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2007-2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file va_enc_vp8.h
+ * \brief VP8 encoding API
+ *
+ * This file contains the \ref api_enc_vp8 "VP8 encoding API".
+ */
+
+#ifndef VA_ENC_VP8_H
+#define VA_ENC_VP8_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup api_enc_vp8 VP8 encoding API
+ *
+ * @{
+ */
+
+/**
+ * \brief VP8 Encoding Sequence Parameter Buffer Structure
+ *
+ * This structure conveys sequence level parameters.
+ *
+ */
+typedef struct  _VAEncSequenceParameterBufferVP8
+{
+    /* frame width in pixels */
+    unsigned int frame_width;
+    /* frame height in pixels */
+    unsigned int frame_height;
+    /* horizontal scale */
+    unsigned int frame_width_scale;
+    /* vertical scale */
+    unsigned int frame_height_scale;
+
+    /* whether to enable error resilience features */
+    unsigned int error_resilient;
+    /* auto keyframe placement, non-zero means enable auto keyframe placement */
+    unsigned int kf_auto;
+    /* keyframe minimum interval */
+    unsigned int kf_min_dist;
+    /* keyframe maximum interval */
+    unsigned int kf_max_dist;
+
+
+    /* RC related fields. RC modes are set with VAConfigAttribRateControl */
+    /* For VP8, CBR implies HRD conformance and VBR implies no HRD conformance */
+
+    /**
+     * Initial bitrate set for this sequence in CBR or VBR modes.
+     *
+     * This field represents the initial bitrate value for this
+     * sequence if CBR or VBR mode is used, i.e. if the encoder
+     * pipeline was created with a #VAConfigAttribRateControl
+     * attribute set to either \ref VA_RC_CBR or \ref VA_RC_VBR.
+     *
+     * The bitrate can be modified later on through
+     * #VAEncMiscParameterRateControl buffers.
+     */
+    unsigned int bits_per_second;
+    /* Period between I frames. */
+    unsigned int intra_period;
+
+    /* reference and reconstructed frame buffers
+     * Used for driver auto reference management when configured through 
+     * VAConfigAttribEncAutoReference. 
+     */
+    VASurfaceID reference_frames[4];
+
+} VAEncSequenceParameterBufferVP8;
+
+
+/**
+ * \brief VP8 Encoding Picture Parameter Buffer Structure
+ *
+ * This structure conveys picture level parameters.
+ *
+ */
+typedef struct  _VAEncPictureParameterBufferVP8
+{
+    /* surface to store reconstructed frame  */
+    VASurfaceID reconstructed_frame;
+
+    /* 
+     * surfaces to store reference frames in non auto reference mode
+     * VA_INVALID_SURFACE can be used to denote an invalid reference frame. 
+     */
+    VASurfaceID ref_last_frame;
+    VASurfaceID ref_gf_frame;
+    VASurfaceID ref_arf_frame;
+
+    /* buffer to store coded data */
+    VABufferID coded_buf;
+
+    union {
+        struct {
+            /* force this frame to be a keyframe */
+            unsigned int force_kf                       : 1;
+            /* don't reference the last frame */
+            unsigned int no_ref_last                    : 1;
+            /* don't reference the golden frame */
+            unsigned int no_ref_gf                      : 1;
+            /* don't reference the alternate reference frame */
+            unsigned int no_ref_arf                     : 1;
+            /* The temporal id the frame belongs to. */
+            unsigned int temporal_id                    : 8;
+            unsigned int reserved                       : 20;
+        } bits;
+        unsigned int value;
+    } ref_flags;
+
+    union {
+        struct {
+            /* version */
+            unsigned int frame_type                     : 1;
+            unsigned int version                        : 3;
+            /* show_frame */
+            unsigned int show_frame                     : 1;
+            /* color_space */						   
+            unsigned int color_space                    : 1;
+            /*  0: bicubic, 1: bilinear, other: none */
+            unsigned int recon_filter_type              : 2;
+            /*  0: no loop fitler, 1: simple loop filter */
+            unsigned int loop_filter_type               : 2;
+            /* 0: disabled, 1: normal, 2: simple */
+            unsigned int auto_partitions                : 1;
+            /* number of token partitions */
+            unsigned int num_token_partitions           : 2;
+
+            /** 
+             * The following fields correspond to the same VP8 syntax elements 
+             * in the frame header.
+             */
+	    /**
+             * 0: clamping of reconstruction pixels is disabled,
+             * 1: clamping enabled.
+             */
+            unsigned int clamping_type                  : 1;
+            /* indicate segmentation is enabled for the current frame. */
+            unsigned int segmentation_enabled           : 1;
+            /**
+             * Determines if the MB segmentation map is updated in the current 
+             * frame.
+             */
+            unsigned int update_mb_segmentation_map     : 1;
+            /**
+             * Indicates if the segment feature data is updated in the current 
+             * frame.
+             */
+            unsigned int update_segment_feature_data    : 1;
+            /**
+             * indicates if the MB level loop filter adjustment is enabled for 
+             * the current frame (0 off, 1 on).  
+             */
+	    unsigned int loop_filter_adj_enable         : 1;
+            /**
+             * Determines whether updated token probabilities are used only for 
+             * this frame or until further update. 
+             * It may be used by application to enable error resilient mode. 
+             * In this mode probability updates are allowed only at Key Frames.
+             */
+            unsigned int refresh_entropy_probs          : 1;
+            /**
+             * Determines if the current decoded frame refreshes the golden frame.
+             */
+            unsigned int refresh_golden_frame           : 1;
+            /** 
+             * Determines if the current decoded frame refreshes the alternate 
+             * reference frame.
+             */
+            unsigned int refresh_alternate_frame        : 1;
+            /**
+             * Determines if the current decoded frame refreshes the last frame 
+             * reference buffer.
+             */
+            unsigned int refresh_last                   : 1;
+            /**
+             * Determines if the golden reference is replaced by another reference.
+             */
+            unsigned int copy_buffer_to_golden          : 2;
+            /**
+             * Determines if the alternate reference is replaced by another reference.
+             */
+            unsigned int copy_buffer_to_alternate       : 2;
+            /** 
+             * Controls the sign of motion vectors when the golden frame is referenced.  
+             */
+            unsigned int sign_bias_golden               : 1;
+            /**
+             * Controls the sign of motion vectors when the alternate frame is 
+             * referenced. 
+             */
+	    unsigned int sign_bias_alternate            : 1;
+            /**
+             * Enables or disables the skipping of macroblocks containing no 
+             * non-zero coefficients. 
+             */
+	    unsigned int mb_no_coeff_skip               : 1;
+            /** 
+             * Enforces unconditional per-MB loop filter delta update setting frame 
+             * header flags mode_ref_lf_delta_update, all mb_mode_delta_update_flag[4], 
+             * and all ref_frame_delta_update_flag[4] to 1. 
+	     * Since loop filter deltas are not automatically refreshed to default 
+             * values at key frames, dropped frame with delta update may prevent 
+             * correct decoding from the next key frame. 
+	     * Encoder application is advised to set this flag to 1 at key frames.
+	     */
+            unsigned int forced_lf_adjustment           : 1;
+            unsigned int reserved                       : 2;
+        } bits;
+        unsigned int value;
+    } pic_flags;
+
+    /**
+     * Contains a list of 4 loop filter level values (updated value if applicable)
+     * controlling the deblocking filter strength. Each entry represents a segment.
+     * When segmentation is disabled, use entry 0. 
+     * When loop_filter_level is 0, loop filter shall be disabled. 
+     */
+    char loop_filter_level[4];
+
+    /** 
+     * Contains a list of 4 delta values for reference frame based MB-level 
+     * loop filter adjustment.  
+     * If no update, then set to 0.
+     */
+    char ref_lf_delta[4];
+
+    /**
+     * Contains a list of 4 delta values for coding mode based MB-level loop
+     * filter adjustment.  
+     * If no update, then set to 0. 
+     */
+    char mode_lf_delta[4];
+	
+    /**
+     * Controls the deblocking filter sensitivity. 
+     * Corresponds to the same VP8 syntax element in frame header.
+     */
+    unsigned char sharpness_level;
+	
+    /** 
+     * Application supplied maximum clamp value for Qindex used in quantization.  
+     * Qindex will not be allowed to exceed this value.  
+     * It has a valid range [0..127] inclusive.  
+     */
+    unsigned char clamp_qindex_high;
+	
+    /**
+     * Application supplied minimum clamp value for Qindex used in quantization.  
+     * Qindex will not be allowed to be lower than this value.  
+     * It has a valid range [0..127] inclusive.  
+     * Condition clamp_qindex_low <= clamp_qindex_high must be guaranteed, 
+     * otherwise they are ignored. 
+     */
+    unsigned char clamp_qindex_low;
+	
+} VAEncPictureParameterBufferVP8;
+
+/**
+ * \brief VP8 Quantization Matrix Buffer Structure
+ *
+ * Contains quantization index for yac(0-3) for each segment and quantization 
+ * index deltas, ydc(0), y2dc(1), y2ac(2), uvdc(3), uvac(4) that are applied 
+ * to all segments.  When segmentation is disabled, only quantization_index[0] 
+ * will be used. This structure is sent once per frame.
+ */
+typedef struct _VAQMatrixBufferVP8
+{
+    unsigned short quantization_index[4];
+    short quantization_index_delta[5];
+} VAQMatrixBufferVP8;
+
+/**
+ * \brief VP8 MB Segmentation ID Buffer
+ *
+ * The application provides a buffer of VAEncMacroblockMapBufferType containing 
+ * the initial segmentation id for each MB, one byte each, in raster scan order. 
+ * Rate control may reassign it.  For example, a 640x480 video, the buffer has 1200 entries. 
+ * The value of each entry should be in the range [0..3], inclusive.
+ * If segmentation is not enabled, the application does not need to provide it. 
+ */
+
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_ENC_VP8_H */
diff --git a/va/va_fool.c b/va/va_fool.c
index 94b4c0b..1df177f 100644
--- a/va/va_fool.c
+++ b/va/va_fool.c
@@ -32,6 +32,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <errno.h>
 #include <string.h>
 #include <dlfcn.h>
 #include <unistd.h>
@@ -50,7 +51,8 @@
  * . if set, decode does nothing
  * LIBVA_FOOL_ENCODE=<framename>:
  * . if set, encode does nothing, but fill in the coded buffer from the content of files with
- *   name framename.0,framename.1,framename.2, ..., framename.N, framename.N,framename.N,...
+ *   name framename.0,framename.1,..., framename.N, framename.0,..., framename.N,...repeatly
+ *   Use file name to determine h264 or vp8
  * LIBVA_FOOL_JPEG=<framename>:fill the content of filename to codedbuf for jpeg encoding
  * LIBVA_FOOL_POSTP:
  * . if set, do nothing for vaPutSurface
@@ -61,14 +63,11 @@
 int fool_codec = 0;
 int fool_postp  = 0;
 
-#define FOOL_CONTEXT_MAX 4
-
 #define FOOL_BUFID_MAGIC   0x12345600
 #define FOOL_BUFID_MASK    0xffffff00
-/* per context settings */
-static struct _fool_context {
-    VADisplay dpy; /* should use context as the key */
 
+struct fool_context {
+    int enabled; /* fool_codec is global, and it is for concurent encode/decode */
     char *fn_enc;/* file pattern with codedbuf content for encode */
     char *segbuf_enc; /* the segment buffer of coded buffer, load frome fn_enc */
     int file_count;
@@ -88,17 +87,19 @@
     unsigned int fool_buf_element[VABufferTypeMax]; /* element count of created buffers */
     unsigned int fool_buf_count[VABufferTypeMax]; /* count of created buffers */
     VAContextID context;
-} fool_context[FOOL_CONTEXT_MAX]; /* trace five context at the same time */
+};
 
-#define DPY2INDEX(dpy)                                  \
-    int idx;                                            \
-                                                        \
-    for (idx = 0; idx < FOOL_CONTEXT_MAX; idx++)        \
-        if (fool_context[idx].dpy == dpy)               \
-            break;                                      \
-                                                        \
-    if (idx == FOOL_CONTEXT_MAX)                        \
-        return 0;  /* let driver go */
+#define FOOL_CTX(dpy) ((struct fool_context *)((VADisplayContextP)dpy)->vafool)
+
+#define DPY2FOOLCTX(dpy)                                 \
+    struct fool_context *fool_ctx = FOOL_CTX(dpy);       \
+    if (fool_ctx == NULL)                                \
+        return 0; /* no fool for the context */          \
+
+#define DPY2FOOLCTX_CHK(dpy)                             \
+    struct fool_context *fool_ctx = FOOL_CTX(dpy);       \
+    if ((fool_ctx == NULL) || (fool_ctx->enabled == 0))  \
+        return 0; /* no fool for the context */          \
 
 /* Prototype declarations (functions defined in va.c) */
 
@@ -110,16 +111,12 @@
 void va_FoolInit(VADisplay dpy)
 {
     char env_value[1024];
-    int fool_index = 0;
 
-    for (fool_index = 0; fool_index < FOOL_CONTEXT_MAX; fool_index++)
-        if (fool_context[fool_index].dpy == 0)
-            break;
-
-    if (fool_index == FOOL_CONTEXT_MAX)
+    struct fool_context *fool_ctx = calloc(sizeof(struct fool_context), 1);
+    
+    if (fool_ctx == NULL)
         return;
-
-    memset(&fool_context[fool_index], 0, sizeof(struct _fool_context));
+    
     if (va_parseConfig("LIBVA_FOOL_POSTP", NULL) == 0) {
         fool_postp = 1;
         va_infoMessage("LIBVA_FOOL_POSTP is on, dummy vaPutSurface\n");
@@ -131,59 +128,58 @@
     }
     if (va_parseConfig("LIBVA_FOOL_ENCODE", &env_value[0]) == 0) {
         fool_codec  |= VA_FOOL_FLAG_ENCODE;
-        fool_context[fool_index].fn_enc = strdup(env_value);
+        fool_ctx->fn_enc = strdup(env_value);
         va_infoMessage("LIBVA_FOOL_ENCODE is on, load encode data from file with patten %s\n",
-                       fool_context[fool_index].fn_enc);
+                       fool_ctx->fn_enc);
     }
     if (va_parseConfig("LIBVA_FOOL_JPEG", &env_value[0]) == 0) {
         fool_codec  |= VA_FOOL_FLAG_JPEG;
-        fool_context[fool_index].fn_jpg = strdup(env_value);
+        fool_ctx->fn_jpg = strdup(env_value);
         va_infoMessage("LIBVA_FOOL_JPEG is on, load encode data from file with patten %s\n",
-                       fool_context[fool_index].fn_jpg);
+                       fool_ctx->fn_jpg);
     }
     
-    if (fool_codec)
-        fool_context[fool_index].dpy = dpy;
+    ((VADisplayContextP)dpy)->vafool = fool_ctx;
 }
 
 
 int va_FoolEnd(VADisplay dpy)
 {
     int i;
-    DPY2INDEX(dpy);
+    DPY2FOOLCTX(dpy);
 
     for (i = 0; i < VABufferTypeMax; i++) {/* free memory */
-        if (fool_context[idx].fool_buf[i])
-            free(fool_context[idx].fool_buf[i]);
+        if (fool_ctx->fool_buf[i])
+            free(fool_ctx->fool_buf[i]);
     }
-    if (fool_context[idx].segbuf_enc)
-        free(fool_context[idx].segbuf_enc);
-    if (fool_context[idx].segbuf_jpg)
-        free(fool_context[idx].segbuf_jpg);
-    if (fool_context[idx].fn_enc)
-        free(fool_context[idx].fn_enc);
-    if (fool_context[idx].fn_jpg)
-        free(fool_context[idx].fn_jpg);
-    
-    memset(&fool_context[idx], 0, sizeof(struct _fool_context));
-    
+    if (fool_ctx->segbuf_enc)
+        free(fool_ctx->segbuf_enc);
+    if (fool_ctx->segbuf_jpg)
+        free(fool_ctx->segbuf_jpg);
+    if (fool_ctx->fn_enc)
+        free(fool_ctx->fn_enc);
+    if (fool_ctx->fn_jpg)
+        free(fool_ctx->fn_jpg);
+
+    free(fool_ctx);
+    ((VADisplayContextP)dpy)->vafool = NULL;
+
     return 0;
 }
 
-
 int va_FoolCreateConfig(
         VADisplay dpy,
         VAProfile profile, 
         VAEntrypoint entrypoint, 
-        VAConfigAttrib *attrib_list,
-        int num_attribs,
-        VAConfigID *config_id /* out */
+        VAConfigAttrib __maybe_unused *attrib_list,
+        int __maybe_unused num_attribs,
+        VAConfigID __maybe_unused *config_id /* out */
 )
 {
-    DPY2INDEX(dpy);
+    DPY2FOOLCTX(dpy);
 
-    fool_context[idx].entrypoint = entrypoint;
-    
+    fool_ctx->entrypoint = entrypoint;
+
     /*
      * check fool_codec to align with current context
      * e.g. fool_codec = decode then for encode, the
@@ -191,38 +187,53 @@
      * which is not desired
      */
     if (((fool_codec & VA_FOOL_FLAG_DECODE) && (entrypoint == VAEntrypointVLD)) ||
-        ((fool_codec & VA_FOOL_FLAG_ENCODE) && (entrypoint == VAEntrypointEncSlice)) ||
         ((fool_codec & VA_FOOL_FLAG_JPEG) && (entrypoint == VAEntrypointEncPicture)))
-        ; /* the fool_codec is meaningful */
-    else
-        fool_codec = 0;
+        fool_ctx->enabled = 1;
+    else if ((fool_codec & VA_FOOL_FLAG_ENCODE) && (entrypoint == VAEntrypointEncSlice)) {
+        /* H264 is desired */
+        if (((profile == VAProfileH264Baseline ||
+              profile == VAProfileH264Main ||
+              profile == VAProfileH264High ||
+              profile == VAProfileH264ConstrainedBaseline)) &&
+            strstr(fool_ctx->fn_enc, "h264"))
+            fool_ctx->enabled = 1;
 
-    return 0; /* driver continue */
+        /* vp8 is desired */
+        if ((profile == VAProfileVP8Version0_3) &&
+            strstr(fool_ctx->fn_enc, "vp8"))
+            fool_ctx->enabled = 1;
+    }
+    if (fool_ctx->enabled)
+        va_infoMessage("FOOL is enabled for this context\n");
+    else
+        va_infoMessage("FOOL is not enabled for this context\n");
+
+    return 0; /* continue */
 }
 
 
 VAStatus va_FoolCreateBuffer(
     VADisplay dpy,
-    VAContextID context,	/* in */
+    VAContextID __maybe_unused context,	/* in */
     VABufferType type,		/* in */
     unsigned int size,		/* in */
     unsigned int num_elements,	/* in */
-    void *data,			/* in */
+    void __maybe_unused *data,			/* in */
     VABufferID *buf_id		/* out */
 )
 {
     unsigned int new_size = size * num_elements;
     unsigned int old_size;
-    DPY2INDEX(dpy);
+    DPY2FOOLCTX_CHK(dpy);
 
-    old_size = fool_context[idx].fool_buf_size[type] * fool_context[idx].fool_buf_element[type];
+    old_size = fool_ctx->fool_buf_size[type] * fool_ctx->fool_buf_element[type];
 
     if (old_size < new_size)
-        fool_context[idx].fool_buf[type] = realloc(fool_context[idx].fool_buf[type], new_size);
+        fool_ctx->fool_buf[type] = realloc(fool_ctx->fool_buf[type], new_size);
     
-    fool_context[idx].fool_buf_size[type] = size;
-    fool_context[idx].fool_buf_element[type] = num_elements;
-    fool_context[idx].fool_buf_count[type]++;
+    fool_ctx->fool_buf_size[type] = size;
+    fool_ctx->fool_buf_element[type] = num_elements;
+    fool_ctx->fool_buf_count[type]++;
     /* because we ignore the vaRenderPicture, 
      * all buffers with same type share same real memory
      * bufferID = (magic number) | type
@@ -240,91 +251,91 @@
     unsigned int *num_elements /* out */
 )
 {
-    unsigned int magic = buf_id & FOOL_BUFID_MASK;
-    DPY2INDEX(dpy);
-
-    if (magic != FOOL_BUFID_MAGIC)
-        return 0;
-
-    *type = buf_id & 0xff;
-    *size = fool_context[idx].fool_buf_size[*type];
-    *num_elements = fool_context[idx].fool_buf_element[*type];;
+    unsigned int magic;
     
-    return 1; /* don't call into driver */
+    DPY2FOOLCTX_CHK(dpy);
+
+    magic = buf_id & FOOL_BUFID_MASK;
+    if (magic != FOOL_BUFID_MAGIC)
+        return 0; /* could be VAImageBufferType from vaDeriveImage */
+    
+    *type = buf_id & 0xff;
+    *size = fool_ctx->fool_buf_size[*type];
+    *num_elements = fool_ctx->fool_buf_element[*type];;
+    
+    return 1; /* fool is valid */
 }
 
-static int va_FoolFillCodedBufEnc(int idx)
+static int va_FoolFillCodedBufEnc(struct fool_context *fool_ctx)
 {
     char file_name[1024];
-    struct stat file_stat;
+    struct stat file_stat = {0};
     VACodedBufferSegment *codedbuf;
     int i, fd = -1;
 
     /* try file_name.file_count, if fail, try file_name.file_count-- */
     for (i=0; i<=1; i++) {
         snprintf(file_name, 1024, "%s.%d",
-                fool_context[idx].fn_enc,
-                fool_context[idx].file_count);
+                 fool_ctx->fn_enc,
+                 fool_ctx->file_count);
 
         if ((fd = open(file_name, O_RDONLY)) != -1) {
             fstat(fd, &file_stat);
-            fool_context[idx].file_count++; /* open next file */
+            fool_ctx->file_count++; /* open next file */
             break;
-        }
-        
-        fool_context[idx].file_count--; /* fall back to previous file */
-        if (fool_context[idx].file_count < 0)
-            fool_context[idx].file_count = 0;
+        } else /* fall back to the first file file */
+            fool_ctx->file_count = 0;
     }
     if (fd != -1) {
-        fool_context[idx].segbuf_enc = realloc(fool_context[idx].segbuf_enc, file_stat.st_size);
-        read(fd, fool_context[idx].segbuf_enc, file_stat.st_size);
+        fool_ctx->segbuf_enc = realloc(fool_ctx->segbuf_enc, file_stat.st_size);
+        read(fd, fool_ctx->segbuf_enc, file_stat.st_size);
         close(fd);
-    }
-    codedbuf = (VACodedBufferSegment *)fool_context[idx].fool_buf[VAEncCodedBufferType];
+    } else
+        va_errorMessage("Open file %s failed:%s\n", file_name, strerror(errno));
+
+    codedbuf = (VACodedBufferSegment *)fool_ctx->fool_buf[VAEncCodedBufferType];
     codedbuf->size = file_stat.st_size;
     codedbuf->bit_offset = 0;
     codedbuf->status = 0;
     codedbuf->reserved = 0;
-    codedbuf->buf = fool_context[idx].segbuf_enc;
+    codedbuf->buf = fool_ctx->segbuf_enc;
     codedbuf->next = NULL;
 
     return 0;
 }
 
-
-static int va_FoolFillCodedBufJPG(int idx)
+static int va_FoolFillCodedBufJPG(struct fool_context *fool_ctx)
 {
-    struct stat file_stat;
+    struct stat file_stat = {0};
     VACodedBufferSegment *codedbuf;
-    int i, fd = -1;
+    int fd = -1;
 
-    if ((fd = open(fool_context[idx].fn_jpg, O_RDONLY)) != -1)
+    if ((fd = open(fool_ctx->fn_jpg, O_RDONLY)) != -1) {
         fstat(fd, &file_stat);
-        
-    if (fd != -1) {
-        fool_context[idx].segbuf_jpg = realloc(fool_context[idx].segbuf_jpg, file_stat.st_size);
-        read(fd, fool_context[idx].segbuf_jpg, file_stat.st_size);
+        fool_ctx->segbuf_jpg = realloc(fool_ctx->segbuf_jpg, file_stat.st_size);
+        read(fd, fool_ctx->segbuf_jpg, file_stat.st_size);
         close(fd);
-    }
-    codedbuf = (VACodedBufferSegment *)fool_context[idx].fool_buf[VAEncCodedBufferType];
+    } else
+        va_errorMessage("Open file %s failed:%s\n", fool_ctx->fn_jpg, strerror(errno));
+
+    codedbuf = (VACodedBufferSegment *)fool_ctx->fool_buf[VAEncCodedBufferType];
     codedbuf->size = file_stat.st_size;
     codedbuf->bit_offset = 0;
     codedbuf->status = 0;
     codedbuf->reserved = 0;
-    codedbuf->buf = fool_context[idx].segbuf_jpg;
+    codedbuf->buf = fool_ctx->segbuf_jpg;
     codedbuf->next = NULL;
 
     return 0;
 }
 
 
-static int va_FoolFillCodedBuf(int idx)
+static int va_FoolFillCodedBuf(struct fool_context *fool_ctx)
 {
-    if (fool_context[idx].entrypoint == VAEntrypointEncSlice)
-        va_FoolFillCodedBufEnc(idx);
-    else if (fool_context[idx].entrypoint == VAEntrypointEncPicture)
-        va_FoolFillCodedBufJPG(idx);
+    if (fool_ctx->entrypoint == VAEntrypointEncSlice)
+        va_FoolFillCodedBufEnc(fool_ctx);
+    else if (fool_ctx->entrypoint == VAEntrypointEncPicture)
+        va_FoolFillCodedBufJPG(fool_ctx);
         
     return 0;
 }
@@ -336,32 +347,27 @@
     void **pbuf 	/* out */
 )
 {
-    unsigned int buftype = buf_id & 0xff;
-    unsigned int magic = buf_id & FOOL_BUFID_MASK;
-    DPY2INDEX(dpy);
+    unsigned int magic, buftype;
+    DPY2FOOLCTX_CHK(dpy);
 
+    magic = buf_id & FOOL_BUFID_MASK;
     if (magic != FOOL_BUFID_MAGIC)
-        return 0;
-
-    /* buf_id is the buffer type */
-    *pbuf = fool_context[idx].fool_buf[buftype];
-
-    /* it is coded buffer, fill the fake segment buf from file */
-    if (*pbuf && (buftype == VAEncCodedBufferType))
-        va_FoolFillCodedBuf(idx);
+        return 0; /* could be VAImageBufferType from vaDeriveImage */
     
-    return 1; /* don't call into driver */
+    buftype = buf_id & 0xff;
+    *pbuf = fool_ctx->fool_buf[buftype];
+
+    /* it is coded buffer, fill coded segment from file */
+    if (*pbuf && (buftype == VAEncCodedBufferType))
+        va_FoolFillCodedBuf(fool_ctx);
+    
+    return 1; /* fool is valid */
 }
 
-VAStatus va_FoolUnmapBuffer(
-        VADisplay dpy,
-        VABufferID buf_id	/* in */
-)
+VAStatus va_FoolCheckContinuity(VADisplay dpy)
 {
-    unsigned int magic = buf_id & FOOL_BUFID_MASK;
+    DPY2FOOLCTX_CHK(dpy);
 
-    if (magic != FOOL_BUFID_MAGIC)
-        return 0;
-
-    return 1;
+    return 1; /* fool is valid */
 }
+
diff --git a/va/va_fool.h b/va/va_fool.h
index 5ea4830..6f4f917 100644
--- a/va/va_fool.h
+++ b/va/va_fool.h
@@ -41,13 +41,10 @@
 
 #define VA_FOOL_FUNC(fool_func,...)            \
     if (fool_codec) {                          \
-        ret = fool_func(__VA_ARGS__);          \
+        if (fool_func(__VA_ARGS__))            \
+            return VA_STATUS_SUCCESS;          \
     }
-#define VA_FOOL_RETURN()                       \
-    if (fool_codec) {                          \
-        return VA_STATUS_SUCCESS;              \
-    }
-
+    
 void va_FoolInit(VADisplay dpy);
 int va_FoolEnd(VADisplay dpy);
 
@@ -77,11 +74,6 @@
     void **pbuf 	/* out */
 );
 
-VAStatus va_FoolUnmapBuffer(
-        VADisplay dpy,
-        VABufferID buf_id	/* in */
-);
-
 VAStatus va_FoolBufferInfo (
     VADisplay dpy,
     VABufferID buf_id,  /* in */
@@ -90,7 +82,8 @@
     unsigned int *num_elements /* out */
 );
     
-    
+VAStatus va_FoolCheckContinuity(VADisplay dpy);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/va/va_tpi.c b/va/va_tpi.c
index 6b67bbe..f4fefe4 100644
--- a/va/va_tpi.c
+++ b/va/va_tpi.c
@@ -58,6 +58,8 @@
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
 
+  printf("WARNING: vaCreateSurfacesWithAttribute will be removed, please use vaCreateSurfaces\n");
+  
   tpi = (struct VADriverVTableTPI *)ctx->vtable_tpi;
   if (tpi && tpi->vaCreateSurfacesWithAttribute) {
       return tpi->vaCreateSurfacesWithAttribute( ctx, width, height, format, num_surfaces, surfaces, attribute_tpi);
@@ -98,20 +100,22 @@
 }
 
 VAStatus vaSetTimestampForSurface(
-    VADisplay dpy,
-    VASurfaceID surface,
-    long long timestamp
+       VADisplay dpy,
+       VASurfaceID surface,
+       long long timestamp
 )
 {
-    VADriverContextP ctx;
-    struct VADriverVTableTPI *tpi;
-    CHECK_DISPLAY(dpy);
-    ctx = CTX(dpy);
+   VADriverContextP ctx;
+   struct VADriverVTableTPI *tpi;
+   CHECK_DISPLAY(dpy);
+   ctx = CTX(dpy);
 
-    tpi = ( struct VADriverVTableTPI *)ctx->vtable_tpi;
-    if (tpi && tpi->vaSetTimestampForSurface) {
-        return tpi->vaSetTimestampForSurface(ctx, surface, timestamp);
-    } else
-        return VA_STATUS_ERROR_UNIMPLEMENTED;
+   tpi = ( struct VADriverVTableTPI *)ctx->vtable_tpi;
+   if (tpi && tpi->vaSetTimestampForSurface) {
+       return tpi->vaSetTimestampForSurface(ctx, surface, timestamp);
+   } else
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
 
 }
+
+
diff --git a/va/va_tpi.h b/va/va_tpi.h
index f05f08a..b7c9c57 100644
--- a/va/va_tpi.h
+++ b/va/va_tpi.h
@@ -44,6 +44,8 @@
     VAExternalMemoryAndroidGrallocBuffer, /* the memory is from Android Gralloc memory, and buffers points
                                            * the gralloc native_handle_t list
                                            */
+    VAExternalMemoryIONSharedFD, /* the memory is allocated from ION and shared as a fd */
+    VAExternalMemoryNoneCacheUserPointer, /* the memory is uncached and allocated from user space*/
 } VASurfaceMemoryType;
 
 typedef struct _VASurfaceAttributeTPI {
@@ -60,7 +62,7 @@
     unsigned int chroma_u_offset; /* U offset from the beginning of the memory */
     unsigned int chroma_v_offset; /* V offset from the beginning of the memory */
     unsigned int count; /* buffer count for surface creation */
-    unsigned int *buffers; /* buffer handles or user pointers */
+    unsigned long *buffers; /* buffer handles or user pointers */
     unsigned int reserved[4]; /* used to pass additional information, like
                                * Android native window pointer
                                */
@@ -85,7 +87,7 @@
     unsigned int flags /* de-interlacing flags */
 );
 
-VAStatus vaSetTimestampForSurface(
+VAStatus vaSetTimestampForSurface (
     VADisplay dpy,
     VASurfaceID surface,
     long long timestamp
diff --git a/va/va_trace.c b/va/va_trace.c
index a6b870e..a70091e 100755
--- a/va/va_trace.c
+++ b/va/va_trace.c
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (c) 2009-2011 Intel Corporation. All Rights Reserved.
  *
@@ -28,7 +29,11 @@
 #include "va_backend.h"
 #include "va_trace.h"
 #include "va_enc_h264.h"
-
+#include "va_enc_jpeg.h"
+#include "va_enc_vp8.h"
+#include "va_dec_jpeg.h"
+#include "va_dec_vp8.h"
+#include "va_vpp.h"
 #include <assert.h>
 #include <stdarg.h>
 #include <stdlib.h>
@@ -45,14 +50,12 @@
 /*
  * Env. to debug some issue, e.g. the decode/encode issue in a video conference scenerio:
  * .LIBVA_TRACE=log_file: general VA parameters saved into log_file
- * .LIBVA_TRACE_BUFDATA: dump VA buffer data into log_file (if not set, just calculate a checksum)
+ * .LIBVA_TRACE_BUFDATA: dump all VA data buffer into log_file
  * .LIBVA_TRACE_CODEDBUF=coded_clip_file: save the coded clip into file coded_clip_file
  * .LIBVA_TRACE_SURFACE=yuv_file: save surface YUV into file yuv_file. Use file name to determine
  *                                decode/encode or jpeg surfaces
  * .LIBVA_TRACE_SURFACE_GEOMETRY=WIDTHxHEIGHT+XOFF+YOFF: only save part of surface context into file
  *                                due to storage bandwidth limitation
- * .LIBVA_TRACE_LOGSIZE=numeric number: truncate the log_file or coded_clip_file, or decoded_yuv_file
- *                                      when the size is bigger than the number
  */
 
 /* global settings */
@@ -60,14 +63,8 @@
 /* LIBVA_TRACE */
 int trace_flag = 0;
 
-/* LIBVA_TRACE_LOGSIZE */
-static unsigned int trace_logsize = 0xffffffff; /* truncate the log when the size is bigger than it */
-
-#define TRACE_CONTEXT_MAX 4
 /* per context settings */
-static struct _trace_context {
-    VADisplay dpy; /* should use context as the key */
-    
+struct trace_context {
     /* LIBVA_TRACE */
     FILE *trace_fp_log; /* save the log into a file */
     char *trace_log_fn; /* file name */
@@ -85,7 +82,6 @@
     VASurfaceID  trace_rendertarget; /* current render target */
     VAProfile trace_profile; /* current profile for buffers */
     VAEntrypoint trace_entrypoint; /* current entrypoint */
-    VABufferID trace_codedbuf;
     
     unsigned int trace_frame_no; /* current frame NO */
     unsigned int trace_slice_no; /* current slice NO */
@@ -98,20 +94,17 @@
 
     unsigned int trace_frame_width; /* current frame width */
     unsigned int trace_frame_height; /* current frame height */
-    unsigned int trace_sequence_start; /* get a new sequence for encoding or not */
-} trace_context[TRACE_CONTEXT_MAX]; /* trace five context at the same time */
+};
 
-#define DPY2INDEX(dpy)                                  \
-    int idx;                                            \
-                                                        \
-    for (idx = 0; idx < TRACE_CONTEXT_MAX; idx++)       \
-        if (trace_context[idx].dpy == dpy)              \
-            break;                                      \
-                                                        \
-    if (idx == TRACE_CONTEXT_MAX)                       \
-        return;
+#define TRACE_CTX(dpy) ((struct trace_context *)((VADisplayContextP)dpy)->vatrace)
 
-#define TRACE_FUNCNAME(idx)    va_TraceMsg(idx, "==========%s\n", __func__); 
+#define DPY2TRACECTX(dpy)                               \
+    struct trace_context *trace_ctx = TRACE_CTX(dpy);   \
+                                                        \
+    if (trace_ctx == NULL)                              \
+        return;                                         \
+
+#define TRACE_FUNCNAME(idx)    va_TraceMsg(trace_ctx, "==========%s\n", __func__); 
 
 /* Prototype declarations (functions defined in va.c) */
 
@@ -153,9 +146,9 @@
                                                         \
     snprintf(env_value+tmp,                             \
              left,                                      \
-             ".%04d.%05d",                              \
-             trace_index,                               \
-             suffix);                                   \
+             ".%04d.%08lx",                             \
+             suffix,                                    \
+             (unsigned long)trace_ctx);                 \
 } while (0)
 
 void va_TraceInit(VADisplay dpy)
@@ -164,34 +157,25 @@
     unsigned short suffix = 0xffff & ((unsigned int)time(NULL));
     int trace_index = 0;
     FILE *tmp;    
-    
-    for (trace_index = 0; trace_index < TRACE_CONTEXT_MAX; trace_index++)
-        if (trace_context[trace_index].dpy == 0)
-            break;
+    struct trace_context *trace_ctx = calloc(sizeof(struct trace_context), 1);
 
-    if (trace_index == TRACE_CONTEXT_MAX)
+    if (trace_ctx == NULL)
         return;
-
-    memset(&trace_context[trace_index], 0, sizeof(struct _trace_context));
+    
     if (va_parseConfig("LIBVA_TRACE", &env_value[0]) == 0) {
         FILE_NAME_SUFFIX(env_value);
-        trace_context[trace_index].trace_log_fn = strdup(env_value);
+        trace_ctx->trace_log_fn = strdup(env_value);
         
         tmp = fopen(env_value, "w");
         if (tmp) {
-            trace_context[trace_index].trace_fp_log = tmp;
-            va_infoMessage("LIBVA_TRACE is on, save log into %s\n", trace_context[trace_index].trace_log_fn);
+            trace_ctx->trace_fp_log = tmp;
+            va_infoMessage("LIBVA_TRACE is on, save log into %s\n", trace_ctx->trace_log_fn);
             trace_flag = VA_TRACE_FLAG_LOG;
         } else
             va_errorMessage("Open file %s failed (%s)\n", env_value, strerror(errno));
     }
 
     /* may re-get the global settings for multiple context */
-    if (va_parseConfig("LIBVA_TRACE_LOGSIZE", &env_value[0]) == 0) {
-        trace_logsize = atoi(env_value);
-        va_infoMessage("LIBVA_TRACE_LOGSIZE is on, size is %d\n", trace_logsize);
-    }
-
     if ((trace_flag & VA_TRACE_FLAG_LOG) && (va_parseConfig("LIBVA_TRACE_BUFDATA", NULL) == 0)) {
         trace_flag |= VA_TRACE_FLAG_BUFDATA;
         va_infoMessage("LIBVA_TRACE_BUFDATA is on, dump buffer into log file\n");
@@ -200,18 +184,18 @@
     /* per-context setting */
     if (va_parseConfig("LIBVA_TRACE_CODEDBUF", &env_value[0]) == 0) {
         FILE_NAME_SUFFIX(env_value);
-        trace_context[trace_index].trace_codedbuf_fn = strdup(env_value);
+        trace_ctx->trace_codedbuf_fn = strdup(env_value);
         va_infoMessage("LIBVA_TRACE_CODEDBUF is on, save codedbuf into log file %s\n",
-                       trace_context[trace_index].trace_codedbuf_fn);
+                       trace_ctx->trace_codedbuf_fn);
         trace_flag |= VA_TRACE_FLAG_CODEDBUF;
     }
 
     if (va_parseConfig("LIBVA_TRACE_SURFACE", &env_value[0]) == 0) {
         FILE_NAME_SUFFIX(env_value);
-        trace_context[trace_index].trace_surface_fn = strdup(env_value);
+        trace_ctx->trace_surface_fn = strdup(env_value);
 
         va_infoMessage("LIBVA_TRACE_SURFACE is on, save surface into %s\n",
-                       trace_context[trace_index].trace_surface_fn);
+                       trace_ctx->trace_surface_fn);
 
         /* for surface data dump, it is time-consume, and may
          * cause some side-effect, so only trace the needed surfaces
@@ -229,124 +213,71 @@
         if (va_parseConfig("LIBVA_TRACE_SURFACE_GEOMETRY", &env_value[0]) == 0) {
             char *p = env_value, *q;
 
-            trace_context[trace_index].trace_surface_width = strtod(p, &q);
+            trace_ctx->trace_surface_width = strtod(p, &q);
             p = q+1; /* skip "x" */
-            trace_context[trace_index].trace_surface_height = strtod(p, &q);
+            trace_ctx->trace_surface_height = strtod(p, &q);
             p = q+1; /* skip "+" */
-            trace_context[trace_index].trace_surface_xoff = strtod(p, &q);
+            trace_ctx->trace_surface_xoff = strtod(p, &q);
             p = q+1; /* skip "+" */
-            trace_context[trace_index].trace_surface_yoff = strtod(p, &q);
+            trace_ctx->trace_surface_yoff = strtod(p, &q);
 
             va_infoMessage("LIBVA_TRACE_SURFACE_GEOMETRY is on, only dump surface %dx%d+%d+%d content\n",
-                           trace_context[trace_index].trace_surface_width,
-                           trace_context[trace_index].trace_surface_height,
-                           trace_context[trace_index].trace_surface_xoff,
-                           trace_context[trace_index].trace_surface_yoff);
+                           trace_ctx->trace_surface_width,
+                           trace_ctx->trace_surface_height,
+                           trace_ctx->trace_surface_xoff,
+                           trace_ctx->trace_surface_yoff);
         }
     }
 
-    trace_context[trace_index].dpy = dpy;
+    ((VADisplayContextP)dpy)->vatrace = trace_ctx;
 }
 
 
 void va_TraceEnd(VADisplay dpy)
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
     
-    if (trace_context[idx].trace_fp_log)
-        fclose(trace_context[idx].trace_fp_log);
+    if (trace_ctx->trace_fp_log)
+        fclose(trace_ctx->trace_fp_log);
     
-    if (trace_context[idx].trace_fp_codedbuf)
-        fclose(trace_context[idx].trace_fp_codedbuf);
+    if (trace_ctx->trace_fp_codedbuf)
+        fclose(trace_ctx->trace_fp_codedbuf);
     
-    if (trace_context[idx].trace_fp_surface)
-        fclose(trace_context[idx].trace_fp_surface);
+    if (trace_ctx->trace_fp_surface)
+        fclose(trace_ctx->trace_fp_surface);
 
-    if (trace_context[idx].trace_log_fn)
-        free(trace_context[idx].trace_log_fn);
+    if (trace_ctx->trace_log_fn)
+        free(trace_ctx->trace_log_fn);
     
-    if (trace_context[idx].trace_codedbuf_fn)
-        free(trace_context[idx].trace_codedbuf_fn);
+    if (trace_ctx->trace_codedbuf_fn)
+        free(trace_ctx->trace_codedbuf_fn);
     
-    if (trace_context[idx].trace_surface_fn)
-        free(trace_context[idx].trace_surface_fn);
+    if (trace_ctx->trace_surface_fn)
+        free(trace_ctx->trace_surface_fn);
     
-    memset(&trace_context[idx], 0, sizeof(struct _trace_context));
+    free(trace_ctx);
+    ((VADisplayContextP)dpy)->vatrace = NULL;
 }
 
 
-static unsigned int file_size(FILE *fp)
-{
-    struct stat buf;
-
-    fstat(fileno(fp), &buf);
-
-    return buf.st_size;
-}
-
-
-static void truncate_file(FILE *fp)
-{
-    ftruncate(fileno(fp), 0);
-    rewind(fp);
-}
-
-void va_TraceMsg(int idx, const char *msg, ...)
+void va_TraceMsg(struct trace_context *trace_ctx, const char *msg, ...)
 {
     va_list args;
 
     if (!(trace_flag & VA_TRACE_FLAG_LOG))
         return;
 
-    if (file_size(trace_context[idx].trace_fp_log) >= trace_logsize)
-        truncate_file(trace_context[idx].trace_fp_log);
     if (msg)  {
+        struct timeval tv;
+
+        if (gettimeofday(&tv, NULL) == 0)
+            fprintf(trace_ctx->trace_fp_log, "[%04d.%06d] ",
+                    (unsigned int)tv.tv_sec & 0xffff, (unsigned int)tv.tv_usec);
         va_start(args, msg);
-        vfprintf(trace_context[idx].trace_fp_log, msg, args);
+        vfprintf(trace_ctx->trace_fp_log, msg, args);
         va_end(args);
     } else
-        fflush(trace_context[idx].trace_fp_log);
-}
-
-void va_TraceCodedBuf(VADisplay dpy)
-{
-    VACodedBufferSegment *buf_list = NULL;
-    VAStatus va_status;
-    unsigned char check_sum = 0;
-    DPY2INDEX(dpy);
-    
-    /* can only truncate at a sequence boudary */
-    if (((file_size(trace_context[idx].trace_fp_log) >= trace_logsize))
-        && trace_context[idx].trace_sequence_start) {
-        va_TraceMsg(idx, "==========truncate file %s\n", trace_context[idx].trace_codedbuf_fn);
-        truncate_file(trace_context[idx].trace_fp_log);
-    }
-    
-
-    trace_context[idx].trace_sequence_start = 0; /* only truncate coded file when meet next new sequence */
-    
-    va_status = vaMapBuffer(dpy, trace_context[idx].trace_codedbuf, (void **)(&buf_list));
-    if (va_status != VA_STATUS_SUCCESS)
-        return;
-
-    va_TraceMsg(idx, "==========dump codedbuf into file %s\n", trace_context[idx].trace_codedbuf_fn);
-    
-    while (buf_list != NULL) {
-        unsigned int i;
-        
-        va_TraceMsg(idx, "\tsize = %d\n", buf_list->size);
-        if (trace_context[idx].trace_fp_codedbuf)
-            fwrite(buf_list->buf, buf_list->size, 1, trace_context[idx].trace_fp_codedbuf);
-
-        for (i=0; i<buf_list->size; i++)
-            check_sum ^= *((unsigned char *)buf_list->buf + i);
-
-        buf_list = buf_list->next;
-    }
-    vaUnmapBuffer(dpy,trace_context[idx].trace_codedbuf);
-    
-    va_TraceMsg(idx, "\tchecksum = 0x%02x\n", check_sum);
-    va_TraceMsg(idx, NULL);
+        fflush(trace_ctx->trace_fp_log);
 }
 
 
@@ -365,86 +296,84 @@
     unsigned char *Y_data, *UV_data, *tmp;
     VAStatus va_status;
     unsigned char check_sum = 0;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    va_TraceMsg(idx, "==========dump surface data in file %s\n", trace_context[idx].trace_surface_fn);
+    if (!trace_ctx->trace_fp_surface)
+        return;
 
-    if ((file_size(trace_context[idx].trace_fp_surface) >= trace_logsize)) {
-        va_TraceMsg(idx, "==========truncate file %s\n", trace_context[idx].trace_surface_fn);
-        truncate_file(trace_context[idx].trace_fp_surface);
-    }
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "==========dump surface data in file %s\n", trace_ctx->trace_surface_fn);
+
+    va_TraceMsg(trace_ctx, NULL);
 
     va_status = vaLockSurface(
         dpy,
-        trace_context[idx].trace_rendertarget,
+        trace_ctx->trace_rendertarget,
         &fourcc,
         &luma_stride, &chroma_u_stride, &chroma_v_stride,
         &luma_offset, &chroma_u_offset, &chroma_v_offset,
         &buffer_name, &buffer);
 
     if (va_status != VA_STATUS_SUCCESS) {
-        va_TraceMsg(idx, "Error:vaLockSurface failed\n");
+        va_TraceMsg(trace_ctx, "Error:vaLockSurface failed\n");
         return;
     }
 
-    va_TraceMsg(idx, "\tfourcc = 0x%08x\n", fourcc);
-    va_TraceMsg(idx, "\twidth = %d\n", trace_context[idx].trace_frame_width);
-    va_TraceMsg(idx, "\theight = %d\n", trace_context[idx].trace_frame_height);
-    va_TraceMsg(idx, "\tluma_stride = %d\n", luma_stride);
-    va_TraceMsg(idx, "\tchroma_u_stride = %d\n", chroma_u_stride);
-    va_TraceMsg(idx, "\tchroma_v_stride = %d\n", chroma_v_stride);
-    va_TraceMsg(idx, "\tluma_offset = %d\n", luma_offset);
-    va_TraceMsg(idx, "\tchroma_u_offset = %d\n", chroma_u_offset);
-    va_TraceMsg(idx, "\tchroma_v_offset = %d\n", chroma_v_offset);
+    va_TraceMsg(trace_ctx, "\tfourcc = 0x%08x\n", fourcc);
+    va_TraceMsg(trace_ctx, "\twidth = %d\n", trace_ctx->trace_frame_width);
+    va_TraceMsg(trace_ctx, "\theight = %d\n", trace_ctx->trace_frame_height);
+    va_TraceMsg(trace_ctx, "\tluma_stride = %d\n", luma_stride);
+    va_TraceMsg(trace_ctx, "\tchroma_u_stride = %d\n", chroma_u_stride);
+    va_TraceMsg(trace_ctx, "\tchroma_v_stride = %d\n", chroma_v_stride);
+    va_TraceMsg(trace_ctx, "\tluma_offset = %d\n", luma_offset);
+    va_TraceMsg(trace_ctx, "\tchroma_u_offset = %d\n", chroma_u_offset);
+    va_TraceMsg(trace_ctx, "\tchroma_v_offset = %d\n", chroma_v_offset);
 
     if (buffer == NULL) {
-        va_TraceMsg(idx, "Error:vaLockSurface return NULL buffer\n");
-        va_TraceMsg(idx, NULL);
+        va_TraceMsg(trace_ctx, "Error:vaLockSurface return NULL buffer\n");
+        va_TraceMsg(trace_ctx, NULL);
 
-        vaUnlockSurface(dpy, trace_context[idx].trace_rendertarget);
+        vaUnlockSurface(dpy, trace_ctx->trace_rendertarget);
         return;
     }
-    va_TraceMsg(idx, "\tbuffer location = 0x%08x\n", buffer);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "\tbuffer location = 0x%08x\n", buffer);
+    va_TraceMsg(trace_ctx, NULL);
 
     Y_data = (unsigned char*)buffer;
     UV_data = (unsigned char*)buffer + chroma_u_offset;
 
-    tmp = Y_data + luma_stride * trace_context[idx].trace_surface_yoff;
-    for (i=0; i<trace_context[idx].trace_surface_height; i++) {
-        if (trace_context[idx].trace_fp_surface)
-            fwrite(tmp + trace_context[idx].trace_surface_xoff,
-                   trace_context[idx].trace_surface_width,
-                   1, trace_context[idx].trace_fp_surface);
+    tmp = Y_data + luma_stride * trace_ctx->trace_surface_yoff;
+    for (i=0; i<trace_ctx->trace_surface_height; i++) {
+        fwrite(tmp + trace_ctx->trace_surface_xoff,
+               trace_ctx->trace_surface_width,
+               1, trace_ctx->trace_fp_surface);
         
         tmp += luma_stride;
     }
-    tmp = UV_data + chroma_u_stride * trace_context[idx].trace_surface_yoff;
+    tmp = UV_data + chroma_u_stride * trace_ctx->trace_surface_yoff / 2;
     if (fourcc == VA_FOURCC_NV12) {
-        for (i=0; i<trace_context[idx].trace_surface_height/2; i++) {
-            if (trace_context[idx].trace_fp_surface)
-                fwrite(tmp + trace_context[idx].trace_surface_xoff,
-                       trace_context[idx].trace_surface_width,
-                       1, trace_context[idx].trace_fp_surface);
+        for (i=0; i<trace_ctx->trace_surface_height/2; i++) {
+            fwrite(tmp + trace_ctx->trace_surface_xoff,
+                   trace_ctx->trace_surface_width,
+                   1, trace_ctx->trace_fp_surface);
             
             tmp += chroma_u_stride;
         }
     }
 
-    vaUnlockSurface(dpy, trace_context[idx].trace_rendertarget);
+    vaUnlockSurface(dpy, trace_ctx->trace_rendertarget);
 
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 
 void va_TraceInitialize (
     VADisplay dpy,
-    int *major_version,     /* out */
-    int *minor_version      /* out */
+    int __maybe_unused *major_version,     /* out */
+    int __maybe_unused *minor_version      /* out */
 )
 {
-    DPY2INDEX(dpy);    
+    DPY2TRACECTX(dpy);
+
     TRACE_FUNCNAME(idx);
 }
 
@@ -452,7 +381,7 @@
     VADisplay dpy
 )
 {
-    DPY2INDEX(dpy);    
+    DPY2TRACECTX(dpy);    
     TRACE_FUNCNAME(idx);
 }
 
@@ -463,62 +392,130 @@
     VAEntrypoint entrypoint, 
     VAConfigAttrib *attrib_list,
     int num_attribs,
-    VAConfigID *config_id /* out */
+    VAConfigID __maybe_unused *config_id /* out */
 )
 {
     int i;
     int encode, decode, jpeg;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
-    
-    va_TraceMsg(idx, "\tprofile = %d\n", profile);
-    va_TraceMsg(idx, "\tentrypoint = %d\n", entrypoint);
-    va_TraceMsg(idx, "\tnum_attribs = %d\n", num_attribs);
-    for (i = 0; i < num_attribs; i++) {
-        va_TraceMsg(idx, "\t\tattrib_list[%d].type = 0x%08x\n", i, attrib_list[i].type);
-        va_TraceMsg(idx, "\t\tattrib_list[%d].value = 0x%08x\n", i, attrib_list[i].value);
-    }
-    va_TraceMsg(idx, NULL);
 
-    trace_context[idx].trace_profile = profile;
-    trace_context[idx].trace_entrypoint = entrypoint;
+    va_TraceMsg(trace_ctx, "\tprofile = %d\n", profile);
+    va_TraceMsg(trace_ctx, "\tentrypoint = %d\n", entrypoint);
+    va_TraceMsg(trace_ctx, "\tnum_attribs = %d\n", num_attribs);
+    if (attrib_list) {
+        for (i = 0; i < num_attribs; i++) {
+            va_TraceMsg(trace_ctx, "\t\tattrib_list[%d].type = 0x%08x\n", i, attrib_list[i].type);
+            va_TraceMsg(trace_ctx, "\t\tattrib_list[%d].value = 0x%08x\n", i, attrib_list[i].value);
+        }
+    }
+    va_TraceMsg(trace_ctx, NULL);
+
+    trace_ctx->trace_profile = profile;
+    trace_ctx->trace_entrypoint = entrypoint;
 
     /* avoid to create so many empty files */
-    encode = (trace_context[idx].trace_entrypoint == VAEntrypointEncSlice);
-    decode = (trace_context[idx].trace_entrypoint == VAEntrypointVLD);
-    jpeg = (trace_context[idx].trace_entrypoint == VAEntrypointEncPicture);
+    encode = (trace_ctx->trace_entrypoint == VAEntrypointEncSlice);
+    decode = (trace_ctx->trace_entrypoint == VAEntrypointVLD);
+    jpeg = (trace_ctx->trace_entrypoint == VAEntrypointEncPicture);
     if ((encode && (trace_flag & VA_TRACE_FLAG_SURFACE_ENCODE)) ||
         (decode && (trace_flag & VA_TRACE_FLAG_SURFACE_DECODE)) ||
         (jpeg && (trace_flag & VA_TRACE_FLAG_SURFACE_JPEG))) {
-        FILE *tmp = fopen(trace_context[idx].trace_surface_fn, "w");
+        FILE *tmp = fopen(trace_ctx->trace_surface_fn, "w");
         
         if (tmp)
-            trace_context[idx].trace_fp_surface = tmp;
+            trace_ctx->trace_fp_surface = tmp;
         else {
             va_errorMessage("Open file %s failed (%s)\n",
-                            trace_context[idx].trace_surface_fn,
+                            trace_ctx->trace_surface_fn,
                             strerror(errno));
-            trace_context[idx].trace_fp_surface = NULL;
+            trace_ctx->trace_fp_surface = NULL;
             trace_flag &= ~(VA_TRACE_FLAG_SURFACE);
         }
     }
 
     if (encode && (trace_flag & VA_TRACE_FLAG_CODEDBUF)) {
-        FILE *tmp = fopen(trace_context[idx].trace_codedbuf_fn, "w");
+        FILE *tmp = fopen(trace_ctx->trace_codedbuf_fn, "w");
         
         if (tmp)
-            trace_context[idx].trace_fp_codedbuf = tmp;
+            trace_ctx->trace_fp_codedbuf = tmp;
         else {
             va_errorMessage("Open file %s failed (%s)\n",
-                            trace_context[idx].trace_codedbuf_fn,
+                            trace_ctx->trace_codedbuf_fn,
                             strerror(errno));
-            trace_context[idx].trace_fp_codedbuf = NULL;
+            trace_ctx->trace_fp_codedbuf = NULL;
             trace_flag &= ~VA_TRACE_FLAG_CODEDBUF;
         }
     }
 }
 
+static void va_TraceSurfaceAttributes(
+    struct trace_context *trace_ctx,
+    VASurfaceAttrib    *attrib_list,
+    unsigned int       *num_attribs
+)
+{
+    int i, num;
+    VASurfaceAttrib *p;
+    
+    if (!attrib_list || !num_attribs)
+        return;
+    
+    p = attrib_list;
+    num = *num_attribs;
+    if (num > VASurfaceAttribCount)
+        num = VASurfaceAttribCount;
+
+    for (i=0; i<num; i++) {
+        int type = p->value.type;
+        
+        va_TraceMsg(trace_ctx, "\tattrib_list[%i] =\n", i);
+        
+        va_TraceMsg(trace_ctx, "\t\ttype = %d\n", p->type);
+        va_TraceMsg(trace_ctx, "\t\tflags = %d\n", p->flags);
+        va_TraceMsg(trace_ctx, "\t\tvalue.type = %d\n", type);
+        switch (type) {
+        case VAGenericValueTypeInteger:
+            va_TraceMsg(trace_ctx, "\t\tvalue.value.i = 0x%08x\n", p->value.value.i);
+            break;
+        case VAGenericValueTypeFloat:
+            va_TraceMsg(trace_ctx, "\t\tvalue.value.f = %f\n", p->value.value.f);
+            break;
+        case VAGenericValueTypePointer:
+            va_TraceMsg(trace_ctx, "\t\tvalue.value.p = %p\n", p->value.value.p);
+            if ((p->type == VASurfaceAttribExternalBufferDescriptor) && p->value.value.p) {
+                VASurfaceAttribExternalBuffers *tmp = (VASurfaceAttribExternalBuffers *) p->value.value.p;
+                unsigned int j;
+                
+                va_TraceMsg(trace_ctx, "\t\t--VASurfaceAttribExternalBufferDescriptor\n");
+                va_TraceMsg(trace_ctx, "\t\t  pixel_format=0x%08x\n", tmp->pixel_format);
+                va_TraceMsg(trace_ctx, "\t\t  width=%d\n", tmp->width);
+                va_TraceMsg(trace_ctx, "\t\t  height=%d\n", tmp->height);
+                va_TraceMsg(trace_ctx, "\t\t  data_size=%d\n", tmp->data_size);
+                va_TraceMsg(trace_ctx, "\t\t  num_planes=%d\n", tmp->num_planes);
+                va_TraceMsg(trace_ctx, "\t\t  pitches[4]=%d %d %d %d\n",
+                            tmp->pitches[0], tmp->pitches[1], tmp->pitches[2], tmp->pitches[3]);
+                va_TraceMsg(trace_ctx, "\t\t  offsets[4]=%d %d %d %d\n",
+                            tmp->offsets[0], tmp->offsets[1], tmp->offsets[2], tmp->offsets[3]);
+                va_TraceMsg(trace_ctx, "\t\t  flags=0x%08x\n", tmp->flags);
+                va_TraceMsg(trace_ctx, "\t\t  num_buffers=0x%08x\n", tmp->num_buffers);
+                va_TraceMsg(trace_ctx, "\t\t  buffers=%p\n", tmp->buffers);
+                for (j = 0; j < tmp->num_buffers; j++) {
+                    va_TraceMsg(trace_ctx, "\t\t\tbuffers[%d]=%p\n", j, tmp->buffers[j]);
+                }
+            }
+            break;
+        case VAGenericValueTypeFunc:
+            va_TraceMsg(trace_ctx, "\t\tvalue.value.fn = %p\n", p->value.value.fn);
+            break;
+        default:
+            break;
+        }
+
+        p++;
+    }
+}
 
 void va_TraceCreateSurfaces(
     VADisplay dpy,
@@ -532,19 +529,43 @@
 )
 {
     int i;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
     
-    va_TraceMsg(idx, "\twidth = %d\n", width);
-    va_TraceMsg(idx, "\theight = %d\n", height);
-    va_TraceMsg(idx, "\tformat = %d\n", format);
-    va_TraceMsg(idx, "\tnum_surfaces = %d\n", num_surfaces);
+    va_TraceMsg(trace_ctx, "\twidth = %d\n", width);
+    va_TraceMsg(trace_ctx, "\theight = %d\n", height);
+    va_TraceMsg(trace_ctx, "\tformat = %d\n", format);
+    va_TraceMsg(trace_ctx, "\tnum_surfaces = %d\n", num_surfaces);
 
-    for (i = 0; i < num_surfaces; i++)
-        va_TraceMsg(idx, "\t\tsurfaces[%d] = 0x%08x\n", i, surfaces[i]);
+    if (surfaces) {
+        for (i = 0; i < num_surfaces; i++)
+            va_TraceMsg(trace_ctx, "\t\tsurfaces[%d] = 0x%08x\n", i, surfaces[i]);
+    }
+    
+    va_TraceSurfaceAttributes(trace_ctx, attrib_list, &num_attribs);
 
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
+}
+
+
+void va_TraceDestroySurfaces(
+    VADisplay dpy,
+    VASurfaceID *surface_list,
+    int num_surfaces
+)
+{
+    int i;
+    DPY2TRACECTX(dpy);
+
+    TRACE_FUNCNAME(idx);
+
+    if (surface_list) {
+        for (i = 0; i < num_surfaces; i++)
+            va_TraceMsg(trace_ctx, "\t\tsurfaces[%d] = 0x%08x\n", i, surface_list[i]);
+    }
+    
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 
@@ -560,31 +581,35 @@
 )
 {
     int i;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
+
+    va_TraceMsg(trace_ctx, "\tconfig = 0x%08x\n", config_id);
+    va_TraceMsg(trace_ctx, "\twidth = %d\n", picture_width);
+    va_TraceMsg(trace_ctx, "\theight = %d\n", picture_height);
+    va_TraceMsg(trace_ctx, "\tflag = 0x%08x\n", flag);
+    va_TraceMsg(trace_ctx, "\tnum_render_targets = %d\n", num_render_targets);
+    if (render_targets) {
+        for (i=0; i<num_render_targets; i++)
+            va_TraceMsg(trace_ctx, "\t\trender_targets[%d] = 0x%08x\n", i, render_targets[i]);
+    }
+    if (context) {
+        va_TraceMsg(trace_ctx, "\tcontext = 0x%08x\n", *context);
+        trace_ctx->trace_context = *context;
+    } else
+        trace_ctx->trace_context = VA_INVALID_ID;
     
-    va_TraceMsg(idx, "\twidth = %d\n", picture_width);
-    va_TraceMsg(idx, "\theight = %d\n", picture_height);
-    va_TraceMsg(idx, "\tflag = 0x%08x\n", flag);
-    va_TraceMsg(idx, "\tnum_render_targets = %d\n", num_render_targets);
-    for (i=0; i<num_render_targets; i++)
-        va_TraceMsg(idx, "\t\trender_targets[%d] = 0x%08x\n", i, render_targets[i]);
-    va_TraceMsg(idx, "\tcontext = 0x%08x\n", *context);
-    va_TraceMsg(idx, NULL);
+    trace_ctx->trace_frame_no = 0;
+    trace_ctx->trace_slice_no = 0;
 
-    trace_context[idx].trace_context = *context;
+    trace_ctx->trace_frame_width = picture_width;
+    trace_ctx->trace_frame_height = picture_height;
 
-    trace_context[idx].trace_frame_no = 0;
-    trace_context[idx].trace_slice_no = 0;
-
-    trace_context[idx].trace_frame_width = picture_width;
-    trace_context[idx].trace_frame_height = picture_height;
-
-    if (trace_context[idx].trace_surface_width == 0)
-        trace_context[idx].trace_surface_width = picture_width;
-    if (trace_context[idx].trace_surface_height == 0)
-        trace_context[idx].trace_surface_height = picture_height;
+    if (trace_ctx->trace_surface_width == 0)
+        trace_ctx->trace_surface_width = picture_width;
+    if (trace_ctx->trace_surface_height == 0)
+        trace_ctx->trace_surface_height = picture_height;
 }
 
 
@@ -602,15 +627,80 @@
     case VAResidualDataBufferType: return "VAResidualDataBufferType";
     case VADeblockingParameterBufferType: return "VADeblockingParameterBufferType";
     case VAImageBufferType: return "VAImageBufferType";
+    case VAQMatrixBufferType: return "VAQMatrixBufferType";
+    case VAHuffmanTableBufferType: return "VAHuffmanTableBufferType";
+    case VAProbabilityBufferType: return "VAProbabilityBufferType";
+/* Following are encode buffer types */
     case VAEncCodedBufferType: return "VAEncCodedBufferType";
     case VAEncSequenceParameterBufferType: return "VAEncSequenceParameterBufferType";
     case VAEncPictureParameterBufferType: return "VAEncPictureParameterBufferType";
     case VAEncSliceParameterBufferType: return "VAEncSliceParameterBufferType";
+    case VAEncPackedHeaderParameterBufferType: return "VAEncPackedHeaderParameterBufferType";
+    case VAEncPackedHeaderDataBufferType: return "VAEncPackedHeaderDataBufferType";
     case VAEncMiscParameterBufferType: return "VAEncMiscParameterBufferType";
+    case VAEncMacroblockParameterBufferType: return "VAEncMacroblockParameterBufferType";
+    case VAProcPipelineParameterBufferType: return "VAProcPipelineParameterBufferType";
+    case VAProcFilterParameterBufferType: return "VAProcFilterParameterBufferType";
     default: return "UnknowBuffer";
     }
 }
 
+void va_TraceCreateBuffer (
+    VADisplay dpy,
+    VAContextID __maybe_unused context,	/* in */
+    VABufferType type,		/* in */
+    unsigned int size,		/* in */
+    unsigned int num_elements,	/* in */
+    void __maybe_unused *data,			/* in */
+    VABufferID *buf_id		/* out */
+)
+{
+    DPY2TRACECTX(dpy);
+
+    /* only trace CodedBuffer */
+    if (type != VAEncCodedBufferType)
+        return;
+
+    TRACE_FUNCNAME(idx);
+    va_TraceMsg(trace_ctx, "\tbuf_type=%s\n", buffer_type_to_string(type));
+    if (buf_id)
+        va_TraceMsg(trace_ctx, "\tbuf_id=0x%x\n", *buf_id);
+    va_TraceMsg(trace_ctx, "\tsize=%d\n", size);
+    va_TraceMsg(trace_ctx, "\tnum_elements=%d\n", num_elements);
+    
+    va_TraceMsg(trace_ctx, NULL);
+}
+
+void va_TraceDestroyBuffer (
+    VADisplay dpy,
+    VABufferID buf_id    /* in */
+)
+{
+    VABufferType type;
+    unsigned int size;
+    unsigned int num_elements;
+    
+    VACodedBufferSegment *buf_list;
+    int i = 0;
+    
+    DPY2TRACECTX(dpy);
+
+    vaBufferInfo(dpy, trace_ctx->trace_context, buf_id, &type, &size, &num_elements);    
+    
+    /* only trace CodedBuffer */
+    if (type != VAEncCodedBufferType)
+        return;
+
+    TRACE_FUNCNAME(idx);
+    va_TraceMsg(trace_ctx, "\tbuf_type=%s\n", buffer_type_to_string(type));
+    va_TraceMsg(trace_ctx, "\tbuf_id=0x%x\n", buf_id);
+    va_TraceMsg(trace_ctx, "\tsize=%d\n", size);
+    va_TraceMsg(trace_ctx, "\tnum_elements=%d\n", num_elements);
+    
+    va_TraceMsg(trace_ctx, NULL);
+}
+
+
 void va_TraceMapBuffer (
     VADisplay dpy,
     VABufferID buf_id,    /* in */
@@ -624,33 +714,38 @@
     VACodedBufferSegment *buf_list;
     int i = 0;
     
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    vaBufferInfo(dpy, trace_context[idx].trace_context, buf_id, &type, &size, &num_elements);    
-    /*
-      va_TraceMsg(idx, "\tbuf_id=0x%x\n", buf_id);
-      va_TraceMsg(idx, "\tbuf_type=%s\n", buffer_type_to_string(type));
-      va_TraceMsg(idx, "\tbuf_size=%s\n", size);
-      va_TraceMsg(idx, "\tbuf_elements=%s\n", &num_elements);
-    */
+    vaBufferInfo(dpy, trace_ctx->trace_context, buf_id, &type, &size, &num_elements);    
     
     /* only trace CodedBuffer */
     if (type != VAEncCodedBufferType)
         return;
+
+    TRACE_FUNCNAME(idx);
+    va_TraceMsg(trace_ctx, "\tbuf_id=0x%x\n", buf_id);
+    va_TraceMsg(trace_ctx, "\tbuf_type=%s\n", buffer_type_to_string(type));
+    if ((pbuf == NULL) || (*pbuf == NULL))
+        return;
     
     buf_list = (VACodedBufferSegment *)(*pbuf);
     while (buf_list != NULL) {
-        va_TraceMsg(idx, "\tCodedbuf[%d] =\n", i++);
+        va_TraceMsg(trace_ctx, "\tCodedbuf[%d] =\n", i++);
         
-        va_TraceMsg(idx, "\t   size = %d\n", buf_list->size);
-        va_TraceMsg(idx, "\t   bit_offset = %d\n", buf_list->bit_offset);
-        va_TraceMsg(idx, "\t   status = 0x%08x\n", buf_list->status);
-        va_TraceMsg(idx, "\t   reserved = 0x%08x\n", buf_list->reserved);
-        va_TraceMsg(idx, "\t   buf = 0x%08x\n", buf_list->buf);
+        va_TraceMsg(trace_ctx, "\t   size = %d\n", buf_list->size);
+        va_TraceMsg(trace_ctx, "\t   bit_offset = %d\n", buf_list->bit_offset);
+        va_TraceMsg(trace_ctx, "\t   status = 0x%08x\n", buf_list->status);
+        va_TraceMsg(trace_ctx, "\t   reserved = 0x%08x\n", buf_list->reserved);
+        va_TraceMsg(trace_ctx, "\t   buf = 0x%08x\n", buf_list->buf);
 
+        if (trace_ctx->trace_fp_codedbuf) {
+            va_TraceMsg(trace_ctx, "\tDump the content to file\n");
+            fwrite(buf_list->buf, buf_list->size, 1, trace_ctx->trace_fp_codedbuf);
+        }
+        
         buf_list = buf_list->next;
     }
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 static void va_TraceVABuffers(
@@ -665,25 +760,35 @@
 {
     unsigned int i;
     unsigned char *p = pbuf;
-    unsigned char  check_sum = 0;
-    DPY2INDEX(dpy);
-    
-    va_TraceMsg(idx, "%s\n",  buffer_type_to_string(type));
+    unsigned int dump_size = 64;
 
-    for (i=0; i<size; i++) {
-        unsigned char value =  p[i];
-            
-        if ((trace_flag & VA_TRACE_FLAG_BUFDATA) && ((i%16) == 0))
-            va_TraceMsg(idx, "\n0x%08x:", i);
+    DPY2TRACECTX(dpy);
 
-        if (trace_flag & VA_TRACE_FLAG_BUFDATA)
-            va_TraceMsg(idx, " %02x", value);
+    va_TraceMsg(trace_ctx, "\t    context = %d, buffer = %d, type = %d, size = %d, num_elements = %d\n",
+                context, buffer, type, size, num_elements);
+    va_TraceMsg(trace_ctx, "--%s\n",  buffer_type_to_string(type));
 
-        check_sum ^= value;
+    if (dump_size>size)
+        dump_size = size;
+
+    if (trace_flag & VA_TRACE_FLAG_BUFDATA)
+        dump_size = size;
+
+    if (trace_ctx->trace_fp_log) {
+        for (i=0; i<dump_size; i++) {
+            unsigned char value =  p[i];
+
+            if (i==0)
+                fprintf(trace_ctx->trace_fp_log, "\t\t0x%04x:", i);
+            else if ((i%16) == 0)
+                fprintf(trace_ctx->trace_fp_log, "\n\t\t0x%04x:", i);
+
+            fprintf(trace_ctx->trace_fp_log, " %02x", value);
+        }
+        fprintf(trace_ctx->trace_fp_log, "\n");
     }
-
-    va_TraceMsg(idx, "\tchecksum = 0x%02x\n", check_sum & 0xff);
-    va_TraceMsg(idx, NULL);
+    
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
@@ -691,38 +796,37 @@
 
 static void va_TraceVAPictureParameterBufferMPEG2(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAPictureParameterBufferMPEG2 *p=(VAPictureParameterBufferMPEG2 *)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    va_TraceMsg(idx,"VAPictureParameterBufferMPEG2\n");
+    va_TraceMsg(trace_ctx,"VAPictureParameterBufferMPEG2\n");
+    va_TraceMsg(trace_ctx,"\thorizontal size= %d\n", p->horizontal_size);
+    va_TraceMsg(trace_ctx,"\tvertical size= %d\n", p->vertical_size);
+    va_TraceMsg(trace_ctx,"\tforward reference picture= %d\n", p->forward_reference_picture);
+    va_TraceMsg(trace_ctx,"\tbackward reference picture= %d\n", p->backward_reference_picture);
+    va_TraceMsg(trace_ctx,"\tpicture coding type= %d\n", p->picture_coding_type);
+    va_TraceMsg(trace_ctx,"\tf mode= %d\n", p->f_code);
 
-    va_TraceMsg(idx,"\thorizontal size= %d\n", p->horizontal_size);
-    va_TraceMsg(idx,"\tvertical size= %d\n", p->vertical_size);
-    va_TraceMsg(idx,"\tforward reference picture= %d\n", p->forward_reference_picture);
-    va_TraceMsg(idx,"\tbackward reference picture= %d\n", p->backward_reference_picture);
-    va_TraceMsg(idx,"\tpicture coding type= %d\n", p->picture_coding_type);
-    va_TraceMsg(idx,"\tf mode= %d\n", p->f_code);
-
-    va_TraceMsg(idx,"\tpicture coding extension = %d\n", p->picture_coding_extension.value);
-    va_TraceMsg(idx,"\tintra_dc_precision= %d\n", p->picture_coding_extension.bits.intra_dc_precision);
-    va_TraceMsg(idx,"\tpicture_structure= %d\n", p->picture_coding_extension.bits.picture_structure);
-    va_TraceMsg(idx,"\ttop_field_first= %d\n", p->picture_coding_extension.bits.top_field_first);
-    va_TraceMsg(idx,"\tframe_pred_frame_dct= %d\n", p->picture_coding_extension.bits.frame_pred_frame_dct);
-    va_TraceMsg(idx,"\tconcealment_motion_vectors= %d\n", p->picture_coding_extension.bits.concealment_motion_vectors);
-    va_TraceMsg(idx,"\tq_scale_type= %d\n", p->picture_coding_extension.bits.q_scale_type);
-    va_TraceMsg(idx,"\tintra_vlc_format= %d\n", p->picture_coding_extension.bits.intra_vlc_format);
-    va_TraceMsg(idx,"\talternate_scan= %d\n", p->picture_coding_extension.bits.alternate_scan);
-    va_TraceMsg(idx,"\trepeat_first_field= %d\n", p->picture_coding_extension.bits.repeat_first_field);
-    va_TraceMsg(idx,"\tprogressive_frame= %d\n", p->picture_coding_extension.bits.progressive_frame);
-    va_TraceMsg(idx,"\tis_first_field= %d\n", p->picture_coding_extension.bits.is_first_field);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx,"\tpicture coding extension = %d\n", p->picture_coding_extension.value);
+    va_TraceMsg(trace_ctx,"\tintra_dc_precision= %d\n", p->picture_coding_extension.bits.intra_dc_precision);
+    va_TraceMsg(trace_ctx,"\tpicture_structure= %d\n", p->picture_coding_extension.bits.picture_structure);
+    va_TraceMsg(trace_ctx,"\ttop_field_first= %d\n", p->picture_coding_extension.bits.top_field_first);
+    va_TraceMsg(trace_ctx,"\tframe_pred_frame_dct= %d\n", p->picture_coding_extension.bits.frame_pred_frame_dct);
+    va_TraceMsg(trace_ctx,"\tconcealment_motion_vectors= %d\n", p->picture_coding_extension.bits.concealment_motion_vectors);
+    va_TraceMsg(trace_ctx,"\tq_scale_type= %d\n", p->picture_coding_extension.bits.q_scale_type);
+    va_TraceMsg(trace_ctx,"\tintra_vlc_format= %d\n", p->picture_coding_extension.bits.intra_vlc_format);
+    va_TraceMsg(trace_ctx,"\talternate_scan= %d\n", p->picture_coding_extension.bits.alternate_scan);
+    va_TraceMsg(trace_ctx,"\trepeat_first_field= %d\n", p->picture_coding_extension.bits.repeat_first_field);
+    va_TraceMsg(trace_ctx,"\tprogressive_frame= %d\n", p->picture_coding_extension.bits.progressive_frame);
+    va_TraceMsg(trace_ctx,"\tis_first_field= %d\n", p->picture_coding_extension.bits.is_first_field);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
@@ -730,27 +834,26 @@
 
 static void va_TraceVAIQMatrixBufferMPEG2(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAIQMatrixBufferMPEG2 *p=(VAIQMatrixBufferMPEG2 *)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    va_TraceMsg(idx,"VAIQMatrixBufferMPEG2\n");
-
-    va_TraceMsg(idx,"\tload_intra_quantiser_matrix = %d\n", p->load_intra_quantiser_matrix);
-    va_TraceMsg(idx,"\tload_non_intra_quantiser_matrix = %d\n", p->load_non_intra_quantiser_matrix);
-    va_TraceMsg(idx,"\tload_chroma_intra_quantiser_matrix = %d\n", p->load_chroma_intra_quantiser_matrix);
-    va_TraceMsg(idx,"\tload_chroma_non_intra_quantiser_matrix = %d\n", p->load_chroma_non_intra_quantiser_matrix);
-    va_TraceMsg(idx,"\tintra_quantiser_matrix = %d\n", p->intra_quantiser_matrix);
-    va_TraceMsg(idx,"\tnon_intra_quantiser_matrix = %d\n", p->non_intra_quantiser_matrix);
-    va_TraceMsg(idx,"\tchroma_intra_quantiser_matrix = %d\n", p->chroma_intra_quantiser_matrix);
-    va_TraceMsg(idx,"\tchroma_non_intra_quantiser_matrix = %d\n", p->chroma_non_intra_quantiser_matrix);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx,"VAIQMatrixBufferMPEG2\n");
+    va_TraceMsg(trace_ctx,"\tload_intra_quantiser_matrix = %d\n", p->load_intra_quantiser_matrix);
+    va_TraceMsg(trace_ctx,"\tload_non_intra_quantiser_matrix = %d\n", p->load_non_intra_quantiser_matrix);
+    va_TraceMsg(trace_ctx,"\tload_chroma_intra_quantiser_matrix = %d\n", p->load_chroma_intra_quantiser_matrix);
+    va_TraceMsg(trace_ctx,"\tload_chroma_non_intra_quantiser_matrix = %d\n", p->load_chroma_non_intra_quantiser_matrix);
+    va_TraceMsg(trace_ctx,"\tintra_quantiser_matrix = %d\n", p->intra_quantiser_matrix);
+    va_TraceMsg(trace_ctx,"\tnon_intra_quantiser_matrix = %d\n", p->non_intra_quantiser_matrix);
+    va_TraceMsg(trace_ctx,"\tchroma_intra_quantiser_matrix = %d\n", p->chroma_intra_quantiser_matrix);
+    va_TraceMsg(trace_ctx,"\tchroma_non_intra_quantiser_matrix = %d\n", p->chroma_non_intra_quantiser_matrix);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
@@ -758,92 +861,219 @@
 
 static void va_TraceVASliceParameterBufferMPEG2(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VASliceParameterBufferMPEG2 *p=(VASliceParameterBufferMPEG2 *)data;
 
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    trace_context[idx].trace_slice_no++;
+    trace_ctx->trace_slice_no++;
     
-    trace_context[idx].trace_slice_size = p->slice_data_size;
+    trace_ctx->trace_slice_size = p->slice_data_size;
 
-    va_TraceMsg(idx,"VASliceParameterBufferMPEG2\n");
-
-    va_TraceMsg(idx,"\tslice_data_size = %d\n", p->slice_data_size);
-    va_TraceMsg(idx,"\tslice_data_offset = %d\n", p->slice_data_offset);
-    va_TraceMsg(idx,"\tslice_data_flag = %d\n", p->slice_data_flag);
-    va_TraceMsg(idx,"\tmacroblock_offset = %d\n", p->macroblock_offset);
-    va_TraceMsg(idx,"\tslice_horizontal_position = %d\n", p->slice_horizontal_position);
-    va_TraceMsg(idx,"\tslice_vertical_position = %d\n", p->slice_vertical_position);
-    va_TraceMsg(idx,"\tquantiser_scale_code = %d\n", p->quantiser_scale_code);
-    va_TraceMsg(idx,"\tintra_slice_flag = %d\n", p->intra_slice_flag);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx,"VASliceParameterBufferMPEG2\n");
+    va_TraceMsg(trace_ctx,"\tslice_data_size = %d\n", p->slice_data_size);
+    va_TraceMsg(trace_ctx,"\tslice_data_offset = %d\n", p->slice_data_offset);
+    va_TraceMsg(trace_ctx,"\tslice_data_flag = %d\n", p->slice_data_flag);
+    va_TraceMsg(trace_ctx,"\tmacroblock_offset = %d\n", p->macroblock_offset);
+    va_TraceMsg(trace_ctx,"\tslice_horizontal_position = %d\n", p->slice_horizontal_position);
+    va_TraceMsg(trace_ctx,"\tslice_vertical_position = %d\n", p->slice_vertical_position);
+    va_TraceMsg(trace_ctx,"\tquantiser_scale_code = %d\n", p->quantiser_scale_code);
+    va_TraceMsg(trace_ctx,"\tintra_slice_flag = %d\n", p->intra_slice_flag);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
 
+static void va_TraceVAPictureParameterBufferJPEG(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    int i;
+    VAPictureParameterBufferJPEGBaseline *p=(VAPictureParameterBufferJPEGBaseline *)data;
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx,"*VAPictureParameterBufferJPEG\n");
+    va_TraceMsg(trace_ctx,"\tpicture_width = %u\n", p->picture_width);
+    va_TraceMsg(trace_ctx,"\tpicture_height = %u\n", p->picture_height);
+    va_TraceMsg(trace_ctx,"\tcomponents = \n");
+    for (i = 0; i < p->num_components && i < 255; ++i) {
+        va_TraceMsg(trace_ctx,"\t\t[%d] component_id = %u\n", i, p->components[i].component_id);
+        va_TraceMsg(trace_ctx,"\t\t[%d] h_sampling_factor = %u\n", i, p->components[i].h_sampling_factor);
+        va_TraceMsg(trace_ctx,"\t\t[%d] v_sampling_factor = %u\n", i, p->components[i].v_sampling_factor);
+        va_TraceMsg(trace_ctx,"\t\t[%d] quantiser_table_selector = %u\n", i, p->components[i].quantiser_table_selector);
+    }
+}
+
+static void va_TraceVAIQMatrixBufferJPEG(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    int i, j;
+    static char tmp[1024];
+    VAIQMatrixBufferJPEGBaseline *p=(VAIQMatrixBufferJPEGBaseline *)data;
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx,"*VAIQMatrixParameterBufferJPEG\n");
+    va_TraceMsg(trace_ctx,"\tload_quantiser_table =\n");
+    for (i = 0; i < 4; ++i) {
+        va_TraceMsg(trace_ctx,"\t\t[%d] = %u\n", i, p->load_quantiser_table[i]);
+    }
+    va_TraceMsg(trace_ctx,"\tquantiser_table =\n");
+    for (i = 0; i < 4; ++i) {
+        memset(tmp, 0, sizeof tmp);
+        for (j = 0; j < 64; ++j) {
+            sprintf(tmp + strlen(tmp), "%u ", p->quantiser_table[i][j]);
+        }
+        va_TraceMsg(trace_ctx,"\t\t[%d] = %s\n", i, tmp);
+    }
+}
+
+static void va_TraceVASliceParameterBufferJPEG(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    int i;
+    VASliceParameterBufferJPEGBaseline *p=(VASliceParameterBufferJPEGBaseline *)data;
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx,"*VASliceParameterBufferJPEG\n");
+    va_TraceMsg(trace_ctx,"\tslice_data_size = %u\n", p->slice_data_size);
+    va_TraceMsg(trace_ctx,"\tslice_data_offset = %u\n", p->slice_data_offset);
+    va_TraceMsg(trace_ctx,"\tslice_data_flag = %u\n", p->slice_data_flag);
+    va_TraceMsg(trace_ctx,"\tslice_horizontal_position = %u\n", p->slice_horizontal_position);
+    va_TraceMsg(trace_ctx,"\tslice_vertical_position = %u\n", p->slice_vertical_position);
+    va_TraceMsg(trace_ctx,"\tcomponents = \n");
+    for (i = 0; i < p->num_components && i < 4; ++i) {
+        va_TraceMsg(trace_ctx,"\t\t[%d] component_selector = %u\n", i, p->components[i].component_selector);
+        va_TraceMsg(trace_ctx,"\t\t[%d] dc_table_selector = %u\n", i, p->components[i].dc_table_selector);
+        va_TraceMsg(trace_ctx,"\t\t[%d] ac_table_selector = %u\n", i, p->components[i].ac_table_selector);
+    }
+    va_TraceMsg(trace_ctx,"\trestart_interval = %u\n", p->restart_interval);
+    va_TraceMsg(trace_ctx,"\tnum_mcus = %u\n", p->num_mcus);
+}
+
+static void va_TraceVAHuffmanTableBufferJPEG(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    int i, j;
+    static char tmp[1024];
+    VAHuffmanTableBufferJPEGBaseline *p=(VAHuffmanTableBufferJPEGBaseline *)data;
+    DPY2TRACECTX(dpy);
+    va_TraceMsg(trace_ctx,"*VAHuffmanTableBufferJPEG\n");
+
+    for (i = 0; i < 2; ++i) {
+        va_TraceMsg(trace_ctx,"\tload_huffman_table[%d] =%u\n", i, p->load_huffman_table[0]);
+        va_TraceMsg(trace_ctx,"\thuffman_table[%d] =\n", i);
+        memset(tmp, 0, sizeof tmp);
+        for (j = 0; j < 16; ++j) {
+            sprintf(tmp + strlen(tmp), "%u ", p->huffman_table[i].num_dc_codes[j]);
+        }
+        va_TraceMsg(trace_ctx,"\t\tnum_dc_codes =%s\n", tmp);
+        memset(tmp, 0, sizeof tmp);
+        for (j = 0; j < 12; ++j) {
+            sprintf(tmp + strlen(tmp), "%u ", p->huffman_table[i].dc_values[j]);
+        }
+        va_TraceMsg(trace_ctx,"\t\tdc_values =%s\n", tmp);
+        memset(tmp, 0, sizeof tmp);
+        for (j = 0; j < 16; ++j) {
+            sprintf(tmp + strlen(tmp), "%u ", p->huffman_table[i].num_ac_codes[j]);
+        }
+        va_TraceMsg(trace_ctx,"\t\tnum_ac_codes =%s\n", tmp);
+        memset(tmp, 0, sizeof tmp);
+        for (j = 0; j < 162; ++j) {
+            sprintf(tmp + strlen(tmp), "%u ", p->huffman_table[i].ac_values[j]);
+        }
+        va_TraceMsg(trace_ctx,"\t\tac_values =%s\n", tmp);
+        memset(tmp, 0, sizeof tmp);
+        for (j = 0; j < 2; ++j) {
+            sprintf(tmp + strlen(tmp), "%u ", p->huffman_table[i].pad[j]);
+        }
+        va_TraceMsg(trace_ctx,"\t\tpad =%s\n", tmp);
+    }
+}
 
 static void va_TraceVAPictureParameterBufferMPEG4(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     int i;
     VAPictureParameterBufferMPEG4 *p=(VAPictureParameterBufferMPEG4 *)data;
     
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    va_TraceMsg(idx,"*VAPictureParameterBufferMPEG4\n");
-    va_TraceMsg(idx,"\tvop_width = %d\n", p->vop_width);
-    va_TraceMsg(idx,"\tvop_height = %d\n", p->vop_height);
-    va_TraceMsg(idx,"\tforward_reference_picture = %d\n", p->forward_reference_picture);
-    va_TraceMsg(idx,"\tbackward_reference_picture = %d\n", p->backward_reference_picture);
-    va_TraceMsg(idx,"\tvol_fields value = %d\n", p->vol_fields.value);
-    va_TraceMsg(idx,"\tshort_video_header= %d\n", p->vol_fields.bits.short_video_header);
-    va_TraceMsg(idx,"\tchroma_format= %d\n", p->vol_fields.bits.chroma_format);
-    va_TraceMsg(idx,"\tinterlaced= %d\n", p->vol_fields.bits.interlaced);
-    va_TraceMsg(idx,"\tobmc_disable= %d\n", p->vol_fields.bits.obmc_disable);
-    va_TraceMsg(idx,"\tsprite_enable= %d\n", p->vol_fields.bits.sprite_enable);
-    va_TraceMsg(idx,"\tsprite_warping_accuracy= %d\n", p->vol_fields.bits.sprite_warping_accuracy);
-    va_TraceMsg(idx,"\tquant_type= %d\n", p->vol_fields.bits.quant_type);
-    va_TraceMsg(idx,"\tquarter_sample= %d\n", p->vol_fields.bits.quarter_sample);
-    va_TraceMsg(idx,"\tdata_partitioned= %d\n", p->vol_fields.bits.data_partitioned);
-    va_TraceMsg(idx,"\treversible_vlc= %d\n", p->vol_fields.bits.reversible_vlc);
-    va_TraceMsg(idx,"\tresync_marker_disable= %d\n", p->vol_fields.bits.resync_marker_disable);
-    va_TraceMsg(idx,"\tno_of_sprite_warping_points = %d\n", p->no_of_sprite_warping_points);
-    va_TraceMsg(idx,"\tsprite_trajectory_du =");
+    va_TraceMsg(trace_ctx,"*VAPictureParameterBufferMPEG4\n");
+    va_TraceMsg(trace_ctx,"\tvop_width = %d\n", p->vop_width);
+    va_TraceMsg(trace_ctx,"\tvop_height = %d\n", p->vop_height);
+    va_TraceMsg(trace_ctx,"\tforward_reference_picture = %d\n", p->forward_reference_picture);
+    va_TraceMsg(trace_ctx,"\tbackward_reference_picture = %d\n", p->backward_reference_picture);
+    va_TraceMsg(trace_ctx,"\tvol_fields value = %d\n", p->vol_fields.value);
+    va_TraceMsg(trace_ctx,"\tshort_video_header= %d\n", p->vol_fields.bits.short_video_header);
+    va_TraceMsg(trace_ctx,"\tchroma_format= %d\n", p->vol_fields.bits.chroma_format);
+    va_TraceMsg(trace_ctx,"\tinterlaced= %d\n", p->vol_fields.bits.interlaced);
+    va_TraceMsg(trace_ctx,"\tobmc_disable= %d\n", p->vol_fields.bits.obmc_disable);
+    va_TraceMsg(trace_ctx,"\tsprite_enable= %d\n", p->vol_fields.bits.sprite_enable);
+    va_TraceMsg(trace_ctx,"\tsprite_warping_accuracy= %d\n", p->vol_fields.bits.sprite_warping_accuracy);
+    va_TraceMsg(trace_ctx,"\tquant_type= %d\n", p->vol_fields.bits.quant_type);
+    va_TraceMsg(trace_ctx,"\tquarter_sample= %d\n", p->vol_fields.bits.quarter_sample);
+    va_TraceMsg(trace_ctx,"\tdata_partitioned= %d\n", p->vol_fields.bits.data_partitioned);
+    va_TraceMsg(trace_ctx,"\treversible_vlc= %d\n", p->vol_fields.bits.reversible_vlc);
+    va_TraceMsg(trace_ctx,"\tresync_marker_disable= %d\n", p->vol_fields.bits.resync_marker_disable);
+    va_TraceMsg(trace_ctx,"\tno_of_sprite_warping_points = %d\n", p->no_of_sprite_warping_points);
+    va_TraceMsg(trace_ctx,"\tsprite_trajectory_du =");
     for(i=0;i<3;i++)
-        va_TraceMsg(idx,"\t%d", p->sprite_trajectory_du[i]);
+        va_TraceMsg(trace_ctx,"\t%d", p->sprite_trajectory_du[i]);
 
-    va_TraceMsg(idx,"\n");
-    va_TraceMsg(idx,"\tsprite_trajectory_dv =");
+    va_TraceMsg(trace_ctx,"\n");
+    va_TraceMsg(trace_ctx,"\tsprite_trajectory_dv =");
     for(i=0;i<3;i++)
-        va_TraceMsg(idx,"\t%d", p->sprite_trajectory_dv[i]);
-    va_TraceMsg(idx,"\n");
-    va_TraceMsg(idx,"\tvop_fields value = %d\n", p->vop_fields.value);
-    va_TraceMsg(idx,"\tvop_coding_type= %d\n", p->vop_fields.bits.vop_coding_type);
-    va_TraceMsg(idx,"\tbackward_reference_vop_coding_type= %d\n", p->vop_fields.bits.backward_reference_vop_coding_type);
-    va_TraceMsg(idx,"\tvop_rounding_type= %d\n", p->vop_fields.bits.vop_rounding_type);
-    va_TraceMsg(idx,"\tintra_dc_vlc_thr= %d\n", p->vop_fields.bits.intra_dc_vlc_thr);
-    va_TraceMsg(idx,"\ttop_field_first= %d\n", p->vop_fields.bits.top_field_first);
-    va_TraceMsg(idx,"\talternate_vertical_scan_flag= %d\n", p->vop_fields.bits.alternate_vertical_scan_flag);
-    va_TraceMsg(idx,"\tvop_fcode_forward = %d\n", p->vop_fcode_forward);
-    va_TraceMsg(idx,"\tvop_fcode_backward = %d\n", p->vop_fcode_backward);
-    va_TraceMsg(idx,"\tnum_gobs_in_vop = %d\n", p->num_gobs_in_vop);
-    va_TraceMsg(idx,"\tnum_macroblocks_in_gob = %d\n", p->num_macroblocks_in_gob);
-    va_TraceMsg(idx,"\tTRB = %d\n", p->TRB);
-    va_TraceMsg(idx,"\tTRD = %d\n", p->TRD);
-    va_TraceMsg(idx, NULL);
+        va_TraceMsg(trace_ctx,"\t%d", p->sprite_trajectory_dv[i]);
+    va_TraceMsg(trace_ctx,"\n");
+    va_TraceMsg(trace_ctx,"\tvop_fields value = %d\n", p->vop_fields.value);
+    va_TraceMsg(trace_ctx,"\tvop_coding_type= %d\n", p->vop_fields.bits.vop_coding_type);
+    va_TraceMsg(trace_ctx,"\tbackward_reference_vop_coding_type= %d\n", p->vop_fields.bits.backward_reference_vop_coding_type);
+    va_TraceMsg(trace_ctx,"\tvop_rounding_type= %d\n", p->vop_fields.bits.vop_rounding_type);
+    va_TraceMsg(trace_ctx,"\tintra_dc_vlc_thr= %d\n", p->vop_fields.bits.intra_dc_vlc_thr);
+    va_TraceMsg(trace_ctx,"\ttop_field_first= %d\n", p->vop_fields.bits.top_field_first);
+    va_TraceMsg(trace_ctx,"\talternate_vertical_scan_flag= %d\n", p->vop_fields.bits.alternate_vertical_scan_flag);
+    va_TraceMsg(trace_ctx,"\tvop_fcode_forward = %d\n", p->vop_fcode_forward);
+    va_TraceMsg(trace_ctx,"\tvop_fcode_backward = %d\n", p->vop_fcode_backward);
+    va_TraceMsg(trace_ctx,"\tnum_gobs_in_vop = %d\n", p->num_gobs_in_vop);
+    va_TraceMsg(trace_ctx,"\tnum_macroblocks_in_gob = %d\n", p->num_macroblocks_in_gob);
+    va_TraceMsg(trace_ctx,"\tTRB = %d\n", p->TRB);
+    va_TraceMsg(trace_ctx,"\tTRD = %d\n", p->TRD);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
@@ -851,396 +1081,402 @@
 
 static void va_TraceVAIQMatrixBufferMPEG4(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     int i;
     VAIQMatrixBufferMPEG4 *p=(VAIQMatrixBufferMPEG4 *)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    va_TraceMsg(idx,"VAIQMatrixBufferMPEG4\n");
+    va_TraceMsg(trace_ctx,"VAIQMatrixBufferMPEG4\n");
 
-    va_TraceMsg(idx,"\tload_intra_quant_mat = %d\n", p->load_intra_quant_mat);
-    va_TraceMsg(idx,"\tload_non_intra_quant_mat = %d\n", p->load_non_intra_quant_mat);
-    va_TraceMsg(idx,"\tintra_quant_mat =\n");
+    va_TraceMsg(trace_ctx,"\tload_intra_quant_mat = %d\n", p->load_intra_quant_mat);
+    va_TraceMsg(trace_ctx,"\tload_non_intra_quant_mat = %d\n", p->load_non_intra_quant_mat);
+    va_TraceMsg(trace_ctx,"\tintra_quant_mat =\n");
     for(i=0;i<64;i++)
-        va_TraceMsg(idx,"\t\t%d\n", p->intra_quant_mat[i]);
+        va_TraceMsg(trace_ctx,"\t\t%d\n", p->intra_quant_mat[i]);
 
-    va_TraceMsg(idx,"\tnon_intra_quant_mat =\n");
+    va_TraceMsg(trace_ctx,"\tnon_intra_quant_mat =\n");
     for(i=0;i<64;i++)
-        va_TraceMsg(idx,"\t\t%d\n", p->non_intra_quant_mat[i]);
-    va_TraceMsg(idx, NULL);
+        va_TraceMsg(trace_ctx,"\t\t%d\n", p->non_intra_quant_mat[i]);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
 
 static void va_TraceVAEncSequenceParameterBufferMPEG4(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAEncSequenceParameterBufferMPEG4 *p = (VAEncSequenceParameterBufferMPEG4 *)data;
-    DPY2INDEX(dpy);
-    
-    va_TraceMsg(idx, "VAEncSequenceParameterBufferMPEG4\n");
-    
-    va_TraceMsg(idx, "\tprofile_and_level_indication = %d\n", p->profile_and_level_indication);
-    va_TraceMsg(idx, "\tintra_period = %d\n", p->intra_period);
-    va_TraceMsg(idx, "\tvideo_object_layer_width = %d\n", p->video_object_layer_width);
-    va_TraceMsg(idx, "\tvideo_object_layer_height = %d\n", p->video_object_layer_height);
-    va_TraceMsg(idx, "\tvop_time_increment_resolution = %d\n", p->vop_time_increment_resolution);
-    va_TraceMsg(idx, "\tfixed_vop_rate = %d\n", p->fixed_vop_rate);
-    va_TraceMsg(idx, "\tfixed_vop_time_increment = %d\n", p->fixed_vop_time_increment);
-    va_TraceMsg(idx, "\tbits_per_second = %d\n", p->bits_per_second);
-    va_TraceMsg(idx, "\tframe_rate = %d\n", p->frame_rate);
-    va_TraceMsg(idx, "\tinitial_qp = %d\n", p->initial_qp);
-    va_TraceMsg(idx, "\tmin_qp = %d\n", p->min_qp);
-    va_TraceMsg(idx, NULL);
+    DPY2TRACECTX(dpy);
 
-    /* start a new sequce, coded log file can be truncated */
-    trace_context[idx].trace_sequence_start = 1;
+    va_TraceMsg(trace_ctx, "\t--VAEncSequenceParameterBufferMPEG4\n");
+    va_TraceMsg(trace_ctx, "\tprofile_and_level_indication = %d\n", p->profile_and_level_indication);
+    va_TraceMsg(trace_ctx, "\tintra_period = %d\n", p->intra_period);
+    va_TraceMsg(trace_ctx, "\tvideo_object_layer_width = %d\n", p->video_object_layer_width);
+    va_TraceMsg(trace_ctx, "\tvideo_object_layer_height = %d\n", p->video_object_layer_height);
+    va_TraceMsg(trace_ctx, "\tvop_time_increment_resolution = %d\n", p->vop_time_increment_resolution);
+    va_TraceMsg(trace_ctx, "\tfixed_vop_rate = %d\n", p->fixed_vop_rate);
+    va_TraceMsg(trace_ctx, "\tfixed_vop_time_increment = %d\n", p->fixed_vop_time_increment);
+    va_TraceMsg(trace_ctx, "\tbits_per_second = %d\n", p->bits_per_second);
+    va_TraceMsg(trace_ctx, "\tframe_rate = %d\n", p->frame_rate);
+    va_TraceMsg(trace_ctx, "\tinitial_qp = %d\n", p->initial_qp);
+    va_TraceMsg(trace_ctx, "\tmin_qp = %d\n", p->min_qp);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
 
 static void va_TraceVAEncPictureParameterBufferMPEG4(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAEncPictureParameterBufferMPEG4 *p = (VAEncPictureParameterBufferMPEG4 *)data;
-    DPY2INDEX(dpy);
-    
-    va_TraceMsg(idx, "VAEncPictureParameterBufferMPEG4\n");
-    va_TraceMsg(idx, "\treference_picture = 0x%08x\n", p->reference_picture);
-    va_TraceMsg(idx, "\treconstructed_picture = 0x%08x\n", p->reconstructed_picture);
-    va_TraceMsg(idx, "\tcoded_buf = %08x\n", p->coded_buf);
-    va_TraceMsg(idx, "\tpicture_width = %d\n", p->picture_width);
-    va_TraceMsg(idx, "\tpicture_height = %d\n", p->picture_height);
-    va_TraceMsg(idx, "\tmodulo_time_base = %d\n", p->modulo_time_base);
-    va_TraceMsg(idx, "\tvop_time_increment = %d\n", p->vop_time_increment);
-    va_TraceMsg(idx, "\tpicture_type = %d\n", p->picture_type);
-    va_TraceMsg(idx, NULL);
+    DPY2TRACECTX(dpy);
 
-    trace_context[idx].trace_codedbuf =  p->coded_buf;
-    
+    va_TraceMsg(trace_ctx, "\t--VAEncPictureParameterBufferMPEG4\n");
+    va_TraceMsg(trace_ctx, "\treference_picture = 0x%08x\n", p->reference_picture);
+    va_TraceMsg(trace_ctx, "\treconstructed_picture = 0x%08x\n", p->reconstructed_picture);
+    va_TraceMsg(trace_ctx, "\tcoded_buf = 0x%08x\n", p->coded_buf);
+    va_TraceMsg(trace_ctx, "\tpicture_width = %d\n", p->picture_width);
+    va_TraceMsg(trace_ctx, "\tpicture_height = %d\n", p->picture_height);
+    va_TraceMsg(trace_ctx, "\tmodulo_time_base = %d\n", p->modulo_time_base);
+    va_TraceMsg(trace_ctx, "\tvop_time_increment = %d\n", p->vop_time_increment);
+    va_TraceMsg(trace_ctx, "\tpicture_type = %d\n", p->picture_type);
+    va_TraceMsg(trace_ctx, NULL);
+
     return;
 }
 
 
 static void va_TraceVASliceParameterBufferMPEG4(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VASliceParameterBufferMPEG4 *p=(VASliceParameterBufferMPEG4 *)data;
     
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    trace_context[idx].trace_slice_no++;
+    trace_ctx->trace_slice_no++;
 
-    trace_context[idx].trace_slice_size = p->slice_data_size;
+    trace_ctx->trace_slice_size = p->slice_data_size;
 
-    va_TraceMsg(idx,"VASliceParameterBufferMPEG4\n");
+    va_TraceMsg(trace_ctx,"VASliceParameterBufferMPEG4\n");
 
-    va_TraceMsg(idx,"\tslice_data_size = %d\n", p->slice_data_size);
-    va_TraceMsg(idx,"\tslice_data_offset = %d\n", p->slice_data_offset);
-    va_TraceMsg(idx,"\tslice_data_flag = %d\n", p->slice_data_flag);
-    va_TraceMsg(idx,"\tmacroblock_offset = %d\n", p->macroblock_offset);
-    va_TraceMsg(idx,"\tmacroblock_number = %d\n", p->macroblock_number);
-    va_TraceMsg(idx,"\tquant_scale = %d\n", p->quant_scale);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx,"\tslice_data_size = %d\n", p->slice_data_size);
+    va_TraceMsg(trace_ctx,"\tslice_data_offset = %d\n", p->slice_data_offset);
+    va_TraceMsg(trace_ctx,"\tslice_data_flag = %d\n", p->slice_data_flag);
+    va_TraceMsg(trace_ctx,"\tmacroblock_offset = %d\n", p->macroblock_offset);
+    va_TraceMsg(trace_ctx,"\tmacroblock_number = %d\n", p->macroblock_number);
+    va_TraceMsg(trace_ctx,"\tquant_scale = %d\n", p->quant_scale);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
 
 
 static inline void va_TraceFlagIfNotZero(
-    int idx,            /* in */
+    struct trace_context *trace_ctx,
     const char *name,   /* in */
     unsigned int flag   /* in */
 )
 {
     if (flag != 0) {
-        va_TraceMsg(idx, "%s = %x\n", name, flag);
+        va_TraceMsg(trace_ctx, "%s = %x\n", name, flag);
     }
 }
 
 
 static void va_TraceVAPictureParameterBufferH264(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     int i;
     VAPictureParameterBufferH264 *p = (VAPictureParameterBufferH264*)data;
     
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    va_TraceMsg(idx, "VAPictureParameterBufferH264\n");
+    va_TraceMsg(trace_ctx, "\t--VAPictureParameterBufferH264\n");
 
-    va_TraceMsg(idx, "\tCurrPic.picture_id = 0x%08x\n", p->CurrPic.picture_id);
-    va_TraceMsg(idx, "\tCurrPic.frame_idx = %d\n", p->CurrPic.frame_idx);
-    va_TraceMsg(idx, "\tCurrPic.flags = %d\n", p->CurrPic.flags);
-    va_TraceMsg(idx, "\tCurrPic.TopFieldOrderCnt = %d\n", p->CurrPic.TopFieldOrderCnt);
-    va_TraceMsg(idx, "\tCurrPic.BottomFieldOrderCnt = %d\n", p->CurrPic.BottomFieldOrderCnt);
+    va_TraceMsg(trace_ctx, "\tCurrPic.picture_id = 0x%08x\n", p->CurrPic.picture_id);
+    va_TraceMsg(trace_ctx, "\tCurrPic.frame_idx = %d\n", p->CurrPic.frame_idx);
+    va_TraceMsg(trace_ctx, "\tCurrPic.flags = %d\n", p->CurrPic.flags);
+    va_TraceMsg(trace_ctx, "\tCurrPic.TopFieldOrderCnt = %d\n", p->CurrPic.TopFieldOrderCnt);
+    va_TraceMsg(trace_ctx, "\tCurrPic.BottomFieldOrderCnt = %d\n", p->CurrPic.BottomFieldOrderCnt);
 
-    va_TraceMsg(idx, "\tReferenceFrames (TopFieldOrderCnt-BottomFieldOrderCnt-picture_id-frame_idx:\n");
+    va_TraceMsg(trace_ctx, "\tReferenceFrames (TopFieldOrderCnt-BottomFieldOrderCnt-picture_id-frame_idx-flags:\n");
     for (i = 0; i < 16; i++)
     {
-        if (p->ReferenceFrames[i].flags != VA_PICTURE_H264_INVALID) {
-            va_TraceMsg(idx, "\t\t%d-%d-0x%08x-%d\n",
+        if ((p->ReferenceFrames[i].picture_id != VA_INVALID_SURFACE) &&
+            ((p->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID) == 0)) {
+            va_TraceMsg(trace_ctx, "\t\t%08d-%08d-0x%08x-%08d-0x%08x\n",
                         p->ReferenceFrames[i].TopFieldOrderCnt,
                         p->ReferenceFrames[i].BottomFieldOrderCnt,
                         p->ReferenceFrames[i].picture_id,
-                        p->ReferenceFrames[i].frame_idx);
+                        p->ReferenceFrames[i].frame_idx,
+                        p->ReferenceFrames[i].flags);
         } else
-            va_TraceMsg(idx, "\t\tinv-inv-inv-inv\n");
+            break;
     }
-    va_TraceMsg(idx, "\n");
-    
-    va_TraceMsg(idx, "\tpicture_width_in_mbs_minus1 = %d\n", p->picture_width_in_mbs_minus1);
-    va_TraceMsg(idx, "\tpicture_height_in_mbs_minus1 = %d\n", p->picture_height_in_mbs_minus1);
-    va_TraceMsg(idx, "\tbit_depth_luma_minus8 = %d\n", p->bit_depth_luma_minus8);
-    va_TraceMsg(idx, "\tbit_depth_chroma_minus8 = %d\n", p->bit_depth_chroma_minus8);
-    va_TraceMsg(idx, "\tnum_ref_frames = %d\n", p->num_ref_frames);
-    va_TraceMsg(idx, "\tseq fields = %d\n", p->seq_fields.value);
-    va_TraceMsg(idx, "\tchroma_format_idc = %d\n", p->seq_fields.bits.chroma_format_idc);
-    va_TraceMsg(idx, "\tresidual_colour_transform_flag = %d\n", p->seq_fields.bits.residual_colour_transform_flag);
-    va_TraceMsg(idx, "\tframe_mbs_only_flag = %d\n", p->seq_fields.bits.frame_mbs_only_flag);
-    va_TraceMsg(idx, "\tmb_adaptive_frame_field_flag = %d\n", p->seq_fields.bits.mb_adaptive_frame_field_flag);
-    va_TraceMsg(idx, "\tdirect_8x8_inference_flag = %d\n", p->seq_fields.bits.direct_8x8_inference_flag);
-    va_TraceMsg(idx, "\tMinLumaBiPredSize8x8 = %d\n", p->seq_fields.bits.MinLumaBiPredSize8x8);
-    va_TraceMsg(idx, "\tnum_slice_groups_minus1 = %d\n", p->num_slice_groups_minus1);
-    va_TraceMsg(idx, "\tslice_group_map_type = %d\n", p->slice_group_map_type);
-    va_TraceMsg(idx, "\tslice_group_change_rate_minus1 = %d\n", p->slice_group_change_rate_minus1);
-    va_TraceMsg(idx, "\tpic_init_qp_minus26 = %d\n", p->pic_init_qp_minus26);
-    va_TraceMsg(idx, "\tpic_init_qs_minus26 = %d\n", p->pic_init_qs_minus26);
-    va_TraceMsg(idx, "\tchroma_qp_index_offset = %d\n", p->chroma_qp_index_offset);
-    va_TraceMsg(idx, "\tsecond_chroma_qp_index_offset = %d\n", p->second_chroma_qp_index_offset);
-    va_TraceMsg(idx, "\tpic_fields = 0x%03x\n", p->pic_fields.value);
-    va_TraceFlagIfNotZero(idx, "\t\tentropy_coding_mode_flag", p->pic_fields.bits.entropy_coding_mode_flag);
-    va_TraceFlagIfNotZero(idx, "\t\tweighted_pred_flag", p->pic_fields.bits.weighted_pred_flag);
-    va_TraceFlagIfNotZero(idx, "\t\tweighted_bipred_idc", p->pic_fields.bits.weighted_bipred_idc);
-    va_TraceFlagIfNotZero(idx, "\t\ttransform_8x8_mode_flag", p->pic_fields.bits.transform_8x8_mode_flag);
-    va_TraceFlagIfNotZero(idx, "\t\tfield_pic_flag", p->pic_fields.bits.field_pic_flag);
-    va_TraceFlagIfNotZero(idx, "\t\tconstrained_intra_pred_flag", p->pic_fields.bits.constrained_intra_pred_flag);
-    va_TraceFlagIfNotZero(idx, "\t\tpic_order_present_flag", p->pic_fields.bits.pic_order_present_flag);
-    va_TraceFlagIfNotZero(idx, "\t\tdeblocking_filter_control_present_flag", p->pic_fields.bits.deblocking_filter_control_present_flag);
-    va_TraceFlagIfNotZero(idx, "\t\tredundant_pic_cnt_present_flag", p->pic_fields.bits.redundant_pic_cnt_present_flag);
-    va_TraceFlagIfNotZero(idx, "\t\treference_pic_flag", p->pic_fields.bits.reference_pic_flag);
-    va_TraceMsg(idx, "\tframe_num = %d\n", p->frame_num);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "\tpicture_width_in_mbs_minus1 = %d\n", p->picture_width_in_mbs_minus1);
+    va_TraceMsg(trace_ctx, "\tpicture_height_in_mbs_minus1 = %d\n", p->picture_height_in_mbs_minus1);
+    va_TraceMsg(trace_ctx, "\tbit_depth_luma_minus8 = %d\n", p->bit_depth_luma_minus8);
+    va_TraceMsg(trace_ctx, "\tbit_depth_chroma_minus8 = %d\n", p->bit_depth_chroma_minus8);
+    va_TraceMsg(trace_ctx, "\tnum_ref_frames = %d\n", p->num_ref_frames);
+    va_TraceMsg(trace_ctx, "\tseq fields = %d\n", p->seq_fields.value);
+    va_TraceMsg(trace_ctx, "\tchroma_format_idc = %d\n", p->seq_fields.bits.chroma_format_idc);
+    va_TraceMsg(trace_ctx, "\tresidual_colour_transform_flag = %d\n", p->seq_fields.bits.residual_colour_transform_flag);
+    va_TraceMsg(trace_ctx, "\tframe_mbs_only_flag = %d\n", p->seq_fields.bits.frame_mbs_only_flag);
+    va_TraceMsg(trace_ctx, "\tmb_adaptive_frame_field_flag = %d\n", p->seq_fields.bits.mb_adaptive_frame_field_flag);
+    va_TraceMsg(trace_ctx, "\tdirect_8x8_inference_flag = %d\n", p->seq_fields.bits.direct_8x8_inference_flag);
+    va_TraceMsg(trace_ctx, "\tMinLumaBiPredSize8x8 = %d\n", p->seq_fields.bits.MinLumaBiPredSize8x8);
+    va_TraceMsg(trace_ctx, "\tnum_slice_groups_minus1 = %d\n", p->num_slice_groups_minus1);
+    va_TraceMsg(trace_ctx, "\tslice_group_map_type = %d\n", p->slice_group_map_type);
+    va_TraceMsg(trace_ctx, "\tslice_group_change_rate_minus1 = %d\n", p->slice_group_change_rate_minus1);
+    va_TraceMsg(trace_ctx, "\tpic_init_qp_minus26 = %d\n", p->pic_init_qp_minus26);
+    va_TraceMsg(trace_ctx, "\tpic_init_qs_minus26 = %d\n", p->pic_init_qs_minus26);
+    va_TraceMsg(trace_ctx, "\tchroma_qp_index_offset = %d\n", p->chroma_qp_index_offset);
+    va_TraceMsg(trace_ctx, "\tsecond_chroma_qp_index_offset = %d\n", p->second_chroma_qp_index_offset);
+    va_TraceMsg(trace_ctx, "\tpic_fields = 0x%03x\n", p->pic_fields.value);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\tentropy_coding_mode_flag", p->pic_fields.bits.entropy_coding_mode_flag);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\tweighted_pred_flag", p->pic_fields.bits.weighted_pred_flag);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\tweighted_bipred_idc", p->pic_fields.bits.weighted_bipred_idc);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\ttransform_8x8_mode_flag", p->pic_fields.bits.transform_8x8_mode_flag);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\tfield_pic_flag", p->pic_fields.bits.field_pic_flag);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\tconstrained_intra_pred_flag", p->pic_fields.bits.constrained_intra_pred_flag);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\tpic_order_present_flag", p->pic_fields.bits.pic_order_present_flag);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\tdeblocking_filter_control_present_flag", p->pic_fields.bits.deblocking_filter_control_present_flag);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\tredundant_pic_cnt_present_flag", p->pic_fields.bits.redundant_pic_cnt_present_flag);
+    va_TraceFlagIfNotZero(trace_ctx, "\t\treference_pic_flag", p->pic_fields.bits.reference_pic_flag);
+    va_TraceMsg(trace_ctx, "\tframe_num = %d\n", p->frame_num);
+    va_TraceMsg(trace_ctx, "\tnum_ref_idx_l0_default_active_minus1 = %d\n", p->num_ref_idx_l0_default_active_minus1);
+    va_TraceMsg(trace_ctx, "\tnum_ref_idx_l1_default_active_minus1 = %d\n", p->num_ref_idx_l1_default_active_minus1);
+
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
 
 static void va_TraceVASliceParameterBufferH264(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     int i;
     VASliceParameterBufferH264* p = (VASliceParameterBufferH264*)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    trace_context[idx].trace_slice_no++;
-    trace_context[idx].trace_slice_size = p->slice_data_size;
+    trace_ctx->trace_slice_no++;
+    trace_ctx->trace_slice_size = p->slice_data_size;
 
-    va_TraceMsg(idx, "VASliceParameterBufferH264\n");
-    va_TraceMsg(idx, "\tslice_data_size = %d\n", p->slice_data_size);
-    va_TraceMsg(idx, "\tslice_data_offset = %d\n", p->slice_data_offset);
-    va_TraceMsg(idx, "\tslice_data_flag = %d\n", p->slice_data_flag);
-    va_TraceMsg(idx, "\tslice_data_bit_offset = %d\n", p->slice_data_bit_offset);
-    va_TraceMsg(idx, "\tfirst_mb_in_slice = %d\n", p->first_mb_in_slice);
-    va_TraceMsg(idx, "\tslice_type = %d\n", p->slice_type);
-    va_TraceMsg(idx, "\tdirect_spatial_mv_pred_flag = %d\n", p->direct_spatial_mv_pred_flag);
-    va_TraceMsg(idx, "\tnum_ref_idx_l0_active_minus1 = %d\n", p->num_ref_idx_l0_active_minus1);
-    va_TraceMsg(idx, "\tnum_ref_idx_l1_active_minus1 = %d\n", p->num_ref_idx_l1_active_minus1);
-    va_TraceMsg(idx, "\tcabac_init_idc = %d\n", p->cabac_init_idc);
-    va_TraceMsg(idx, "\tslice_qp_delta = %d\n", p->slice_qp_delta);
-    va_TraceMsg(idx, "\tdisable_deblocking_filter_idc = %d\n", p->disable_deblocking_filter_idc);
-    va_TraceMsg(idx, "\tslice_alpha_c0_offset_div2 = %d\n", p->slice_alpha_c0_offset_div2);
-    va_TraceMsg(idx, "\tslice_beta_offset_div2 = %d\n", p->slice_beta_offset_div2);
+    va_TraceMsg(trace_ctx, "\t--VASliceParameterBufferH264\n");
+    va_TraceMsg(trace_ctx, "\tslice_data_size = %d\n", p->slice_data_size);
+    va_TraceMsg(trace_ctx, "\tslice_data_offset = %d\n", p->slice_data_offset);
+    va_TraceMsg(trace_ctx, "\tslice_data_flag = %d\n", p->slice_data_flag);
+    va_TraceMsg(trace_ctx, "\tslice_data_bit_offset = %d\n", p->slice_data_bit_offset);
+    va_TraceMsg(trace_ctx, "\tfirst_mb_in_slice = %d\n", p->first_mb_in_slice);
+    va_TraceMsg(trace_ctx, "\tslice_type = %d\n", p->slice_type);
+    va_TraceMsg(trace_ctx, "\tdirect_spatial_mv_pred_flag = %d\n", p->direct_spatial_mv_pred_flag);
+    va_TraceMsg(trace_ctx, "\tnum_ref_idx_l0_active_minus1 = %d\n", p->num_ref_idx_l0_active_minus1);
+    va_TraceMsg(trace_ctx, "\tnum_ref_idx_l1_active_minus1 = %d\n", p->num_ref_idx_l1_active_minus1);
+    va_TraceMsg(trace_ctx, "\tcabac_init_idc = %d\n", p->cabac_init_idc);
+    va_TraceMsg(trace_ctx, "\tslice_qp_delta = %d\n", p->slice_qp_delta);
+    va_TraceMsg(trace_ctx, "\tdisable_deblocking_filter_idc = %d\n", p->disable_deblocking_filter_idc);
+    va_TraceMsg(trace_ctx, "\tslice_alpha_c0_offset_div2 = %d\n", p->slice_alpha_c0_offset_div2);
+    va_TraceMsg(trace_ctx, "\tslice_beta_offset_div2 = %d\n", p->slice_beta_offset_div2);
 
-    if (p->slice_type == 0 || p->slice_type == 1) {
-        va_TraceMsg(idx, "\tRefPicList0 =");
-        for (i = 0; i < p->num_ref_idx_l0_active_minus1 + 1; i++) {
-            va_TraceMsg(idx, "%d-%d-0x%08x-%d\n", p->RefPicList0[i].TopFieldOrderCnt, p->RefPicList0[i].BottomFieldOrderCnt, p->RefPicList0[i].picture_id, p->RefPicList0[i].frame_idx);
-        }
-        if (p->slice_type == 1) {
-            va_TraceMsg(idx, "\tRefPicList1 =");
-            for (i = 0; i < p->num_ref_idx_l1_active_minus1 + 1; i++)
-            {
-                va_TraceMsg(idx, "%d-%d-0x%08x-%d\n", p->RefPicList1[i].TopFieldOrderCnt, p->RefPicList1[i].BottomFieldOrderCnt, p->RefPicList1[i].picture_id, p->RefPicList1[i].frame_idx);
-            }
-        }
+    va_TraceMsg(trace_ctx, "\tRefPicList0 =\n");
+    for (i = 0; i < 32; i++) {
+        if ((p->RefPicList0[i].picture_id != VA_INVALID_SURFACE) &&
+            ((p->RefPicList0[i].flags & VA_PICTURE_H264_INVALID) == 0))
+        va_TraceMsg(trace_ctx, "%08d-%08d-0x%08x-%08d-0x%08x\n", p->RefPicList0[i].TopFieldOrderCnt, p->RefPicList0[i].BottomFieldOrderCnt, p->RefPicList0[i].picture_id, p->RefPicList0[i].frame_idx,  p->RefPicList0[i].flags);
+        else
+            break;
     }
-    
-    va_TraceMsg(idx, "\tluma_log2_weight_denom = %d\n", p->luma_log2_weight_denom);
-    va_TraceMsg(idx, "\tchroma_log2_weight_denom = %d\n", p->chroma_log2_weight_denom);
-    va_TraceMsg(idx, "\tluma_weight_l0_flag = %d\n", p->luma_weight_l0_flag);
-    if (p->luma_weight_l0_flag) {
-        for (i = 0; i <=  p->num_ref_idx_l0_active_minus1; i++) {
-            va_TraceMsg(idx, "\t%d ", p->luma_weight_l0[i]);
-            va_TraceMsg(idx, "\t%d ", p->luma_offset_l0[i]);
-        }
+    va_TraceMsg(trace_ctx, "\tRefPicList1 =\n");
+    for (i = 0; i < 32; i++) {
+        if ((p->RefPicList1[i].picture_id != VA_INVALID_SURFACE) &&
+            ((p->RefPicList1[i].flags & VA_PICTURE_H264_INVALID) == 0))
+            va_TraceMsg(trace_ctx, "%08d-%08d-0x%08x-%08d-0x%08x\n", p->RefPicList1[i].TopFieldOrderCnt, p->RefPicList1[i].BottomFieldOrderCnt, p->RefPicList1[i].picture_id, p->RefPicList1[i].frame_idx, p->RefPicList1[i].flags);
+        else
+            break;
     }
 
-    va_TraceMsg(idx, "\tchroma_weight_l0_flag = %d\n", p->chroma_weight_l0_flag);
-    if (p->chroma_weight_l0_flag) {
-        for (i = 0; i <= p->num_ref_idx_l0_active_minus1; i++) {
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_weight_l0[i][0]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_offset_l0[i][0]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_weight_l0[i][1]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_offset_l0[i][1]);
-        }
+    va_TraceMsg(trace_ctx, "\tluma_log2_weight_denom = %d\n", p->luma_log2_weight_denom);
+    va_TraceMsg(trace_ctx, "\tchroma_log2_weight_denom = %d\n", p->chroma_log2_weight_denom);
+    va_TraceMsg(trace_ctx, "\tluma_weight_l0_flag = %d\n", p->luma_weight_l0_flag);
+
+    for (i = 0; (i <= p->num_ref_idx_l0_active_minus1) && (i<32); i++) {
+        va_TraceMsg(trace_ctx, "\t\t%d\t%d\n",
+            p->luma_weight_l0[i],
+            p->luma_offset_l0[i]);
     }
-    
-    va_TraceMsg(idx, "\tluma_weight_l1_flag = %d\n", p->luma_weight_l1_flag);
-    if (p->luma_weight_l1_flag) {
-        for (i = 0; i <=  p->num_ref_idx_l1_active_minus1; i++) {
-            va_TraceMsg(idx, "\t\t%d ", p->luma_weight_l1[i]);
-            va_TraceMsg(idx, "\t\t%d ", p->luma_offset_l1[i]);
-        }
+
+
+    va_TraceMsg(trace_ctx, "\tchroma_weight_l0_flag = %d\n", p->chroma_weight_l0_flag);
+
+    for (i = 0; (i <= p->num_ref_idx_l0_active_minus1) && (i<32); i++) {
+        va_TraceMsg(trace_ctx, "\t\t%d\t%d\t%d\t%d\n",
+            p->chroma_weight_l0[i][0],
+            p->chroma_offset_l0[i][0],
+            p->chroma_weight_l0[i][1],
+            p->chroma_offset_l0[i][1]);
     }
-    
-    va_TraceMsg(idx, "\tchroma_weight_l1_flag = %d\n", p->chroma_weight_l1_flag);
-    if (p->chroma_weight_l1_flag) {
-        for (i = 0; i <= p->num_ref_idx_l1_active_minus1; i++) {
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_weight_l1[i][0]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_offset_l1[i][0]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_weight_l1[i][1]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_offset_l1[i][1]);
-        }
-        va_TraceMsg(idx, "\n");
+
+
+    va_TraceMsg(trace_ctx, "\tluma_weight_l1_flag = %d\n", p->luma_weight_l1_flag);
+
+    for (i = 0; (i <=  p->num_ref_idx_l1_active_minus1) && (i<32); i++) {
+        va_TraceMsg(trace_ctx, "\t\t%d\t%d\n",
+            p->luma_weight_l1[i],
+            p->luma_offset_l1[i]);
     }
-    va_TraceMsg(idx, NULL);
+
+
+    va_TraceMsg(trace_ctx, "\tchroma_weight_l1_flag = %d\n", p->chroma_weight_l1_flag);
+
+    for (i = 0; (i <= p->num_ref_idx_l1_active_minus1) && (i<32); i++) {
+        va_TraceMsg(trace_ctx, "\t\t%d\t%d\t%d\t%d\n",
+            p->chroma_weight_l1[i][0],
+            p->chroma_offset_l1[i][0],
+            p->chroma_weight_l1[i][1],
+            p->chroma_offset_l1[i][1]);
+
+    }
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 static void va_TraceVAIQMatrixBufferH264(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data
 )
 {
-    int i, j;    
+    int i, j;
     VAIQMatrixBufferH264* p = (VAIQMatrixBufferH264* )data;
 
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    va_TraceMsg(idx, "VAIQMatrixBufferH264\n");
+    va_TraceMsg(trace_ctx, "\t--VAIQMatrixBufferH264\n");
 
-    va_TraceMsg(idx, "\tScalingList4x4[6][16]=\n");
+    va_TraceMsg(trace_ctx, "\tScalingList4x4[6][16]=\n");
     for (i = 0; i < 6; i++) {
         for (j = 0; j < 16; j++) {
-            va_TraceMsg(idx, "\t%d\t", p->ScalingList4x4[i][j]);
-            if ((j + 1) % 8 == 0)
-                va_TraceMsg(idx, "\n");
+            if (trace_ctx->trace_fp_log) {
+                fprintf(trace_ctx->trace_fp_log, "\t%d", p->ScalingList4x4[i][j]);
+                if ((j + 1) % 8 == 0)
+                    fprintf(trace_ctx->trace_fp_log, "\n");
+            }
         }
     }
 
-    va_TraceMsg(idx, "\tScalingList8x8[2][64]=\n");
+    va_TraceMsg(trace_ctx, "\tScalingList8x8[2][64]=\n");
     for (i = 0; i < 2; i++) {
         for (j = 0; j < 64; j++) {
-            va_TraceMsg(idx, "\t%d", p->ScalingList8x8[i][j]);
-            if ((j + 1) % 8 == 0)
-                va_TraceMsg(idx, "\n");
+            if (trace_ctx->trace_fp_log) {
+                fprintf(trace_ctx->trace_fp_log,"\t%d", p->ScalingList8x8[i][j]);
+                if ((j + 1) % 8 == 0)
+                    fprintf(trace_ctx->trace_fp_log, "\n");
+            }
         }
     }
 
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
+
+
 static void va_TraceVAEncSequenceParameterBufferH264(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAEncSequenceParameterBufferH264 *p = (VAEncSequenceParameterBufferH264 *)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
     unsigned int i;
 
-    va_TraceMsg(idx, "VAEncSequenceParameterBufferH264\n");
+    va_TraceMsg(trace_ctx, "\t--VAEncSequenceParameterBufferH264\n");
 
-    va_TraceMsg(idx, "\tseq_parameter_set_id = %d\n", p->seq_parameter_set_id);
-    va_TraceMsg(idx, "\tlevel_idc = %d\n", p->level_idc);
-    va_TraceMsg(idx, "\tintra_period = %d\n", p->intra_period);
-    va_TraceMsg(idx, "\tintra_idr_period = %d\n", p->intra_idr_period);
-    va_TraceMsg(idx, "\tip_period = %d\n", p->ip_period);
-    va_TraceMsg(idx, "\tbits_per_second = %d\n", p->bits_per_second);
-    va_TraceMsg(idx, "\tmax_num_ref_frames = %d\n", p->max_num_ref_frames);
-    va_TraceMsg(idx, "\tpicture_width_in_mbs = %d\n", p->picture_width_in_mbs);
-    va_TraceMsg(idx, "\tpicture_height_in_mbs = %d\n", p->picture_height_in_mbs);
-    va_TraceMsg(idx, "\tchroma_format_idc = %d\n", p->seq_fields.bits.chroma_format_idc);
-    va_TraceMsg(idx, "\tframe_mbs_only_flag = %d\n", p->seq_fields.bits.frame_mbs_only_flag);
-    va_TraceMsg(idx, "\tmb_adaptive_frame_field_flag = %d\n", p->seq_fields.bits.mb_adaptive_frame_field_flag);
-    va_TraceMsg(idx, "\tseq_scaling_matrix_present_flag = %d\n", p->seq_fields.bits.seq_scaling_matrix_present_flag);
-    va_TraceMsg(idx, "\tdirect_8x8_inference_flag = %d\n", p->seq_fields.bits.direct_8x8_inference_flag);
-    va_TraceMsg(idx, "\tlog2_max_frame_num_minus4 = %d\n", p->seq_fields.bits.log2_max_frame_num_minus4);
-    va_TraceMsg(idx, "\tpic_order_cnt_type = %d\n", p->seq_fields.bits.pic_order_cnt_type);
-    va_TraceMsg(idx, "\tlog2_max_pic_order_cnt_lsb_minus4 = %d\n", p->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
-    va_TraceMsg(idx, "\tdelta_pic_order_always_zero_flag = %d\n", p->seq_fields.bits.delta_pic_order_always_zero_flag);
-    va_TraceMsg(idx, "\tbit_depth_luma_minus8 = %d\n", p->bit_depth_luma_minus8);
-    va_TraceMsg(idx, "\tbit_depth_chroma_minus8 = %d\n", p->bit_depth_chroma_minus8);
-    va_TraceMsg(idx, "\tnum_ref_frames_in_pic_order_cnt_cycle = %d\n", p->num_ref_frames_in_pic_order_cnt_cycle);
-    va_TraceMsg(idx, "\toffset_for_non_ref_pic = %d\n", p->offset_for_non_ref_pic);
-    va_TraceMsg(idx, "\toffset_for_top_to_bottom_field = %d\n", p->offset_for_top_to_bottom_field);
-    for(i = 0; i< p->max_num_ref_frames; ++i)
-        va_TraceMsg(idx, "\toffset_for_ref_frame[%d] = %d\n", i, p->offset_for_ref_frame[i]);
-    va_TraceMsg(idx, "\tframe_cropping_flag = %d\n", p->frame_cropping_flag);
-    va_TraceMsg(idx, "\tframe_crop_left_offset = %d\n", p->frame_crop_left_offset);
-    va_TraceMsg(idx, "\tframe_crop_right_offset = %d\n", p->frame_crop_right_offset);
-    va_TraceMsg(idx, "\tframe_crop_top_offset = %d\n", p->frame_crop_top_offset);
-    va_TraceMsg(idx, "\tframe_crop_bottom_offset = %d\n", p->frame_crop_bottom_offset);
-    va_TraceMsg(idx, "\tvui_parameters_present_flag = %d\n", p->vui_parameters_present_flag);
-    va_TraceMsg(idx, "\taspect_ratio_info_present_flag = %d\n", p->vui_fields.bits.aspect_ratio_info_present_flag);
-    va_TraceMsg(idx, "\ttiming_info_present_flag = %d\n", p->vui_fields.bits.timing_info_present_flag);
-    va_TraceMsg(idx, "\tbitstream_restriction_flag = %d\n", p->vui_fields.bits.bitstream_restriction_flag);
-    va_TraceMsg(idx, "\tlog2_max_mv_length_horizontal = %d\n", p->vui_fields.bits.log2_max_mv_length_horizontal);
-    va_TraceMsg(idx, "\tlog2_max_mv_length_vertical = %d\n", p->vui_fields.bits.log2_max_mv_length_vertical);
-    va_TraceMsg(idx, "\taspect_ratio_idc = %d\n", p->aspect_ratio_idc);
-    va_TraceMsg(idx, "\tsar_width = %d\n", p->sar_width);
-    va_TraceMsg(idx, "\tsar_height = %d\n", p->sar_height);
-    va_TraceMsg(idx, "\tnum_units_in_tick = %d\n", p->num_units_in_tick);
-    va_TraceMsg(idx, "\ttime_scale = %d\n", p->time_scale);
+    va_TraceMsg(trace_ctx, "\tseq_parameter_set_id = %d\n", p->seq_parameter_set_id);
+    va_TraceMsg(trace_ctx, "\tlevel_idc = %d\n", p->level_idc);
+    va_TraceMsg(trace_ctx, "\tintra_period = %d\n", p->intra_period);
+    va_TraceMsg(trace_ctx, "\tintra_idr_period = %d\n", p->intra_idr_period);
+    va_TraceMsg(trace_ctx, "\tip_period = %d\n", p->ip_period);
+    va_TraceMsg(trace_ctx, "\tbits_per_second = %d\n", p->bits_per_second);
+    va_TraceMsg(trace_ctx, "\tmax_num_ref_frames = %d\n", p->max_num_ref_frames);
+    va_TraceMsg(trace_ctx, "\tpicture_width_in_mbs = %d\n", p->picture_width_in_mbs);
+    va_TraceMsg(trace_ctx, "\tpicture_height_in_mbs = %d\n", p->picture_height_in_mbs);
+    va_TraceMsg(trace_ctx, "\tchroma_format_idc = %d\n", p->seq_fields.bits.chroma_format_idc);
+    va_TraceMsg(trace_ctx, "\tframe_mbs_only_flag = %d\n", p->seq_fields.bits.frame_mbs_only_flag);
+    va_TraceMsg(trace_ctx, "\tmb_adaptive_frame_field_flag = %d\n", p->seq_fields.bits.mb_adaptive_frame_field_flag);
+    va_TraceMsg(trace_ctx, "\tseq_scaling_matrix_present_flag = %d\n", p->seq_fields.bits.seq_scaling_matrix_present_flag);
+    va_TraceMsg(trace_ctx, "\tdirect_8x8_inference_flag = %d\n", p->seq_fields.bits.direct_8x8_inference_flag);
+    va_TraceMsg(trace_ctx, "\tlog2_max_frame_num_minus4 = %d\n", p->seq_fields.bits.log2_max_frame_num_minus4);
+    va_TraceMsg(trace_ctx, "\tpic_order_cnt_type = %d\n", p->seq_fields.bits.pic_order_cnt_type);
+    va_TraceMsg(trace_ctx, "\tlog2_max_pic_order_cnt_lsb_minus4 = %d\n", p->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
+    va_TraceMsg(trace_ctx, "\tdelta_pic_order_always_zero_flag = %d\n", p->seq_fields.bits.delta_pic_order_always_zero_flag);
+    va_TraceMsg(trace_ctx, "\tbit_depth_luma_minus8 = %d\n", p->bit_depth_luma_minus8);
+    va_TraceMsg(trace_ctx, "\tbit_depth_chroma_minus8 = %d\n", p->bit_depth_chroma_minus8);
+    va_TraceMsg(trace_ctx, "\tnum_ref_frames_in_pic_order_cnt_cycle = %d\n", p->num_ref_frames_in_pic_order_cnt_cycle);
+    va_TraceMsg(trace_ctx, "\toffset_for_non_ref_pic = %d\n", p->offset_for_non_ref_pic);
+    va_TraceMsg(trace_ctx, "\toffset_for_top_to_bottom_field = %d\n", p->offset_for_top_to_bottom_field);
+    for(i = 0; (i < p->max_num_ref_frames) && (i < 32); ++i)
+        va_TraceMsg(trace_ctx, "\toffset_for_ref_frame[%d] = %d\n", i, p->offset_for_ref_frame[i]);
+    va_TraceMsg(trace_ctx, "\tframe_cropping_flag = %d\n", p->frame_cropping_flag);
+    va_TraceMsg(trace_ctx, "\tframe_crop_left_offset = %d\n", p->frame_crop_left_offset);
+    va_TraceMsg(trace_ctx, "\tframe_crop_right_offset = %d\n", p->frame_crop_right_offset);
+    va_TraceMsg(trace_ctx, "\tframe_crop_top_offset = %d\n", p->frame_crop_top_offset);
+    va_TraceMsg(trace_ctx, "\tframe_crop_bottom_offset = %d\n", p->frame_crop_bottom_offset);
+    va_TraceMsg(trace_ctx, "\tvui_parameters_present_flag = %d\n", p->vui_parameters_present_flag);
+    va_TraceMsg(trace_ctx, "\taspect_ratio_info_present_flag = %d\n", p->vui_fields.bits.aspect_ratio_info_present_flag);
+    va_TraceMsg(trace_ctx, "\ttiming_info_present_flag = %d\n", p->vui_fields.bits.timing_info_present_flag);
+    va_TraceMsg(trace_ctx, "\tbitstream_restriction_flag = %d\n", p->vui_fields.bits.bitstream_restriction_flag);
+    va_TraceMsg(trace_ctx, "\tlog2_max_mv_length_horizontal = %d\n", p->vui_fields.bits.log2_max_mv_length_horizontal);
+    va_TraceMsg(trace_ctx, "\tlog2_max_mv_length_vertical = %d\n", p->vui_fields.bits.log2_max_mv_length_vertical);
+    va_TraceMsg(trace_ctx, "\taspect_ratio_idc = %d\n", p->aspect_ratio_idc);
+    va_TraceMsg(trace_ctx, "\tsar_width = %d\n", p->sar_width);
+    va_TraceMsg(trace_ctx, "\tsar_height = %d\n", p->sar_height);
+    va_TraceMsg(trace_ctx, "\tnum_units_in_tick = %d\n", p->num_units_in_tick);
+    va_TraceMsg(trace_ctx, "\ttime_scale = %d\n", p->time_scale);
 
-    va_TraceMsg(idx, NULL);
-
-    /* start a new sequce, coded log file can be truncated */
-    trace_context[idx].trace_sequence_start = 1;
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
@@ -1248,180 +1484,230 @@
 
 static void va_TraceVAEncPictureParameterBufferH264(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAEncPictureParameterBufferH264 *p = (VAEncPictureParameterBufferH264 *)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
     int i;
 
-    va_TraceMsg(idx, "VAEncPictureParameterBufferH264\n");
+    va_TraceMsg(trace_ctx, "\t--VAEncPictureParameterBufferH264\n");
 
-    va_TraceMsg(idx, "\tCurrPic.picture_id = 0x%08x\n", p->CurrPic.picture_id);
-    va_TraceMsg(idx, "\tCurrPic.frame_idx = %d\n", p->CurrPic.frame_idx);
-    va_TraceMsg(idx, "\tCurrPic.flags = %d\n", p->CurrPic.flags);
-    va_TraceMsg(idx, "\tCurrPic.TopFieldOrderCnt = %d\n", p->CurrPic.TopFieldOrderCnt);
-    va_TraceMsg(idx, "\tCurrPic.BottomFieldOrderCnt = %d\n", p->CurrPic.BottomFieldOrderCnt);
-    va_TraceMsg(idx, "\tReferenceFrames (TopFieldOrderCnt-BottomFieldOrderCnt-picture_id-frame_idx:\n");
+    va_TraceMsg(trace_ctx, "\tCurrPic.picture_id = 0x%08x\n", p->CurrPic.picture_id);
+    va_TraceMsg(trace_ctx, "\tCurrPic.frame_idx = %d\n", p->CurrPic.frame_idx);
+    va_TraceMsg(trace_ctx, "\tCurrPic.flags = %d\n", p->CurrPic.flags);
+    va_TraceMsg(trace_ctx, "\tCurrPic.TopFieldOrderCnt = %d\n", p->CurrPic.TopFieldOrderCnt);
+    va_TraceMsg(trace_ctx, "\tCurrPic.BottomFieldOrderCnt = %d\n", p->CurrPic.BottomFieldOrderCnt);
+    va_TraceMsg(trace_ctx, "\tReferenceFrames (TopFieldOrderCnt-BottomFieldOrderCnt-picture_id-frame_idx-flags):\n");
     for (i = 0; i < 16; i++)
     {
-        if (p->ReferenceFrames[i].flags != VA_PICTURE_H264_INVALID) {
-            va_TraceMsg(idx, "\t\t%d-%d-0x%08x-%d\n",
+        if ((p->ReferenceFrames[i].picture_id != VA_INVALID_SURFACE) &&
+            ((p->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID) == 0)) {
+            va_TraceMsg(trace_ctx, "\t\t%08d-%08d-0x%08x-%08d-0x%08x\n",
                         p->ReferenceFrames[i].TopFieldOrderCnt,
                         p->ReferenceFrames[i].BottomFieldOrderCnt,
                         p->ReferenceFrames[i].picture_id,
-                        p->ReferenceFrames[i].frame_idx);
+                        p->ReferenceFrames[i].frame_idx,
+                        p->ReferenceFrames[i].flags
+                        );
         } else
-            va_TraceMsg(idx, "\t\tinv-inv-inv-inv\n");
+            break;
     }
-    va_TraceMsg(idx, "\tcoded_buf = %08x\n", p->coded_buf);
-    va_TraceMsg(idx, "\tpic_parameter_set_id = %d\n", p->pic_parameter_set_id);
-    va_TraceMsg(idx, "\tseq_parameter_set_id = %d\n", p->seq_parameter_set_id);
-    va_TraceMsg(idx, "\tlast_picture = 0x%08x\n", p->last_picture);
-    va_TraceMsg(idx, "\tframe_num = %d\n", p->frame_num);
-    va_TraceMsg(idx, "\tpic_init_qp = %d\n", p->pic_init_qp);
-    va_TraceMsg(idx, "\tnum_ref_idx_l0_active_minus1 = %d\n", p->num_ref_idx_l0_active_minus1);
-    va_TraceMsg(idx, "\tnum_ref_idx_l1_active_minus1 = %d\n", p->num_ref_idx_l1_active_minus1);
-    va_TraceMsg(idx, "\tchroma_qp_index_offset = %d\n", p->chroma_qp_index_offset);
-    va_TraceMsg(idx, "\tsecond_chroma_qp_index_offset = %d\n", p->second_chroma_qp_index_offset);
-    va_TraceMsg(idx, "\tpic_fields = 0x%03x\n", p->pic_fields.value);
-    va_TraceMsg(idx, "\tidr_pic_flag = %d\n", p->pic_fields.bits.idr_pic_flag);
-    va_TraceMsg(idx, "\treference_pic_flag = %d\n", p->pic_fields.bits.reference_pic_flag);
-    va_TraceMsg(idx, "\tentropy_coding_mode_flag = %d\n", p->pic_fields.bits.entropy_coding_mode_flag);
-    va_TraceMsg(idx, "\tweighted_pred_flag = %d\n", p->pic_fields.bits.weighted_pred_flag);
-    va_TraceMsg(idx, "\tweighted_bipred_idc = %d\n", p->pic_fields.bits.weighted_bipred_idc);
-    va_TraceMsg(idx, "\tconstrained_intra_pred_flag = %d\n", p->pic_fields.bits.constrained_intra_pred_flag);
-    va_TraceMsg(idx, "\ttransform_8x8_mode_flag = %d\n", p->pic_fields.bits.transform_8x8_mode_flag);
-    va_TraceMsg(idx, "\tdeblocking_filter_control_present_flag = %d\n", p->pic_fields.bits.deblocking_filter_control_present_flag);
-    va_TraceMsg(idx, "\tredundant_pic_cnt_present_flag = %d\n", p->pic_fields.bits.redundant_pic_cnt_present_flag);
-    va_TraceMsg(idx, "\tpic_order_present_flag = %d\n", p->pic_fields.bits.pic_order_present_flag);
-    va_TraceMsg(idx, "\tpic_scaling_matrix_present_flag = %d\n", p->pic_fields.bits.pic_scaling_matrix_present_flag);
+    va_TraceMsg(trace_ctx, "\tcoded_buf = %08x\n", p->coded_buf);
+    va_TraceMsg(trace_ctx, "\tpic_parameter_set_id = %d\n", p->pic_parameter_set_id);
+    va_TraceMsg(trace_ctx, "\tseq_parameter_set_id = %d\n", p->seq_parameter_set_id);
+    va_TraceMsg(trace_ctx, "\tlast_picture = 0x%08x\n", p->last_picture);
+    va_TraceMsg(trace_ctx, "\tframe_num = %d\n", p->frame_num);
+    va_TraceMsg(trace_ctx, "\tpic_init_qp = %d\n", p->pic_init_qp);
+    va_TraceMsg(trace_ctx, "\tnum_ref_idx_l0_active_minus1 = %d\n", p->num_ref_idx_l0_active_minus1);
+    va_TraceMsg(trace_ctx, "\tnum_ref_idx_l1_active_minus1 = %d\n", p->num_ref_idx_l1_active_minus1);
+    va_TraceMsg(trace_ctx, "\tchroma_qp_index_offset = %d\n", p->chroma_qp_index_offset);
+    va_TraceMsg(trace_ctx, "\tsecond_chroma_qp_index_offset = %d\n", p->second_chroma_qp_index_offset);
+    va_TraceMsg(trace_ctx, "\tpic_fields = 0x%03x\n", p->pic_fields.value);
+    va_TraceMsg(trace_ctx, "\tidr_pic_flag = %d\n", p->pic_fields.bits.idr_pic_flag);
+    va_TraceMsg(trace_ctx, "\treference_pic_flag = %d\n", p->pic_fields.bits.reference_pic_flag);
+    va_TraceMsg(trace_ctx, "\tentropy_coding_mode_flag = %d\n", p->pic_fields.bits.entropy_coding_mode_flag);
+    va_TraceMsg(trace_ctx, "\tweighted_pred_flag = %d\n", p->pic_fields.bits.weighted_pred_flag);
+    va_TraceMsg(trace_ctx, "\tweighted_bipred_idc = %d\n", p->pic_fields.bits.weighted_bipred_idc);
+    va_TraceMsg(trace_ctx, "\tconstrained_intra_pred_flag = %d\n", p->pic_fields.bits.constrained_intra_pred_flag);
+    va_TraceMsg(trace_ctx, "\ttransform_8x8_mode_flag = %d\n", p->pic_fields.bits.transform_8x8_mode_flag);
+    va_TraceMsg(trace_ctx, "\tdeblocking_filter_control_present_flag = %d\n", p->pic_fields.bits.deblocking_filter_control_present_flag);
+    va_TraceMsg(trace_ctx, "\tredundant_pic_cnt_present_flag = %d\n", p->pic_fields.bits.redundant_pic_cnt_present_flag);
+    va_TraceMsg(trace_ctx, "\tpic_order_present_flag = %d\n", p->pic_fields.bits.pic_order_present_flag);
+    va_TraceMsg(trace_ctx, "\tpic_scaling_matrix_present_flag = %d\n", p->pic_fields.bits.pic_scaling_matrix_present_flag);
 
-    va_TraceMsg(idx, NULL);
-
-    trace_context[idx].trace_codedbuf =  p->coded_buf;
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
 
 static void va_TraceVAEncSliceParameterBuffer(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAEncSliceParameterBuffer* p = (VAEncSliceParameterBuffer*)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx, "\t--VAEncSliceParameterBuffer\n");
     
-    va_TraceMsg(idx, "VAEncSliceParameterBuffer\n");
-    
-    va_TraceMsg(idx, "\tstart_row_number = %d\n", p->start_row_number);
-    va_TraceMsg(idx, "\tslice_height = %d\n", p->slice_height);
-    va_TraceMsg(idx, "\tslice_flags.is_intra = %d\n", p->slice_flags.bits.is_intra);
-    va_TraceMsg(idx, "\tslice_flags.disable_deblocking_filter_idc = %d\n", p->slice_flags.bits.disable_deblocking_filter_idc);
-    va_TraceMsg(idx, "\tslice_flags.uses_long_term_ref = %d\n", p->slice_flags.bits.uses_long_term_ref);
-    va_TraceMsg(idx, "\tslice_flags.is_long_term_ref = %d\n", p->slice_flags.bits.is_long_term_ref);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "\tstart_row_number = %d\n", p->start_row_number);
+    va_TraceMsg(trace_ctx, "\tslice_height = %d\n", p->slice_height);
+    va_TraceMsg(trace_ctx, "\tslice_flags.is_intra = %d\n", p->slice_flags.bits.is_intra);
+    va_TraceMsg(trace_ctx, "\tslice_flags.disable_deblocking_filter_idc = %d\n", p->slice_flags.bits.disable_deblocking_filter_idc);
+    va_TraceMsg(trace_ctx, "\tslice_flags.uses_long_term_ref = %d\n", p->slice_flags.bits.uses_long_term_ref);
+    va_TraceMsg(trace_ctx, "\tslice_flags.is_long_term_ref = %d\n", p->slice_flags.bits.is_long_term_ref);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
 
 static void va_TraceVAEncSliceParameterBufferH264(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAEncSliceParameterBufferH264* p = (VAEncSliceParameterBufferH264*)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
     int i;
 
-    va_TraceMsg(idx, "VAEncSliceParameterBufferH264\n");
-    va_TraceMsg(idx, "\tmacroblock_address = %d\n", p->macroblock_address);
-    va_TraceMsg(idx, "\tnum_macroblocks = %d\n", p->num_macroblocks);
-    va_TraceMsg(idx, "\tmacroblock_info = %08x\n", p->macroblock_info);
-    va_TraceMsg(idx, "\tslice_type = %d\n", p->slice_type);
-    va_TraceMsg(idx, "\tpic_parameter_set_id = %d\n", p->pic_parameter_set_id);
-    va_TraceMsg(idx, "\tidr_pic_id = %d\n", p->idr_pic_id);
-    va_TraceMsg(idx, "\tpic_order_cnt_lsb = %d\n", p->pic_order_cnt_lsb);
-    va_TraceMsg(idx, "\tdelta_pic_order_cnt_bottom = %d\n", p->delta_pic_order_cnt_bottom);
-    va_TraceMsg(idx, "\tdelta_pic_order_cnt[0] = %d\n", p->delta_pic_order_cnt[0]);
-    va_TraceMsg(idx, "\tdelta_pic_order_cnt[1] = %d\n", p->delta_pic_order_cnt[1]);
-    va_TraceMsg(idx, "\tdirect_spatial_mv_pred_flag = %d\n", p->direct_spatial_mv_pred_flag);
-    va_TraceMsg(idx, "\tnum_ref_idx_active_override_flag = %d\n", p->num_ref_idx_active_override_flag);
-    va_TraceMsg(idx, "\tnum_ref_idx_l1_active_minus1 = %d\n", p->num_ref_idx_l1_active_minus1);
-    va_TraceMsg(idx, "\tslice_beta_offset_div2 = %d\n", p->slice_beta_offset_div2);
+    if (!p)
+        return;
+    
+    va_TraceMsg(trace_ctx, "\t--VAEncSliceParameterBufferH264\n");
+    va_TraceMsg(trace_ctx, "\tmacroblock_address = %d\n", p->macroblock_address);
+    va_TraceMsg(trace_ctx, "\tnum_macroblocks = %d\n", p->num_macroblocks);
+    va_TraceMsg(trace_ctx, "\tmacroblock_info = %08x\n", p->macroblock_info);
+    va_TraceMsg(trace_ctx, "\tslice_type = %d\n", p->slice_type);
+    va_TraceMsg(trace_ctx, "\tpic_parameter_set_id = %d\n", p->pic_parameter_set_id);
+    va_TraceMsg(trace_ctx, "\tidr_pic_id = %d\n", p->idr_pic_id);
+    va_TraceMsg(trace_ctx, "\tpic_order_cnt_lsb = %d\n", p->pic_order_cnt_lsb);
+    va_TraceMsg(trace_ctx, "\tdelta_pic_order_cnt_bottom = %d\n", p->delta_pic_order_cnt_bottom);
+    va_TraceMsg(trace_ctx, "\tdelta_pic_order_cnt[0] = %d\n", p->delta_pic_order_cnt[0]);
+    va_TraceMsg(trace_ctx, "\tdelta_pic_order_cnt[1] = %d\n", p->delta_pic_order_cnt[1]);
+    va_TraceMsg(trace_ctx, "\tdirect_spatial_mv_pred_flag = %d\n", p->direct_spatial_mv_pred_flag);
+    va_TraceMsg(trace_ctx, "\tnum_ref_idx_active_override_flag = %d\n", p->num_ref_idx_active_override_flag);
+    va_TraceMsg(trace_ctx, "\tnum_ref_idx_l1_active_minus1 = %d\n", p->num_ref_idx_l1_active_minus1);
+    va_TraceMsg(trace_ctx, "\tslice_beta_offset_div2 = %d\n", p->slice_beta_offset_div2);
 
-    if (p->slice_type == 0 || p->slice_type == 1) {
-        va_TraceMsg(idx, "\tRefPicList0 =");
-        for (i = 0; i < p->num_ref_idx_l0_active_minus1 + 1; i++) {
-            va_TraceMsg(idx, "%d-%d-0x%08x-%d\n", p->RefPicList0[i].TopFieldOrderCnt, p->RefPicList0[i].BottomFieldOrderCnt, p->RefPicList0[i].picture_id, p->RefPicList0[i].frame_idx);
-        }
-        if (p->slice_type == 1) {
-            va_TraceMsg(idx, "\tRefPicList1 =");
-            for (i = 0; i < p->num_ref_idx_l1_active_minus1 + 1; i++)
-            {
-                va_TraceMsg(idx, "%d-%d-0x%08x-%d\n", p->RefPicList1[i].TopFieldOrderCnt, p->RefPicList1[i].BottomFieldOrderCnt, p->RefPicList1[i].picture_id, p->RefPicList1[i].frame_idx);
-            }
-        }
+    va_TraceMsg(trace_ctx, "\tRefPicList0 (TopFieldOrderCnt-BottomFieldOrderCnt-picture_id-frame_idx-flags):\n");
+
+    
+    
+    for (i = 0; i < 32; i++) {
+        if ((p->RefPicList0[i].picture_id != VA_INVALID_SURFACE) &&
+            ((p->RefPicList0[i].flags & VA_PICTURE_H264_INVALID) == 0))
+            va_TraceMsg(trace_ctx, "\t\t%08d-%08d-0x%08x-%08d-0x%08x\n",
+                        p->RefPicList0[i].TopFieldOrderCnt,
+                        p->RefPicList0[i].BottomFieldOrderCnt,
+                        p->RefPicList0[i].picture_id,
+                        p->RefPicList0[i].frame_idx,
+                        p->RefPicList0[i].flags);
+        else
+            break;
     }
-
-    va_TraceMsg(idx, "\tluma_log2_weight_denom = %d\n", p->luma_log2_weight_denom);
-    va_TraceMsg(idx, "\tchroma_log2_weight_denom = %d\n", p->chroma_log2_weight_denom);
-    va_TraceMsg(idx, "\tluma_weight_l0_flag = %d\n", p->luma_weight_l0_flag);
+    
+    va_TraceMsg(trace_ctx, "\tRefPicList1 (TopFieldOrderCnt-BottomFieldOrderCnt-picture_id-frame_idx-flags):\n");
+    for (i = 0; i < 32; i++) {
+        if ((p->RefPicList1[i].picture_id != VA_INVALID_SURFACE) &&
+            ((p->RefPicList1[i].flags & VA_PICTURE_H264_INVALID) == 0))
+            va_TraceMsg(trace_ctx, "\t\t%08d-%08d-0x%08x-%08d-0x%08d\n",
+                        p->RefPicList1[i].TopFieldOrderCnt,
+                        p->RefPicList1[i].BottomFieldOrderCnt,
+                        p->RefPicList1[i].picture_id,
+                        p->RefPicList1[i].frame_idx,
+                        p->RefPicList1[i].flags
+                        );
+        else
+            break;
+    }
+    
+    va_TraceMsg(trace_ctx, "\tluma_log2_weight_denom = %d\n", p->luma_log2_weight_denom);
+    va_TraceMsg(trace_ctx, "\tchroma_log2_weight_denom = %d\n", p->chroma_log2_weight_denom);
+    va_TraceMsg(trace_ctx, "\tluma_weight_l0_flag = %d\n", p->luma_weight_l0_flag);
     if (p->luma_weight_l0_flag) {
-        for (i = 0; i <=  p->num_ref_idx_l0_active_minus1; i++) {
-            va_TraceMsg(idx, "\t%d ", p->luma_weight_l0[i]);
-            va_TraceMsg(idx, "\t%d ", p->luma_offset_l0[i]);
+        for (i = 0; (i <= p->num_ref_idx_l0_active_minus1) && (i<32); i++) {
+            va_TraceMsg(trace_ctx, "\t\t%d\t%d\n",
+                        p->luma_weight_l0[i],
+                        p->luma_offset_l0[i]);
         }
     }
 
-    va_TraceMsg(idx, "\tchroma_weight_l0_flag = %d\n", p->chroma_weight_l0_flag);
+    va_TraceMsg(trace_ctx, "\tchroma_weight_l0_flag = %d\n", p->chroma_weight_l0_flag);
     if (p->chroma_weight_l0_flag) {
-        for (i = 0; i <= p->num_ref_idx_l0_active_minus1; i++) {
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_weight_l0[i][0]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_offset_l0[i][0]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_weight_l0[i][1]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_offset_l0[i][1]);
+        for (i = 0; (i <= p->num_ref_idx_l0_active_minus1) && (i<32); i++) {
+            va_TraceMsg(trace_ctx, "\t\t%d\t%d\t%d\t%d\n",
+                        p->chroma_weight_l0[i][0],
+                        p->chroma_offset_l0[i][0],
+                        p->chroma_weight_l0[i][1],
+                        p->chroma_offset_l0[i][1]);
         }
     }
 
-    va_TraceMsg(idx, "\tluma_weight_l1_flag = %d\n", p->luma_weight_l1_flag);
+    va_TraceMsg(trace_ctx, "\tluma_weight_l1_flag = %d\n", p->luma_weight_l1_flag);
     if (p->luma_weight_l1_flag) {
-        for (i = 0; i <=  p->num_ref_idx_l1_active_minus1; i++) {
-            va_TraceMsg(idx, "\t\t%d ", p->luma_weight_l1[i]);
-            va_TraceMsg(idx, "\t\t%d ", p->luma_offset_l1[i]);
+        for (i = 0; (i <= p->num_ref_idx_l1_active_minus1) && (i<32); i++) {
+            va_TraceMsg(trace_ctx, "\t\t%d\t\t%d\n",
+                        p->luma_weight_l1[i],
+                        p->luma_offset_l1[i]);
         }
     }
 
-    va_TraceMsg(idx, "\tchroma_weight_l1_flag = %d\n", p->chroma_weight_l1_flag);
-    if (p->chroma_weight_l1_flag) {
-        for (i = 0; i <= p->num_ref_idx_l1_active_minus1; i++) {
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_weight_l1[i][0]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_offset_l1[i][0]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_weight_l1[i][1]);
-            va_TraceMsg(idx, "\t\t%d ", p->chroma_offset_l1[i][1]);
+    va_TraceMsg(trace_ctx, "\tchroma_weight_l1_flag = %d\n", p->chroma_weight_l1_flag);
+    if (p->chroma_weight_l1_flag && p->num_ref_idx_l1_active_minus1 < 32) {
+        for (i = 0; (i <= p->num_ref_idx_l1_active_minus1) && (i<32); i++) {
+            va_TraceMsg(trace_ctx, "\t\t%d\t%d\t%d\t%d\n",
+                        p->chroma_weight_l1[i][0],
+                        p->chroma_offset_l1[i][0],
+                        p->chroma_weight_l1[i][1],
+                        p->chroma_offset_l1[i][1]);
         }
-        va_TraceMsg(idx, "\n");
     }
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 
-    va_TraceMsg(idx, "\tcabac_init_idc = %d\n", p->cabac_init_idc);
-    va_TraceMsg(idx, "\tslice_qp_delta = %d\n", p->slice_qp_delta);
-    va_TraceMsg(idx, "\tdisable_deblocking_filter_idc = %d\n", p->disable_deblocking_filter_idc);
-    va_TraceMsg(idx, "\tslice_alpha_c0_offset_div2 = %d\n", p->slice_alpha_c0_offset_div2);
-    va_TraceMsg(idx, "\tslice_beta_offset_div2 = %d\n", p->slice_beta_offset_div2);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "\tcabac_init_idc = %d\n", p->cabac_init_idc);
+    va_TraceMsg(trace_ctx, "\tslice_qp_delta = %d\n", p->slice_qp_delta);
+    va_TraceMsg(trace_ctx, "\tdisable_deblocking_filter_idc = %d\n", p->disable_deblocking_filter_idc);
+    va_TraceMsg(trace_ctx, "\tslice_alpha_c0_offset_div2 = %d\n", p->slice_alpha_c0_offset_div2);
+    va_TraceMsg(trace_ctx, "\tslice_beta_offset_div2 = %d\n", p->slice_beta_offset_div2);
+    va_TraceMsg(trace_ctx, NULL);
+
+    return;
+}
+
+
+static void va_TraceVAEncPackedHeaderParameterBufferType(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    VAEncPackedHeaderParameterBuffer* p = (VAEncPackedHeaderParameterBuffer*)data;
+    DPY2TRACECTX(dpy);
+    int i;
+
+    if (!p)
+        return;
+    va_TraceMsg(trace_ctx, "\t--VAEncPackedHeaderParameterBuffer\n");
+    va_TraceMsg(trace_ctx, "\ttype = 0x%08x\n", p->type);
+    va_TraceMsg(trace_ctx, "\tbit_length = %d\n", p->bit_length);
+    va_TraceMsg(trace_ctx, "\thas_emulation_bytes = %d\n", p->has_emulation_bytes);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
@@ -1436,14 +1722,15 @@
     void *data)
 {
     VAEncMiscParameterBuffer* tmp = (VAEncMiscParameterBuffer*)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
+    uint32_t i;
     
     switch (tmp->type) {
     case VAEncMiscParameterTypeFrameRate:
     {
         VAEncMiscParameterFrameRate *p = (VAEncMiscParameterFrameRate *)tmp->data;
-        va_TraceMsg(idx, "VAEncMiscParameterFrameRate\n");
-        va_TraceMsg(idx, "\tframerate = %d\n", p->framerate);
+        va_TraceMsg(trace_ctx, "\t--VAEncMiscParameterFrameRate\n");
+        va_TraceMsg(trace_ctx, "\tframerate = %d\n", p->framerate);
         
         break;
     }
@@ -1451,45 +1738,69 @@
     {
         VAEncMiscParameterRateControl *p = (VAEncMiscParameterRateControl *)tmp->data;
 
-        va_TraceMsg(idx, "VAEncMiscParameterRateControl\n");
-        va_TraceMsg(idx, "\tbits_per_second = %d\n", p->bits_per_second);
-        va_TraceMsg(idx, "\twindow_size = %d\n", p->window_size);
-        va_TraceMsg(idx, "\tinitial_qp = %d\n", p->initial_qp);
-        va_TraceMsg(idx, "\tmin_qp = %d\n", p->min_qp);
+        va_TraceMsg(trace_ctx, "\t--VAEncMiscParameterRateControl\n");
+        va_TraceMsg(trace_ctx, "\tbits_per_second = %d\n", p->bits_per_second);
+        va_TraceMsg(trace_ctx, "\ttarget_percentage = %d\n", p->target_percentage);
+        va_TraceMsg(trace_ctx, "\twindow_size = %d\n", p->window_size);
+        va_TraceMsg(trace_ctx, "\tinitial_qp = %d\n", p->initial_qp);
+        va_TraceMsg(trace_ctx, "\tmin_qp = %d\n", p->min_qp);
+        va_TraceMsg(trace_ctx, "\tbasic_unit_size = %d\n", p->basic_unit_size);
+        va_TraceMsg(trace_ctx, "\trc_flags.reset = %d \n", p->rc_flags.bits.reset);
+        va_TraceMsg(trace_ctx, "\trc_flags.disable_frame_skip = %d\n", p->rc_flags.bits.disable_frame_skip);
+        va_TraceMsg(trace_ctx, "\trc_flags.disable_bit_stuffing = %d\n", p->rc_flags.bits.disable_bit_stuffing);
         break;
     }
     case VAEncMiscParameterTypeMaxSliceSize:
     {
         VAEncMiscParameterMaxSliceSize *p = (VAEncMiscParameterMaxSliceSize *)tmp->data;
         
-        va_TraceMsg(idx, "VAEncMiscParameterTypeMaxSliceSize\n");
-        va_TraceMsg(idx, "\tmax_slice_size = %d\n", p->max_slice_size);
+        va_TraceMsg(trace_ctx, "\t--VAEncMiscParameterTypeMaxSliceSize\n");
+        va_TraceMsg(trace_ctx, "\tmax_slice_size = %d\n", p->max_slice_size);
         break;
     }
     case VAEncMiscParameterTypeAIR:
     {
         VAEncMiscParameterAIR *p = (VAEncMiscParameterAIR *)tmp->data;
         
-        va_TraceMsg(idx, "VAEncMiscParameterAIR\n");
-        va_TraceMsg(idx, "\tair_num_mbs = %d\n", p->air_num_mbs);
-        va_TraceMsg(idx, "\tair_threshold = %d\n", p->air_threshold);
-        va_TraceMsg(idx, "\tair_auto = %d\n", p->air_auto);
+        va_TraceMsg(trace_ctx, "\t--VAEncMiscParameterAIR\n");
+        va_TraceMsg(trace_ctx, "\tair_num_mbs = %d\n", p->air_num_mbs);
+        va_TraceMsg(trace_ctx, "\tair_threshold = %d\n", p->air_threshold);
+        va_TraceMsg(trace_ctx, "\tair_auto = %d\n", p->air_auto);
         break;
     }
     case VAEncMiscParameterTypeHRD:
     {
         VAEncMiscParameterHRD *p = (VAEncMiscParameterHRD *)tmp->data;
 
-        va_TraceMsg(idx, "VAEncMiscParameterHRD\n");
-        va_TraceMsg(idx, "\tinitial_buffer_fullness = %d\n", p->initial_buffer_fullness);
-        va_TraceMsg(idx, "\tbuffer_size = %d\n", p->buffer_size);
+        va_TraceMsg(trace_ctx, "\t--VAEncMiscParameterHRD\n");
+        va_TraceMsg(trace_ctx, "\tinitial_buffer_fullness = %d\n", p->initial_buffer_fullness);
+        va_TraceMsg(trace_ctx, "\tbuffer_size = %d\n", p->buffer_size);
+        break;
+    }
+    case VAEncMiscParameterTypeMaxFrameSize:
+    {
+        VAEncMiscParameterBufferMaxFrameSize *p = (VAEncMiscParameterBufferMaxFrameSize *)tmp->data;
+
+        va_TraceMsg(trace_ctx, "\t--VAEncMiscParameterTypeMaxFrameSize\n");
+        va_TraceMsg(trace_ctx, "\tmax_frame_size = %d\n", p->max_frame_size);
+        break;
+    }
+    case VAEncMiscParameterTypeTemporalLayerStructure:
+    {
+        VAEncMiscParameterTemporalLayerStructure *p = (VAEncMiscParameterTemporalLayerStructure *)tmp->data;
+        va_TraceMsg(trace_ctx,"\t--VAEncMiscParameterTypeTemporalLayerStructure\n");
+        va_TraceMsg(trace_ctx,"\tnumber_of_layers = %d\n", p->number_of_layers);
+        va_TraceMsg(trace_ctx,"\tperiodicity = %d\n", p->periodicity);
+        for(i=0;i<p->periodicity;i++)
+                va_TraceMsg(trace_ctx,"\tlayer_id[%d] = %d\n", i, p->layer_id[i]);
         break;
     }
     default:
-        va_TraceMsg(idx, "invalid VAEncMiscParameterBuffer type = %d\n", tmp->type);
+        va_TraceMsg(trace_ctx, "Unknown VAEncMiscParameterBuffer(type = %d):\n", tmp->type);
+        va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, data);
         break;
     }
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
@@ -1506,144 +1817,411 @@
 )
 {
     VAPictureParameterBufferVC1* p = (VAPictureParameterBufferVC1*)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx, "\t--VAPictureParameterBufferVC1\n");
+    va_TraceMsg(trace_ctx, "\t    context = %d, buffer = %d, type = %d, size = %d, num_elements = %d\n",
+                context, buffer, type, size, num_elements);
+    va_TraceMsg(trace_ctx, "\tforward_reference_picture = 0x%08x\n", p->forward_reference_picture);
+    va_TraceMsg(trace_ctx, "\tbackward_reference_picture = 0x%08x\n", p->backward_reference_picture);
+    va_TraceMsg(trace_ctx, "\tinloop_decoded_picture = 0x%08x\n", p->inloop_decoded_picture);
     
-    va_TraceMsg(idx, "VAPictureParameterBufferVC1\n");
-    
-    va_TraceMsg(idx, "\tforward_reference_picture = 0x%08x\n", p->forward_reference_picture);
-    va_TraceMsg(idx, "\tbackward_reference_picture = 0x%08x\n", p->backward_reference_picture);
-    va_TraceMsg(idx, "\tinloop_decoded_picture = 0x%08x\n", p->inloop_decoded_picture);
-    
-    va_TraceMsg(idx, "\tpulldown = %d\n", p->sequence_fields.bits.pulldown);
-    va_TraceMsg(idx, "\tinterlace = %d\n", p->sequence_fields.bits.interlace);
-    va_TraceMsg(idx, "\ttfcntrflag = %d\n", p->sequence_fields.bits.tfcntrflag);
-    va_TraceMsg(idx, "\tfinterpflag = %d\n", p->sequence_fields.bits.finterpflag);
-    va_TraceMsg(idx, "\tpsf = %d\n", p->sequence_fields.bits.psf);
-    va_TraceMsg(idx, "\tmultires = %d\n", p->sequence_fields.bits.multires);
-    va_TraceMsg(idx, "\toverlap = %d\n", p->sequence_fields.bits.overlap);
-    va_TraceMsg(idx, "\tsyncmarker = %d\n", p->sequence_fields.bits.syncmarker);
-    va_TraceMsg(idx, "\trangered = %d\n", p->sequence_fields.bits.rangered);
-    va_TraceMsg(idx, "\tmax_b_frames = %d\n", p->sequence_fields.bits.max_b_frames);
-    va_TraceMsg(idx, "\tprofile = %d\n", p->sequence_fields.bits.profile);
-    va_TraceMsg(idx, "\tcoded_width = %d\n", p->coded_width);
-    va_TraceMsg(idx, "\tcoded_height = %d\n", p->coded_height);
-    va_TraceMsg(idx, "\tclosed_entry = %d\n", p->entrypoint_fields.bits.closed_entry);
-    va_TraceMsg(idx, "\tbroken_link = %d\n", p->entrypoint_fields.bits.broken_link);
-    va_TraceMsg(idx, "\tclosed_entry = %d\n", p->entrypoint_fields.bits.closed_entry);
-    va_TraceMsg(idx, "\tpanscan_flag = %d\n", p->entrypoint_fields.bits.panscan_flag);
-    va_TraceMsg(idx, "\tloopfilter = %d\n", p->entrypoint_fields.bits.loopfilter);
-    va_TraceMsg(idx, "\tconditional_overlap_flag = %d\n", p->conditional_overlap_flag);
-    va_TraceMsg(idx, "\tfast_uvmc_flag = %d\n", p->fast_uvmc_flag);
-    va_TraceMsg(idx, "\trange_mapping_luma_flag = %d\n", p->range_mapping_fields.bits.luma_flag);
-    va_TraceMsg(idx, "\trange_mapping_luma = %d\n", p->range_mapping_fields.bits.luma);
-    va_TraceMsg(idx, "\trange_mapping_chroma_flag = %d\n", p->range_mapping_fields.bits.chroma_flag);
-    va_TraceMsg(idx, "\trange_mapping_chroma = %d\n", p->range_mapping_fields.bits.chroma);
-    va_TraceMsg(idx, "\tb_picture_fraction = %d\n", p->b_picture_fraction);
-    va_TraceMsg(idx, "\tcbp_table = %d\n", p->cbp_table);
-    va_TraceMsg(idx, "\tmb_mode_table = %d\n", p->mb_mode_table);
-    va_TraceMsg(idx, "\trange_reduction_frame = %d\n", p->range_reduction_frame);
-    va_TraceMsg(idx, "\trounding_control = %d\n", p->rounding_control);
-    va_TraceMsg(idx, "\tpost_processing = %d\n", p->post_processing);
-    va_TraceMsg(idx, "\tpicture_resolution_index = %d\n", p->picture_resolution_index);
-    va_TraceMsg(idx, "\tluma_scale = %d\n", p->luma_scale);
-    va_TraceMsg(idx, "\tluma_shift = %d\n", p->luma_shift);
-    va_TraceMsg(idx, "\tpicture_type = %d\n", p->picture_fields.bits.picture_type);
-    va_TraceMsg(idx, "\tframe_coding_mode = %d\n", p->picture_fields.bits.frame_coding_mode);
-    va_TraceMsg(idx, "\ttop_field_first = %d\n", p->picture_fields.bits.top_field_first);
-    va_TraceMsg(idx, "\tis_first_field = %d\n", p->picture_fields.bits.is_first_field);
-    va_TraceMsg(idx, "\tintensity_compensation = %d\n", p->picture_fields.bits.intensity_compensation);
-    va_TraceMsg(idx, "\tmv_type_mb = %d\n", p->raw_coding.flags.mv_type_mb);
-    va_TraceMsg(idx, "\tdirect_mb = %d\n", p->raw_coding.flags.direct_mb);
-    va_TraceMsg(idx, "\tskip_mb = %d\n", p->raw_coding.flags.skip_mb);
-    va_TraceMsg(idx, "\tfield_tx = %d\n", p->raw_coding.flags.field_tx);
-    va_TraceMsg(idx, "\tforward_mb = %d\n", p->raw_coding.flags.forward_mb);
-    va_TraceMsg(idx, "\tac_pred = %d\n", p->raw_coding.flags.ac_pred);
-    va_TraceMsg(idx, "\toverflags = %d\n", p->raw_coding.flags.overflags);
-    va_TraceMsg(idx, "\tbp_mv_type_mb = %d\n", p->bitplane_present.flags.bp_mv_type_mb);
-    va_TraceMsg(idx, "\tbp_direct_mb = %d\n", p->bitplane_present.flags.bp_direct_mb);
-    va_TraceMsg(idx, "\tbp_skip_mb = %d\n", p->bitplane_present.flags.bp_skip_mb);
-    va_TraceMsg(idx, "\tbp_field_tx = %d\n", p->bitplane_present.flags.bp_field_tx);
-    va_TraceMsg(idx, "\tbp_forward_mb = %d\n", p->bitplane_present.flags.bp_forward_mb);
-    va_TraceMsg(idx, "\tbp_ac_pred = %d\n", p->bitplane_present.flags.bp_ac_pred);
-    va_TraceMsg(idx, "\tbp_overflags = %d\n", p->bitplane_present.flags.bp_overflags);
-    va_TraceMsg(idx, "\treference_distance_flag = %d\n", p->reference_fields.bits.reference_distance_flag);
-    va_TraceMsg(idx, "\treference_distance = %d\n", p->reference_fields.bits.reference_distance);
-    va_TraceMsg(idx, "\tnum_reference_pictures = %d\n", p->reference_fields.bits.num_reference_pictures);
-    va_TraceMsg(idx, "\treference_field_pic_indicator = %d\n", p->reference_fields.bits.reference_field_pic_indicator);
-    va_TraceMsg(idx, "\tmv_mode = %d\n", p->mv_fields.bits.mv_mode);
-    va_TraceMsg(idx, "\tmv_mode2 = %d\n", p->mv_fields.bits.mv_mode2);
-    va_TraceMsg(idx, "\tmv_table = %d\n", p->mv_fields.bits.mv_table);
-    va_TraceMsg(idx, "\ttwo_mv_block_pattern_table = %d\n", p->mv_fields.bits.two_mv_block_pattern_table);
-    va_TraceMsg(idx, "\tfour_mv_switch = %d\n", p->mv_fields.bits.four_mv_switch);
-    va_TraceMsg(idx, "\tfour_mv_block_pattern_table = %d\n", p->mv_fields.bits.four_mv_block_pattern_table);
-    va_TraceMsg(idx, "\textended_mv_flag = %d\n", p->mv_fields.bits.extended_mv_flag);
-    va_TraceMsg(idx, "\textended_mv_range = %d\n", p->mv_fields.bits.extended_mv_range);
-    va_TraceMsg(idx, "\textended_dmv_flag = %d\n", p->mv_fields.bits.extended_dmv_flag);
-    va_TraceMsg(idx, "\textended_dmv_range = %d\n", p->mv_fields.bits.extended_dmv_range);
-    va_TraceMsg(idx, "\tdquant = %d\n", p->pic_quantizer_fields.bits.dquant);
-    va_TraceMsg(idx, "\tquantizer = %d\n", p->pic_quantizer_fields.bits.quantizer);
-    va_TraceMsg(idx, "\thalf_qp = %d\n", p->pic_quantizer_fields.bits.half_qp);
-    va_TraceMsg(idx, "\tpic_quantizer_scale = %d\n", p->pic_quantizer_fields.bits.pic_quantizer_scale);
-    va_TraceMsg(idx, "\tpic_quantizer_type = %d\n", p->pic_quantizer_fields.bits.pic_quantizer_type);
-    va_TraceMsg(idx, "\tdq_frame = %d\n", p->pic_quantizer_fields.bits.dq_frame);
-    va_TraceMsg(idx, "\tdq_profile = %d\n", p->pic_quantizer_fields.bits.dq_profile);
-    va_TraceMsg(idx, "\tdq_sb_edge = %d\n", p->pic_quantizer_fields.bits.dq_sb_edge);
-    va_TraceMsg(idx, "\tdq_db_edge = %d\n", p->pic_quantizer_fields.bits.dq_db_edge);
-    va_TraceMsg(idx, "\tdq_binary_level = %d\n", p->pic_quantizer_fields.bits.dq_binary_level);
-    va_TraceMsg(idx, "\talt_pic_quantizer = %d\n", p->pic_quantizer_fields.bits.alt_pic_quantizer);
-    va_TraceMsg(idx, "\tvariable_sized_transform_flag = %d\n", p->transform_fields.bits.variable_sized_transform_flag);
-    va_TraceMsg(idx, "\tmb_level_transform_type_flag = %d\n", p->transform_fields.bits.mb_level_transform_type_flag);
-    va_TraceMsg(idx, "\tframe_level_transform_type = %d\n", p->transform_fields.bits.frame_level_transform_type);
-    va_TraceMsg(idx, "\ttransform_ac_codingset_idx1 = %d\n", p->transform_fields.bits.transform_ac_codingset_idx1);
-    va_TraceMsg(idx, "\ttransform_ac_codingset_idx2 = %d\n", p->transform_fields.bits.transform_ac_codingset_idx2);
-    va_TraceMsg(idx, "\tintra_transform_dc_table = %d\n", p->transform_fields.bits.intra_transform_dc_table);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "\tpulldown = %d\n", p->sequence_fields.bits.pulldown);
+    va_TraceMsg(trace_ctx, "\tinterlace = %d\n", p->sequence_fields.bits.interlace);
+    va_TraceMsg(trace_ctx, "\ttfcntrflag = %d\n", p->sequence_fields.bits.tfcntrflag);
+    va_TraceMsg(trace_ctx, "\tfinterpflag = %d\n", p->sequence_fields.bits.finterpflag);
+    va_TraceMsg(trace_ctx, "\tpsf = %d\n", p->sequence_fields.bits.psf);
+    va_TraceMsg(trace_ctx, "\tmultires = %d\n", p->sequence_fields.bits.multires);
+    va_TraceMsg(trace_ctx, "\toverlap = %d\n", p->sequence_fields.bits.overlap);
+    va_TraceMsg(trace_ctx, "\tsyncmarker = %d\n", p->sequence_fields.bits.syncmarker);
+    va_TraceMsg(trace_ctx, "\trangered = %d\n", p->sequence_fields.bits.rangered);
+    va_TraceMsg(trace_ctx, "\tmax_b_frames = %d\n", p->sequence_fields.bits.max_b_frames);
+    va_TraceMsg(trace_ctx, "\tprofile = %d\n", p->sequence_fields.bits.profile);
+    va_TraceMsg(trace_ctx, "\tcoded_width = %d\n", p->coded_width);
+    va_TraceMsg(trace_ctx, "\tcoded_height = %d\n", p->coded_height);
+    va_TraceMsg(trace_ctx, "\tclosed_entry = %d\n", p->entrypoint_fields.bits.closed_entry);
+    va_TraceMsg(trace_ctx, "\tbroken_link = %d\n", p->entrypoint_fields.bits.broken_link);
+    va_TraceMsg(trace_ctx, "\tclosed_entry = %d\n", p->entrypoint_fields.bits.closed_entry);
+    va_TraceMsg(trace_ctx, "\tpanscan_flag = %d\n", p->entrypoint_fields.bits.panscan_flag);
+    va_TraceMsg(trace_ctx, "\tloopfilter = %d\n", p->entrypoint_fields.bits.loopfilter);
+    va_TraceMsg(trace_ctx, "\tconditional_overlap_flag = %d\n", p->conditional_overlap_flag);
+    va_TraceMsg(trace_ctx, "\tfast_uvmc_flag = %d\n", p->fast_uvmc_flag);
+    va_TraceMsg(trace_ctx, "\trange_mapping_luma_flag = %d\n", p->range_mapping_fields.bits.luma_flag);
+    va_TraceMsg(trace_ctx, "\trange_mapping_luma = %d\n", p->range_mapping_fields.bits.luma);
+    va_TraceMsg(trace_ctx, "\trange_mapping_chroma_flag = %d\n", p->range_mapping_fields.bits.chroma_flag);
+    va_TraceMsg(trace_ctx, "\trange_mapping_chroma = %d\n", p->range_mapping_fields.bits.chroma);
+    va_TraceMsg(trace_ctx, "\tb_picture_fraction = %d\n", p->b_picture_fraction);
+    va_TraceMsg(trace_ctx, "\tcbp_table = %d\n", p->cbp_table);
+    va_TraceMsg(trace_ctx, "\tmb_mode_table = %d\n", p->mb_mode_table);
+    va_TraceMsg(trace_ctx, "\trange_reduction_frame = %d\n", p->range_reduction_frame);
+    va_TraceMsg(trace_ctx, "\trounding_control = %d\n", p->rounding_control);
+    va_TraceMsg(trace_ctx, "\tpost_processing = %d\n", p->post_processing);
+    va_TraceMsg(trace_ctx, "\tpicture_resolution_index = %d\n", p->picture_resolution_index);
+    va_TraceMsg(trace_ctx, "\tluma_scale = %d\n", p->luma_scale);
+    va_TraceMsg(trace_ctx, "\tluma_shift = %d\n", p->luma_shift);
+    va_TraceMsg(trace_ctx, "\tpicture_type = %d\n", p->picture_fields.bits.picture_type);
+    va_TraceMsg(trace_ctx, "\tframe_coding_mode = %d\n", p->picture_fields.bits.frame_coding_mode);
+    va_TraceMsg(trace_ctx, "\ttop_field_first = %d\n", p->picture_fields.bits.top_field_first);
+    va_TraceMsg(trace_ctx, "\tis_first_field = %d\n", p->picture_fields.bits.is_first_field);
+    va_TraceMsg(trace_ctx, "\tintensity_compensation = %d\n", p->picture_fields.bits.intensity_compensation);
+    va_TraceMsg(trace_ctx, "\tmv_type_mb = %d\n", p->raw_coding.flags.mv_type_mb);
+    va_TraceMsg(trace_ctx, "\tdirect_mb = %d\n", p->raw_coding.flags.direct_mb);
+    va_TraceMsg(trace_ctx, "\tskip_mb = %d\n", p->raw_coding.flags.skip_mb);
+    va_TraceMsg(trace_ctx, "\tfield_tx = %d\n", p->raw_coding.flags.field_tx);
+    va_TraceMsg(trace_ctx, "\tforward_mb = %d\n", p->raw_coding.flags.forward_mb);
+    va_TraceMsg(trace_ctx, "\tac_pred = %d\n", p->raw_coding.flags.ac_pred);
+    va_TraceMsg(trace_ctx, "\toverflags = %d\n", p->raw_coding.flags.overflags);
+    va_TraceMsg(trace_ctx, "\tbp_mv_type_mb = %d\n", p->bitplane_present.flags.bp_mv_type_mb);
+    va_TraceMsg(trace_ctx, "\tbp_direct_mb = %d\n", p->bitplane_present.flags.bp_direct_mb);
+    va_TraceMsg(trace_ctx, "\tbp_skip_mb = %d\n", p->bitplane_present.flags.bp_skip_mb);
+    va_TraceMsg(trace_ctx, "\tbp_field_tx = %d\n", p->bitplane_present.flags.bp_field_tx);
+    va_TraceMsg(trace_ctx, "\tbp_forward_mb = %d\n", p->bitplane_present.flags.bp_forward_mb);
+    va_TraceMsg(trace_ctx, "\tbp_ac_pred = %d\n", p->bitplane_present.flags.bp_ac_pred);
+    va_TraceMsg(trace_ctx, "\tbp_overflags = %d\n", p->bitplane_present.flags.bp_overflags);
+    va_TraceMsg(trace_ctx, "\treference_distance_flag = %d\n", p->reference_fields.bits.reference_distance_flag);
+    va_TraceMsg(trace_ctx, "\treference_distance = %d\n", p->reference_fields.bits.reference_distance);
+    va_TraceMsg(trace_ctx, "\tnum_reference_pictures = %d\n", p->reference_fields.bits.num_reference_pictures);
+    va_TraceMsg(trace_ctx, "\treference_field_pic_indicator = %d\n", p->reference_fields.bits.reference_field_pic_indicator);
+    va_TraceMsg(trace_ctx, "\tmv_mode = %d\n", p->mv_fields.bits.mv_mode);
+    va_TraceMsg(trace_ctx, "\tmv_mode2 = %d\n", p->mv_fields.bits.mv_mode2);
+    va_TraceMsg(trace_ctx, "\tmv_table = %d\n", p->mv_fields.bits.mv_table);
+    va_TraceMsg(trace_ctx, "\ttwo_mv_block_pattern_table = %d\n", p->mv_fields.bits.two_mv_block_pattern_table);
+    va_TraceMsg(trace_ctx, "\tfour_mv_switch = %d\n", p->mv_fields.bits.four_mv_switch);
+    va_TraceMsg(trace_ctx, "\tfour_mv_block_pattern_table = %d\n", p->mv_fields.bits.four_mv_block_pattern_table);
+    va_TraceMsg(trace_ctx, "\textended_mv_flag = %d\n", p->mv_fields.bits.extended_mv_flag);
+    va_TraceMsg(trace_ctx, "\textended_mv_range = %d\n", p->mv_fields.bits.extended_mv_range);
+    va_TraceMsg(trace_ctx, "\textended_dmv_flag = %d\n", p->mv_fields.bits.extended_dmv_flag);
+    va_TraceMsg(trace_ctx, "\textended_dmv_range = %d\n", p->mv_fields.bits.extended_dmv_range);
+    va_TraceMsg(trace_ctx, "\tdquant = %d\n", p->pic_quantizer_fields.bits.dquant);
+    va_TraceMsg(trace_ctx, "\tquantizer = %d\n", p->pic_quantizer_fields.bits.quantizer);
+    va_TraceMsg(trace_ctx, "\thalf_qp = %d\n", p->pic_quantizer_fields.bits.half_qp);
+    va_TraceMsg(trace_ctx, "\tpic_quantizer_scale = %d\n", p->pic_quantizer_fields.bits.pic_quantizer_scale);
+    va_TraceMsg(trace_ctx, "\tpic_quantizer_type = %d\n", p->pic_quantizer_fields.bits.pic_quantizer_type);
+    va_TraceMsg(trace_ctx, "\tdq_frame = %d\n", p->pic_quantizer_fields.bits.dq_frame);
+    va_TraceMsg(trace_ctx, "\tdq_profile = %d\n", p->pic_quantizer_fields.bits.dq_profile);
+    va_TraceMsg(trace_ctx, "\tdq_sb_edge = %d\n", p->pic_quantizer_fields.bits.dq_sb_edge);
+    va_TraceMsg(trace_ctx, "\tdq_db_edge = %d\n", p->pic_quantizer_fields.bits.dq_db_edge);
+    va_TraceMsg(trace_ctx, "\tdq_binary_level = %d\n", p->pic_quantizer_fields.bits.dq_binary_level);
+    va_TraceMsg(trace_ctx, "\talt_pic_quantizer = %d\n", p->pic_quantizer_fields.bits.alt_pic_quantizer);
+    va_TraceMsg(trace_ctx, "\tvariable_sized_transform_flag = %d\n", p->transform_fields.bits.variable_sized_transform_flag);
+    va_TraceMsg(trace_ctx, "\tmb_level_transform_type_flag = %d\n", p->transform_fields.bits.mb_level_transform_type_flag);
+    va_TraceMsg(trace_ctx, "\tframe_level_transform_type = %d\n", p->transform_fields.bits.frame_level_transform_type);
+    va_TraceMsg(trace_ctx, "\ttransform_ac_codingset_idx1 = %d\n", p->transform_fields.bits.transform_ac_codingset_idx1);
+    va_TraceMsg(trace_ctx, "\ttransform_ac_codingset_idx2 = %d\n", p->transform_fields.bits.transform_ac_codingset_idx2);
+    va_TraceMsg(trace_ctx, "\tintra_transform_dc_table = %d\n", p->transform_fields.bits.intra_transform_dc_table);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 static void va_TraceVASliceParameterBufferVC1(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void* data
 )
 {
     VASliceParameterBufferVC1 *p = (VASliceParameterBufferVC1*)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
-    trace_context[idx].trace_slice_no++;
-    trace_context[idx].trace_slice_size = p->slice_data_size;
+    trace_ctx->trace_slice_no++;
+    trace_ctx->trace_slice_size = p->slice_data_size;
 
-    va_TraceMsg(idx, "VASliceParameterBufferVC1\n");
-    va_TraceMsg(idx, "\tslice_data_size = %d\n", p->slice_data_size);
-    va_TraceMsg(idx, "\tslice_data_offset = %d\n", p->slice_data_offset);
-    va_TraceMsg(idx, "\tslice_data_flag = %d\n", p->slice_data_flag);
-    va_TraceMsg(idx, "\tmacroblock_offset = %d\n", p->macroblock_offset);
-    va_TraceMsg(idx, "\tslice_vertical_position = %d\n", p->slice_vertical_position);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "\t--VASliceParameterBufferVC1\n");
+    va_TraceMsg(trace_ctx, "\tslice_data_size = %d\n", p->slice_data_size);
+    va_TraceMsg(trace_ctx, "\tslice_data_offset = %d\n", p->slice_data_offset);
+    va_TraceMsg(trace_ctx, "\tslice_data_flag = %d\n", p->slice_data_flag);
+    va_TraceMsg(trace_ctx, "\tmacroblock_offset = %d\n", p->macroblock_offset);
+    va_TraceMsg(trace_ctx, "\tslice_vertical_position = %d\n", p->slice_vertical_position);
+    va_TraceMsg(trace_ctx, NULL);
+}
+
+static void va_TraceVAEncSequenceParameterBufferVP8(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    VAEncSequenceParameterBufferVP8 *p = (VAEncSequenceParameterBufferVP8 *)data;
+    DPY2TRACECTX(dpy);
+    int i;
+
+    va_TraceMsg(trace_ctx, "\t--VAEncSequenceParameterBufferVP8\n");
+
+    va_TraceMsg(trace_ctx, "\tbits_per_second = %d\n", p->bits_per_second);
+    va_TraceMsg(trace_ctx, "\terror_resilient = %d\n", p->error_resilient);
+    va_TraceMsg(trace_ctx, "\tframe_height = %d\n", p->frame_height);
+    va_TraceMsg(trace_ctx, "\tframe_width = %d\n", p->frame_width);
+    va_TraceMsg(trace_ctx, "\tframe_height_scale = %d\n", p->frame_height_scale);
+    va_TraceMsg(trace_ctx, "\tframe_width_scale = %d\n", p->frame_width_scale);
+    va_TraceMsg(trace_ctx, "\tkf_auto = %d\n", p->kf_auto);
+    va_TraceMsg(trace_ctx, "\tkf_max_dist = %d\n", p->kf_max_dist);
+    va_TraceMsg(trace_ctx, "\tkf_min_dist = %d\n", p->kf_min_dist);
+    va_TraceMsg(trace_ctx, "\tintra_period = %d\n", p->intra_period);
+
+    for(i = 0; i<4; ++i)
+        va_TraceMsg(trace_ctx, "\treference_frames[%d] = 0x%08x\n", i, p->reference_frames[i]);
+
+    va_TraceMsg(trace_ctx, NULL);
+
+    return;
+}
+
+static void va_TraceVAEncPictureParameterBufferVP8(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused uffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    VAEncPictureParameterBufferVP8 *p = (VAEncPictureParameterBufferVP8 *)data;
+    DPY2TRACECTX(dpy);
+    int i;
+
+    va_TraceMsg(trace_ctx, "\t--VAEncPictureParameterBufferVP8\n");
+    
+    va_TraceMsg(trace_ctx, "\treconstructed_frame = 0x%08x\n", p->reconstructed_frame);
+    va_TraceMsg(trace_ctx, "\tref_last_frame = 0x%08x\n", p->ref_last_frame);
+    va_TraceMsg(trace_ctx, "\tref_gf_frame = 0x%08x\n", p->ref_gf_frame);
+    va_TraceMsg(trace_ctx, "\tref_arf_frame = 0x%08x\n", p->ref_arf_frame);
+    va_TraceMsg(trace_ctx, "\tcoded_buf = 0x%08x\n", p->coded_buf);
+
+    va_TraceMsg(trace_ctx, "\tref_flags.bits.force_kf = %d\n", p->ref_flags.bits.force_kf);
+    va_TraceMsg(trace_ctx, "\tref_flags.bits.no_ref_last = %d\n", p->ref_flags.bits.no_ref_last);
+    va_TraceMsg(trace_ctx, "\tref_flags.bits.no_ref_gf = %d\n", p->ref_flags.bits.no_ref_gf);
+    va_TraceMsg(trace_ctx, "\tref_flags.bits.no_ref_arf = %d\n", p->ref_flags.bits.no_ref_arf);
+    va_TraceMsg(trace_ctx, "\tref_flags.bits.reserved = 0x%08x\n", p->ref_flags.bits.reserved);
+    
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.frame_type = %d\n", p->pic_flags.bits.frame_type);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.version = %d\n", p->pic_flags.bits.version);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.show_frame = %d\n", p->pic_flags.bits.show_frame);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.color_space = %d\n", p->pic_flags.bits.color_space);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.recon_filter_type = %d\n", p->pic_flags.bits.recon_filter_type);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.loop_filter_type = %d\n", p->pic_flags.bits.loop_filter_type);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.auto_partitions = %d\n", p->pic_flags.bits.auto_partitions);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.num_token_partitions = %d\n", p->pic_flags.bits.num_token_partitions);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.clamping_type = %d\n", p->pic_flags.bits.clamping_type);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.segmentation_enabled = %d\n", p->pic_flags.bits.segmentation_enabled);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.update_mb_segmentation_map = %d\n", p->pic_flags.bits.update_mb_segmentation_map);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.update_segment_feature_data = %d\n", p->pic_flags.bits.update_segment_feature_data);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.loop_filter_adj_enable = %d\n", p->pic_flags.bits.loop_filter_adj_enable);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.refresh_entropy_probs = %d\n", p->pic_flags.bits.refresh_entropy_probs);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.refresh_golden_frame = %d\n", p->pic_flags.bits.refresh_golden_frame);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.refresh_alternate_frame = %d\n", p->pic_flags.bits.refresh_alternate_frame);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.refresh_last = %d\n", p->pic_flags.bits.refresh_last);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.copy_buffer_to_golden = %d\n", p->pic_flags.bits.copy_buffer_to_golden);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.copy_buffer_to_alternate = %d\n", p->pic_flags.bits.copy_buffer_to_alternate);
+
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.sign_bias_golden = %d\n", p->pic_flags.bits.sign_bias_golden);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.sign_bias_alternate = %d\n", p->pic_flags.bits.sign_bias_alternate);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.mb_no_coeff_skip = %d\n", p->pic_flags.bits.mb_no_coeff_skip);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.forced_lf_adjustment = %d\n", p->pic_flags.bits.forced_lf_adjustment);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.reserved = %d\n", p->pic_flags.bits.reserved);
+
+
+    for(i=0;i<4;i++)
+       va_TraceMsg(trace_ctx, "\tloop_filter_level[%d] = %d\n", i, p->loop_filter_level[i]);
+    for(i=0;i<4;i++)
+       va_TraceMsg(trace_ctx, "\tref_lf_delta[%d] = %d\n", i, p->ref_lf_delta[i]);
+    for(i=0;i<4;i++)
+       va_TraceMsg(trace_ctx, "\tmode_lf_delta[%d] = %d\n", i, p->mode_lf_delta[i]);
+
+    va_TraceMsg(trace_ctx, "\tsharpness_level = %d\n", p->sharpness_level);
+    va_TraceMsg(trace_ctx, "\tclamp_qindex_high = %d\n", p->clamp_qindex_high);
+    va_TraceMsg(trace_ctx, "\tclamp_qindex_low = %d\n", p->clamp_qindex_low);
+
+    va_TraceMsg(trace_ctx, NULL);
+
+    return;
+}
+
+static void va_TraceVAPictureParameterBufferVP8(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    char tmp[1024];
+    VAPictureParameterBufferVP8 *p = (VAPictureParameterBufferVP8 *)data;
+    DPY2TRACECTX(dpy);
+    int i,j;
+
+    va_TraceMsg(trace_ctx, "\t--VAPictureParameterBufferVP8\n");
+
+    va_TraceMsg(trace_ctx, "\tframe_width = %d\n", p->frame_width);
+    va_TraceMsg(trace_ctx, "\tframe_height = %d\n", p->frame_height);
+    va_TraceMsg(trace_ctx, "\tlast_ref_frame = %x\n", p->last_ref_frame);
+    va_TraceMsg(trace_ctx, "\tgolden_ref_frame = %x\n", p->golden_ref_frame);
+    va_TraceMsg(trace_ctx, "\talt_ref_frame = %x\n", p->alt_ref_frame);
+    va_TraceMsg(trace_ctx, "\tout_of_loop_frame = %x\n", p->out_of_loop_frame);
+
+    va_TraceMsg(trace_ctx, "\tkey_frame = %d\n", p->pic_fields.bits.key_frame);
+    va_TraceMsg(trace_ctx, "\tversion = %d\n", p->pic_fields.bits.version);
+    va_TraceMsg(trace_ctx, "\tsegmentation_enabled = %d\n", p->pic_fields.bits.segmentation_enabled);
+    va_TraceMsg(trace_ctx, "\tupdate_mb_segmentation_map = %d\n", p->pic_fields.bits.update_mb_segmentation_map);
+    va_TraceMsg(trace_ctx, "\tupdate_segment_feature_data = %d\n", p->pic_fields.bits.update_segment_feature_data);
+    va_TraceMsg(trace_ctx, "\tfilter_type = %d\n", p->pic_fields.bits.filter_type);
+    va_TraceMsg(trace_ctx, "\tsharpness_level = %d\n", p->pic_fields.bits.sharpness_level);
+    va_TraceMsg(trace_ctx, "\tloop_filter_adj_enable = %d\n", p->pic_fields.bits.loop_filter_adj_enable);
+    va_TraceMsg(trace_ctx, "\tmode_ref_lf_delta_update = %d\n", p->pic_fields.bits.mode_ref_lf_delta_update);
+    va_TraceMsg(trace_ctx, "\tsign_bias_golden = %d\n", p->pic_fields.bits.sign_bias_golden);
+    va_TraceMsg(trace_ctx, "\tsign_bias_alternate = %d\n", p->pic_fields.bits.sign_bias_alternate);
+    va_TraceMsg(trace_ctx, "\tmb_no_coeff_skip = %d\n", p->pic_fields.bits.mb_no_coeff_skip);
+    va_TraceMsg(trace_ctx, "\tloop_filter_disable = %d\n", p->pic_fields.bits.loop_filter_disable);
+
+    va_TraceMsg(trace_ctx, "\tmb_segment_tree_probs: 0x%2x, 0x%2x, 0x%2x\n",
+        p->mb_segment_tree_probs[0], p->mb_segment_tree_probs[1], p->mb_segment_tree_probs[2]);
+
+    va_TraceMsg(trace_ctx, "\tloop_filter_level: %d, %d, %d, %d\n",
+        p->loop_filter_level[0], p->loop_filter_level[1], p->loop_filter_level[2], p->loop_filter_level[3]);
+
+    va_TraceMsg(trace_ctx, "\tloop_filter_deltas_ref_frame: %d, %d, %d, %d\n",
+        p->loop_filter_deltas_ref_frame[0], p->loop_filter_deltas_ref_frame[1], p->loop_filter_deltas_ref_frame[2], p->loop_filter_deltas_ref_frame[3]);
+
+    va_TraceMsg(trace_ctx, "\tloop_filter_deltas_mode: %d, %d, %d, %d\n",
+        p->loop_filter_deltas_mode[0], p->loop_filter_deltas_mode[1], p->loop_filter_deltas_mode[2], p->loop_filter_deltas_mode[3]);
+
+    va_TraceMsg(trace_ctx, "\tprob_skip_false = %2x\n", p->prob_skip_false);
+    va_TraceMsg(trace_ctx, "\tprob_intra = %2x\n", p->prob_intra);
+    va_TraceMsg(trace_ctx, "\tprob_last = %2x\n", p->prob_last);
+    va_TraceMsg(trace_ctx, "\tprob_gf = %2x\n", p->prob_gf);
+
+    va_TraceMsg(trace_ctx, "\ty_mode_probs: 0x%2x, 0x%2x, 0x%2x, 0x%2x\n",
+        p->y_mode_probs[0], p->y_mode_probs[1], p->y_mode_probs[2], p->y_mode_probs[3]);
+
+    va_TraceMsg(trace_ctx, "\tuv_mode_probs: 0x%2x, 0x%2x, 0x%2x\n",
+        p->uv_mode_probs[0], p->uv_mode_probs[1], p->uv_mode_probs[2]);
+
+    va_TraceMsg(trace_ctx, "\tmv_probs[2][19]:\n");
+    for(i = 0; i<2; ++i) {
+        memset(tmp, 0, sizeof tmp);
+        for (j=0; j<19; j++)
+            sprintf(tmp + strlen(tmp), "%2x ", p->mv_probs[i][j]);
+        va_TraceMsg(trace_ctx,"\t\t[%d] = %s\n", i, tmp);
+    }
+
+    va_TraceMsg(trace_ctx, "\tbool_coder_ctx: range = %02x, value = %02x, count = %d\n",
+        p->bool_coder_ctx.range, p->bool_coder_ctx.value, p->bool_coder_ctx.count);
+
+    va_TraceMsg(trace_ctx, NULL);
+
+    return;
+}
+
+static void va_TraceVASliceParameterBufferVP8(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    VASliceParameterBufferVP8 *p = (VASliceParameterBufferVP8 *)data;
+    DPY2TRACECTX(dpy);
+    int i;
+
+    va_TraceMsg(trace_ctx, "\t--VASliceParameterBufferVP8\n");
+
+    va_TraceMsg(trace_ctx, "\tslice_data_size = %d\n", p->slice_data_size);
+    va_TraceMsg(trace_ctx, "\tslice_data_offset = %d\n", p->slice_data_offset);
+    va_TraceMsg(trace_ctx, "\tslice_data_flag = %d\n", p->slice_data_flag);
+    va_TraceMsg(trace_ctx, "\tmacroblock_offset = %d\n", p->macroblock_offset);
+    va_TraceMsg(trace_ctx, "\tnum_of_partitions = %d\n", p->num_of_partitions);
+
+    for(i = 0; i<9; ++i)
+        va_TraceMsg(trace_ctx, "\tpartition_size[%d] = %d\n", i, p->partition_size[i]);
+
+    va_TraceMsg(trace_ctx, NULL);
+
+    return;
+}
+
+static void va_TraceVAIQMatrixBufferVP8(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    char tmp[1024];
+    VAIQMatrixBufferVP8 *p = (VAIQMatrixBufferVP8 *)data;
+    DPY2TRACECTX(dpy);
+    int i,j;
+
+    va_TraceMsg(trace_ctx, "\t--VAIQMatrixBufferVP8\n");
+
+    va_TraceMsg(trace_ctx, "\tquantization_index[4][6]=\n");
+    for (i = 0; i < 4; i++) {
+        memset(tmp, 0, sizeof tmp);
+        for (j = 0; j < 6; j++)
+            sprintf(tmp + strlen(tmp), "%4x, ", p->quantization_index[i][j]);
+        va_TraceMsg(trace_ctx,"\t\t[%d] = %s\n", i, tmp);
+    }
+
+    va_TraceMsg(trace_ctx, NULL);
+
+    return;
+}
+static void va_TraceVAProbabilityBufferVP8(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    char tmp[1024];
+    VAProbabilityDataBufferVP8 *p = (VAProbabilityDataBufferVP8 *)data;
+    DPY2TRACECTX(dpy);
+    int i,j,k,l;
+
+    va_TraceMsg(trace_ctx, "\t--VAProbabilityDataBufferVP8\n");
+
+    for (i = 0; i < 4; i++)
+        for (j = 0; j < 8; j++) {
+            memset(tmp, 0, sizeof tmp);
+            for (k=0; k<3; k++)
+                for (l=0; l<11; l++)
+                    sprintf(tmp + strlen(tmp), "%2x, ", p->dct_coeff_probs[i][j][k][l]);
+            va_TraceMsg(trace_ctx,"\t\t[%d, %d] = %s\n", i, j, tmp);
+        }
+
+    va_TraceMsg(trace_ctx, NULL);
+
+    return;
 }
 
 void va_TraceBeginPicture(
     VADisplay dpy,
-    VAContextID context,
+    VAContextID __maybe_unused context,
     VASurfaceID render_target
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
 
-    va_TraceMsg(idx, "\tcontext = 0x%08x\n", context);
-    va_TraceMsg(idx, "\trender_targets = 0x%08x\n", render_target);
-    va_TraceMsg(idx, "\tframe_count  = #%d\n", trace_context[idx].trace_frame_no);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "\trender_targets = 0x%08x\n", render_target);
+    va_TraceMsg(trace_ctx, "\tframe_count  = #%d\n", trace_ctx->trace_frame_no);
+    va_TraceMsg(trace_ctx, NULL);
 
-    trace_context[idx].trace_rendertarget = render_target; /* for surface data dump after vaEndPicture */
+    trace_ctx->trace_rendertarget = render_target; /* for surface data dump after vaEndPicture */
 
-    trace_context[idx].trace_frame_no++;
-    trace_context[idx].trace_slice_no = 0;
+    trace_ctx->trace_frame_no++;
+    trace_ctx->trace_slice_no = 0;
 }
 
 static void va_TraceMPEG2Buf(
@@ -1704,27 +2282,24 @@
 
 static void va_TraceVAEncSequenceParameterBufferH263(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAEncSequenceParameterBufferH263 *p = (VAEncSequenceParameterBufferH263 *)data;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
     
-    va_TraceMsg(idx, "VAEncSequenceParameterBufferH263\n");
+    va_TraceMsg(trace_ctx, "\t--VAEncSequenceParameterBufferH263\n");
     
-    va_TraceMsg(idx, "\tintra_period = %d\n", p->intra_period);
-    va_TraceMsg(idx, "\tbits_per_second = %d\n", p->bits_per_second);
-    va_TraceMsg(idx, "\tframe_rate = %d\n", p->frame_rate);
-    va_TraceMsg(idx, "\tinitial_qp = %d\n", p->initial_qp);
-    va_TraceMsg(idx, "\tmin_qp = %d\n", p->min_qp);
-    va_TraceMsg(idx, NULL);
-
-    /* start a new sequce, coded log file can be truncated */
-    trace_context[idx].trace_sequence_start = 1;
+    va_TraceMsg(trace_ctx, "\tintra_period = %d\n", p->intra_period);
+    va_TraceMsg(trace_ctx, "\tbits_per_second = %d\n", p->bits_per_second);
+    va_TraceMsg(trace_ctx, "\tframe_rate = %d\n", p->frame_rate);
+    va_TraceMsg(trace_ctx, "\tinitial_qp = %d\n", p->initial_qp);
+    va_TraceMsg(trace_ctx, "\tmin_qp = %d\n", p->min_qp);
+    va_TraceMsg(trace_ctx, NULL);
 
     return;
 }
@@ -1732,103 +2307,167 @@
 
 static void va_TraceVAEncPictureParameterBufferH263(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAEncPictureParameterBufferH263 *p = (VAEncPictureParameterBufferH263 *)data;
-    DPY2INDEX(dpy);
-    
-    va_TraceMsg(idx, "VAEncPictureParameterBufferH263\n");
-    va_TraceMsg(idx, "\treference_picture = 0x%08x\n", p->reference_picture);
-    va_TraceMsg(idx, "\treconstructed_picture = 0x%08x\n", p->reconstructed_picture);
-    va_TraceMsg(idx, "\tcoded_buf = %08x\n", p->coded_buf);
-    va_TraceMsg(idx, "\tpicture_width = %d\n", p->picture_width);
-    va_TraceMsg(idx, "\tpicture_height = %d\n", p->picture_height);
-    va_TraceMsg(idx, "\tpicture_type = 0x%08x\n", p->picture_type);
-    va_TraceMsg(idx, NULL);
+    DPY2TRACECTX(dpy);
 
-    trace_context[idx].trace_codedbuf =  p->coded_buf;
-    
+    va_TraceMsg(trace_ctx, "\t--VAEncPictureParameterBufferH263\n");
+    va_TraceMsg(trace_ctx, "\treference_picture = 0x%08x\n", p->reference_picture);
+    va_TraceMsg(trace_ctx, "\treconstructed_picture = 0x%08x\n", p->reconstructed_picture);
+    va_TraceMsg(trace_ctx, "\tcoded_buf = %08x\n", p->coded_buf);
+    va_TraceMsg(trace_ctx, "\tpicture_width = %d\n", p->picture_width);
+    va_TraceMsg(trace_ctx, "\tpicture_height = %d\n", p->picture_height);
+    va_TraceMsg(trace_ctx, "\tpicture_type = 0x%08x\n", p->picture_type);
+    va_TraceMsg(trace_ctx, NULL);
+
     return;
 }
 
 static void va_TraceVAEncPictureParameterBufferJPEG(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAEncPictureParameterBufferJPEG *p = (VAEncPictureParameterBufferJPEG *)data;
-    DPY2INDEX(dpy);
-    
-    va_TraceMsg(idx, "VAEncPictureParameterBufferJPEG\n");
-    va_TraceMsg(idx, "\treconstructed_picture = 0x%08x\n", p->reconstructed_picture);
-    va_TraceMsg(idx, "\tcoded_buf = %08x\n", p->coded_buf);
-    va_TraceMsg(idx, "\tpicture_width = %d\n", p->picture_width);
-    va_TraceMsg(idx, "\tpicture_height = %d\n", p->picture_height);
-    va_TraceMsg(idx, NULL);
+    int i;
 
-    trace_context[idx].trace_codedbuf =  p->coded_buf;
+    DPY2TRACECTX(dpy);
     
+    va_TraceMsg(trace_ctx, "\t--VAEncPictureParameterBufferJPEG\n");
+    va_TraceMsg(trace_ctx, "\treconstructed_picture = 0x%08x\n", p->reconstructed_picture);
+    va_TraceMsg(trace_ctx, "\tcoded_buf = %08x\n", p->coded_buf);
+    va_TraceMsg(trace_ctx, "\tpicture_width = %d\n", p->picture_width);
+    va_TraceMsg(trace_ctx, "\tpicture_height = %d\n", p->picture_height);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.profile = %d\n", p->pic_flags.bits.profile);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.progressive = %d\n", p->pic_flags.bits.profile);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.huffman = %d\n", p->pic_flags.bits.huffman);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.interleaved = %d\n", p->pic_flags.bits.interleaved);
+    va_TraceMsg(trace_ctx, "\tpic_flags.bits.differential = %d\n", p->pic_flags.bits.differential);
+    va_TraceMsg(trace_ctx, "\tsample_bit_depth = %d\n", p->sample_bit_depth);
+    va_TraceMsg(trace_ctx, "\tnum_scan = %d\n", p->num_scan);
+    va_TraceMsg(trace_ctx, "\tnum_components = %d\n", p->num_components);
+    for (i=0; i<p->num_components; i++)
+        va_TraceMsg(trace_ctx, "\tcomponent_id[%d] = %d\n", i, p->component_id[i]);
+
+    if (p->quality > 0)
+        va_TraceMsg(trace_ctx, "\tquality = %d\n", p->quality);
+    else
+        va_TraceMsg(trace_ctx, "\tquantiser_table_selector[] = %d %d %d %d\n",
+                    p->quantiser_table_selector[0],
+                    p->quantiser_table_selector[1],
+                    p->quantiser_table_selector[2],
+                    p->quantiser_table_selector[3]);
+
+    va_TraceMsg(trace_ctx, NULL);
+
     return;
 }
 
 static void va_TraceVAEncQMatrixBufferJPEG(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *data)
 {
     VAQMatrixBufferJPEG *p = (VAQMatrixBufferJPEG *)data;
-    DPY2INDEX(dpy);
-    
-    va_TraceMsg(idx, "VAQMatrixBufferJPEG\n");
-    va_TraceMsg(idx, "\tload_lum_quantiser_matrix = %d", p->load_lum_quantiser_matrix);
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx, "\t--VAQMatrixBufferJPEG\n");
+    va_TraceMsg(trace_ctx, "\tload_lum_quantiser_matrix = %d\n", p->load_lum_quantiser_matrix);
     if (p->load_lum_quantiser_matrix) {
         int i;
-        for (i = 0; i < 64; i++) {
-            if ((i % 8) == 0)
-                va_TraceMsg(idx, "\n\t");
-            va_TraceMsg(idx, "\t0x%02x", p->lum_quantiser_matrix[i]);
+        for (i = 0; i < 8; i++) {
+            va_TraceMsg(trace_ctx,
+                        "\t\t0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+                        p->lum_quantiser_matrix[i*8],
+                        p->lum_quantiser_matrix[i*8 + 1],
+                        p->lum_quantiser_matrix[i*8 + 2],
+                        p->lum_quantiser_matrix[i*8 + 3],
+                        p->lum_quantiser_matrix[i*8 + 4],
+                        p->lum_quantiser_matrix[i*8 + 5],
+                        p->lum_quantiser_matrix[i*8 + 6],
+                        p->lum_quantiser_matrix[i*8 + 7]);
         }
-        va_TraceMsg(idx, "\n");
     }
-    va_TraceMsg(idx, "\tload_chroma_quantiser_matrix = %08x\n", p->load_chroma_quantiser_matrix);
+
+    va_TraceMsg(trace_ctx, "\tload_chroma_quantiser_matrix = %d\n", p->load_chroma_quantiser_matrix);
     if (p->load_chroma_quantiser_matrix) {
         int i;
-        for (i = 0; i < 64; i++) {
-            if ((i % 8) == 0)
-                va_TraceMsg(idx, "\n\t");
-            va_TraceMsg(idx, "\t0x%02x", p->chroma_quantiser_matrix[i]);
+        for (i = 0; i < 8; i++) {
+            va_TraceMsg(trace_ctx,
+                        "\t\t0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+                        p->chroma_quantiser_matrix[i*8],
+                        p->chroma_quantiser_matrix[i*8 + 1],
+                        p->chroma_quantiser_matrix[i*8 + 2],
+                        p->chroma_quantiser_matrix[i*8 + 3],
+                        p->chroma_quantiser_matrix[i*8 + 4],
+                        p->chroma_quantiser_matrix[i*8 + 5],
+                        p->chroma_quantiser_matrix[i*8 + 6],
+                        p->chroma_quantiser_matrix[i*8 + 7]);
         }
-        va_TraceMsg(idx, "\n");
     }
     
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
     
     return;
 }
 
+
+static void va_TraceVAEncSliceParameterBufferJPEG(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data)
+{
+    VAEncSliceParameterBufferJPEG *p = (VAEncSliceParameterBufferJPEG *)data;
+    int i;
+
+    DPY2TRACECTX(dpy);
+    
+    va_TraceMsg(trace_ctx, "\t--VAEncSliceParameterBufferJPEG\n");
+    va_TraceMsg(trace_ctx, "\trestart_interval = 0x%04x\n", p->restart_interval);
+    va_TraceMsg(trace_ctx, "\tnum_components = 0x%08x\n", p->num_components);
+    for (i=0; i<4; i++) {
+        va_TraceMsg(trace_ctx, "\tcomponents[%i] =\n ");
+        va_TraceMsg(trace_ctx, "\t\tcomponent_selector = %d\n", p->components[i].component_selector);
+        va_TraceMsg(trace_ctx, "\t\tdc_table_selector = %d\n", p->components[i].dc_table_selector);
+        va_TraceMsg(trace_ctx, "\t\tac_table_selector = %d\n", p->components[i].ac_table_selector);
+    }
+    
+    va_TraceMsg(trace_ctx, NULL);
+    
+    return;
+}
+
+
 static void va_TraceH263Buf(
     VADisplay dpy,
-    VAContextID context,
-    VABufferID buffer,
-    VABufferType type,
-    unsigned int size,
-    unsigned int num_elements,
+    VAContextID __maybe_unused context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
     void *pbuf
 )
 {
+    DPY2TRACECTX(dpy);
+
     switch (type) {
     case VAPictureParameterBufferType:/* print MPEG4 buffer */
         va_TraceVAPictureParameterBufferMPEG4(dpy, context, buffer, type, size, num_elements, pbuf);
@@ -1872,7 +2511,11 @@
     case VAEncSliceParameterBufferType:
         va_TraceVAEncSliceParameterBuffer(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
+    case VAEncPackedHeaderParameterBufferType:
+        va_TraceVAEncPackedHeaderParameterBufferType(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
     default:
+        va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     }
 }
@@ -1889,11 +2532,8 @@
 )
 {
     switch (type) {
-    case VAPictureParameterBufferType:/* print MPEG4 buffer */
-    case VAIQMatrixBufferType:/* print MPEG4 buffer */
-    case VABitPlaneBufferType:/* print MPEG4 buffer */
+    case VABitPlaneBufferType:
     case VASliceGroupMapBufferType:
-    case VASliceParameterBufferType:/* print MPEG4 buffer */
     case VASliceDataBufferType:
     case VAMacroblockParameterBufferType:
     case VAResidualDataBufferType:
@@ -1902,9 +2542,23 @@
     case VAProtectedSliceDataBufferType:
     case VAEncCodedBufferType:
     case VAEncSequenceParameterBufferType:
-    case VAEncSliceParameterBufferType:
         va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
+    case VAEncSliceParameterBufferType:
+        va_TraceVAEncPictureParameterBufferJPEG(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VAPictureParameterBufferType:
+        va_TraceVAPictureParameterBufferJPEG(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VAIQMatrixBufferType:
+        va_TraceVAIQMatrixBufferJPEG(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VASliceParameterBufferType:
+        va_TraceVASliceParameterBufferJPEG(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VAHuffmanTableBufferType:
+        va_TraceVAHuffmanTableBufferJPEG(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
     case VAEncPictureParameterBufferType:
         va_TraceVAEncPictureParameterBufferJPEG(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
@@ -1912,6 +2566,7 @@
         va_TraceVAEncQMatrixBufferJPEG(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     default:
+        va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     }
 }
@@ -1970,6 +2625,7 @@
         va_TraceVAEncSliceParameterBuffer(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     default:
+        va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     }
 }
@@ -1985,7 +2641,7 @@
     void *pbuf
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
     
     switch (type) {
     case VAPictureParameterBufferType:
@@ -2004,7 +2660,7 @@
         va_TraceVASliceParameterBufferH264(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     case VASliceDataBufferType:
-        va_TraceVABuffers(dpy, context, buffer, type, trace_context[idx].trace_slice_size, num_elements, pbuf);
+        va_TraceVABuffers(dpy, context, buffer, type, trace_ctx->trace_slice_size, num_elements, pbuf);
         break;
     case VAMacroblockParameterBufferType:
         va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);        
@@ -2029,12 +2685,83 @@
         va_TraceVAEncPictureParameterBufferH264(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     case VAEncSliceParameterBufferType:
-        va_TraceVAEncSliceParameterBufferH264(dpy, context, buffer, type, size, num_elements, pbuf);
+        if (size == sizeof(VAEncSliceParameterBuffer))
+            va_TraceVAEncSliceParameterBuffer(dpy, context, buffer, type, size, num_elements, pbuf);
+        else
+            va_TraceVAEncSliceParameterBufferH264(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VAEncPackedHeaderParameterBufferType:
+        va_TraceVAEncPackedHeaderParameterBufferType(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+        
+    case VAEncMiscParameterBufferType:
+        va_TraceVAEncMiscParameterBuffer(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    default:
+        va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    }
+}
+
+static void va_TraceVP8Buf(
+    VADisplay dpy,
+    VAContextID context,
+    VABufferID buffer,
+    VABufferType type,
+    unsigned int size,
+    unsigned int num_elements,
+    void *pbuf
+)
+{
+    DPY2TRACECTX(dpy);
+
+    switch (type) {
+    case VAPictureParameterBufferType:
+        va_TraceVAPictureParameterBufferVP8(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VAIQMatrixBufferType:
+        va_TraceVAIQMatrixBufferVP8(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VABitPlaneBufferType:
+        break;
+    case VASliceGroupMapBufferType:
+        break;
+    case VASliceParameterBufferType:
+        va_TraceVASliceParameterBufferVP8(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VASliceDataBufferType:
+        va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VAProbabilityBufferType:
+        va_TraceVAProbabilityBufferVP8(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VAMacroblockParameterBufferType:
+        break;
+    case VAResidualDataBufferType:
+        break;
+    case VADeblockingParameterBufferType:
+        break;
+    case VAImageBufferType:
+        break;
+    case VAProtectedSliceDataBufferType:
+        break;
+    case VAEncCodedBufferType:
+        break;
+    case VAEncSequenceParameterBufferType:
+        va_TraceVAEncSequenceParameterBufferVP8(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VAEncPictureParameterBufferType:
+        va_TraceVAEncPictureParameterBufferVP8(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    case VAEncSliceParameterBufferType:
+        break;
+    case VAEncPackedHeaderParameterBufferType:
         break;
     case VAEncMiscParameterBufferType:
         va_TraceVAEncMiscParameterBuffer(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     default:
+        va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     }
 }
@@ -2050,7 +2777,7 @@
     void *pbuf
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     switch (type) {
     case VAPictureParameterBufferType:
@@ -2068,7 +2795,7 @@
         va_TraceVASliceParameterBufferVC1(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     case VASliceDataBufferType:
-        va_TraceVABuffers(dpy, context, buffer, type, trace_context[idx].trace_slice_size, num_elements, pbuf);
+        va_TraceVABuffers(dpy, context, buffer, type, trace_ctx->trace_slice_size, num_elements, pbuf);
         break;
     case VAMacroblockParameterBufferType:
         va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
@@ -2096,13 +2823,234 @@
         va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     default:
+        va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    }
+}
+
+static void
+va_TraceProcFilterParameterBufferDeinterlacing(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VAProcFilterParameterBufferBase *base
+)
+{
+    VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
+
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx, "\t    type = %d\n", deint->type);
+    va_TraceMsg(trace_ctx, "\t    algorithm = %d\n", deint->algorithm);
+    va_TraceMsg(trace_ctx, "\t    flags = %d\n", deint->flags);
+}
+
+static void
+va_TraceProcFilterParameterBufferColorBalance(
+    VADisplay dpy,
+    VAContextID __maybe_unused context,
+    VAProcFilterParameterBufferBase *base
+)
+{
+    VAProcFilterParameterBufferColorBalance *color_balance = (VAProcFilterParameterBufferColorBalance *)base;
+
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx, "\t    type = %d\n", color_balance->type);
+    va_TraceMsg(trace_ctx, "\t    attrib = %d\n", color_balance->attrib);
+    va_TraceMsg(trace_ctx, "\t    value = %f\n", color_balance->value);
+}
+
+static void
+va_TraceProcFilterParameterBufferBase(
+    VADisplay dpy,
+    VAContextID context,
+    VAProcFilterParameterBufferBase *base
+)
+{
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx, "\t    type = %d, context = %d\n", base->type, context);
+}
+
+static void
+va_TraceProcFilterParameterBuffer(
+    VADisplay dpy,
+    VAContextID context,
+    VABufferID *filters,
+    unsigned int num_filters
+)
+{
+    VABufferType type;
+    unsigned int size;
+    unsigned int num_elements;
+    VAProcFilterParameterBufferBase *base_filter = NULL;
+    unsigned int i;
+
+    DPY2TRACECTX(dpy);
+
+    if (num_filters == 0 || filters == NULL) {
+        va_TraceMsg(trace_ctx, "\t  num_filters = %d\n", num_filters);
+        va_TraceMsg(trace_ctx, "\t  filters = %p\n", filters);
+        return;
+    }
+
+    va_TraceMsg(trace_ctx, "\t  num_filters = %d\n", num_filters);
+
+    /* get buffer type information */
+    for (i = 0; i < num_filters; i++) {
+        vaBufferInfo(dpy, context, filters[i], &type, &size, &num_elements);
+
+        if (type != VAProcFilterParameterBufferType) {
+            va_TraceMsg(trace_ctx, "\t  filters[%d] = 0x%08x (INVALID)\n", i, filters[i]);
+            return;
+        } else {
+            va_TraceMsg(trace_ctx, "\t  filters[%d] = 0x%08x\n", i, filters[i]);
+        }
+
+        base_filter = NULL;
+        vaMapBuffer(dpy, filters[i], (void **)&base_filter);
+
+        if (base_filter == NULL) {
+            vaUnmapBuffer(dpy, filters[i]);
+            return;
+        }
+
+        switch (base_filter->type) {
+        case VAProcFilterDeinterlacing:
+            va_TraceProcFilterParameterBufferDeinterlacing(dpy,
+                                                           context,
+                                                           base_filter);
+            break;
+        case VAProcFilterColorBalance:
+            va_TraceProcFilterParameterBufferColorBalance(dpy,
+                                                          context,
+                                                          base_filter);
+            break;
+        default:
+            va_TraceProcFilterParameterBufferBase(dpy,
+                                                  context,
+                                                  base_filter);
+            break;
+        }
+
+        vaUnmapBuffer(dpy, filters[i]);
+    }
+}
+
+static void
+va_TraceVAProcPipelineParameterBuffer(
+    VADisplay dpy,
+    VAContextID context,
+    VABufferID __maybe_unused buffer,
+    VABufferType __maybe_unused type,
+    unsigned int __maybe_unused size,
+    unsigned int __maybe_unused num_elements,
+    void *data
+)
+{
+    VAProcPipelineParameterBuffer *p = (VAProcPipelineParameterBuffer *)data;
+    unsigned int i;
+
+    DPY2TRACECTX(dpy);
+
+    va_TraceMsg(trace_ctx, "\t--VAProcPipelineParameterBuffer\n");
+
+    va_TraceMsg(trace_ctx, "\t  surface = 0x%08x\n", p->surface);
+
+    if (p->surface_region) {
+        va_TraceMsg(trace_ctx, "\t  surface_region\n");
+        va_TraceMsg(trace_ctx, "\t    x = %d\n", p->surface_region->x);
+        va_TraceMsg(trace_ctx, "\t    y = %d\n", p->surface_region->y);
+        va_TraceMsg(trace_ctx, "\t    width = %d\n", p->surface_region->width);
+        va_TraceMsg(trace_ctx, "\t    height = %d\n", p->surface_region->height);
+    } else {
+        va_TraceMsg(trace_ctx, "\t  surface_region = (NULL)\n");
+    }
+
+    va_TraceMsg(trace_ctx, "\t  surface_color_standard = %d\n", p->surface_color_standard);
+
+    if (p->output_region) {
+        va_TraceMsg(trace_ctx, "\t  output_region\n");
+        va_TraceMsg(trace_ctx, "\t    x = %d\n", p->output_region->x);
+        va_TraceMsg(trace_ctx, "\t    y = %d\n", p->output_region->y);
+        va_TraceMsg(trace_ctx, "\t    width = %d\n", p->output_region->width);
+        va_TraceMsg(trace_ctx, "\t    height = %d\n", p->output_region->height);
+    } else {
+        va_TraceMsg(trace_ctx, "\t  output_region = (NULL)\n");
+    }
+
+    va_TraceMsg(trace_ctx, "\t  output_background_color = 0x%08x\n", p->output_background_color);
+    va_TraceMsg(trace_ctx, "\t  output_color_standard = %d\n", p->output_color_standard);
+    va_TraceMsg(trace_ctx, "\t  pipeline_flags = 0x%08x\n", p->pipeline_flags);
+    va_TraceMsg(trace_ctx, "\t  filter_flags = 0x%08x\n", p->filter_flags);
+
+    va_TraceProcFilterParameterBuffer(dpy, context, p->filters, p->num_filters);
+
+    va_TraceMsg(trace_ctx, "\t  num_forward_references = 0x%08x\n", p->num_forward_references);
+
+    if (p->num_forward_references) {
+        va_TraceMsg(trace_ctx, "\t  forward_references\n");
+
+        if (p->forward_references) {
+            /* only dump the first 5 forward references */
+            for (i = 0; i < p->num_forward_references && i < 5; i++) {
+                va_TraceMsg(trace_ctx, "\t    forward_references[%d] = 0x%08x\n", i, p->forward_references[i]);
+            }
+        } else {
+            for (i = 0; i < p->num_forward_references && i < 5; i++) {
+                va_TraceMsg(trace_ctx, "\t    forward_references[%d] = (NULL)\n", i);
+            }
+        }
+    }
+
+    va_TraceMsg(trace_ctx, "\t  num_backward_references = 0x%08x\n", p->num_backward_references);
+
+    if (p->num_backward_references) {
+        va_TraceMsg(trace_ctx, "\t  backward_references\n");
+
+        if (p->backward_references) {
+            /* only dump the first 5 backward references */
+            for (i = 0; i < p->num_backward_references && i < 5; i++) {
+                va_TraceMsg(trace_ctx, "\t    backward_references[%d] = 0x%08x\n", i, p->backward_references[i]);
+            }
+        } else {
+            for (i = 0; i < p->num_backward_references && i < 5; i++) {
+                va_TraceMsg(trace_ctx, "\t    backward_references[%d] = (NULL)\n", i);
+            }
+        }
+    }
+
+    /* FIXME: add other info later */
+
+    va_TraceMsg(trace_ctx, NULL);
+}
+
+static void
+va_TraceNoneBuf(
+    VADisplay dpy,
+    VAContextID context,
+    VABufferID buffer,
+    VABufferType type,
+    unsigned int size,
+    unsigned int num_elements,
+    void *pbuf
+)
+{
+    DPY2TRACECTX(dpy);
+
+    switch (type) {
+    case VAProcPipelineParameterBufferType:
+        va_TraceVAProcPipelineParameterBuffer(dpy, context, buffer, type, size, num_elements, pbuf);
+        break;
+    default:
+        va_TraceVABuffers(dpy, context, buffer, type, size, num_elements, pbuf);
         break;
     }
 }
 
 void va_TraceRenderPicture(
     VADisplay dpy,
-    VAContextID context,
+    VAContextID __maybe_unused context,
     VABufferID *buffers,
     int num_buffers
 )
@@ -2111,33 +3059,36 @@
     unsigned int size;
     unsigned int num_elements;
     int i;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
     
-    va_TraceMsg(idx, "\tcontext = 0x%08x\n", context);
-    va_TraceMsg(idx, "\tnum_buffers = %d\n", num_buffers);
+    va_TraceMsg(trace_ctx, "\tnum_buffers = %d\n", num_buffers);
+    if (buffers == NULL)
+        return;
+    
     for (i = 0; i < num_buffers; i++) {
-        unsigned char *pbuf;
+        unsigned char *pbuf = NULL;
         unsigned int j;
         
         /* get buffer type information */
         vaBufferInfo(dpy, context, buffers[i], &type, &size, &num_elements);
 
-        va_TraceMsg(idx, "\t---------------------------\n");
-        va_TraceMsg(idx, "\tbuffers[%d] = 0x%08x\n", i, buffers[i]);
-        va_TraceMsg(idx, "\t  type = %s\n", buffer_type_to_string(type));
-        va_TraceMsg(idx, "\t  size = %d\n", size);
-        va_TraceMsg(idx, "\t  num_elements = %d\n", num_elements);
+        va_TraceMsg(trace_ctx, "\t---------------------------\n");
+        va_TraceMsg(trace_ctx, "\tbuffers[%d] = 0x%08x\n", i, buffers[i]);
+        va_TraceMsg(trace_ctx, "\t  type = %s\n", buffer_type_to_string(type));
+        va_TraceMsg(trace_ctx, "\t  size = %d\n", size);
+        va_TraceMsg(trace_ctx, "\t  num_elements = %d\n", num_elements);
 
         vaMapBuffer(dpy, buffers[i], (void **)&pbuf);
-
-        switch (trace_context[idx].trace_profile) {
+        if (pbuf == NULL)
+            continue;
+        
+        switch (trace_ctx->trace_profile) {
         case VAProfileMPEG2Simple:
         case VAProfileMPEG2Main:
             for (j=0; j<num_elements; j++) {
-                va_TraceMsg(idx, "\t---------------------------\n", j);
-                va_TraceMsg(idx, "\telement[%d] = ", j);
+                va_TraceMsg(trace_ctx, "\telement[%d] =\n", j);
                 va_TraceMPEG2Buf(dpy, context, buffers[i], type, size, num_elements, pbuf + size*j);
             }
             break;
@@ -2145,8 +3096,7 @@
         case VAProfileMPEG4AdvancedSimple:
         case VAProfileMPEG4Main:
             for (j=0; j<num_elements; j++) {
-                va_TraceMsg(idx, "\t---------------------------\n", j);
-                va_TraceMsg(idx, "\telement[%d] = ", j);
+                va_TraceMsg(trace_ctx, "\telement[%d] =\n", j);
                 va_TraceMPEG4Buf(dpy, context, buffers[i], type, size, num_elements, pbuf + size*j);
             }
             break;
@@ -2155,8 +3105,7 @@
         case VAProfileH264High:
         case VAProfileH264ConstrainedBaseline:
             for (j=0; j<num_elements; j++) {
-                va_TraceMsg(idx, "\t---------------------------\n", j);
-                va_TraceMsg(idx, "\telement[%d] = ", j);
+                va_TraceMsg(trace_ctx, "\telement[%d] =\n", j);
                 
                 va_TraceH264Buf(dpy, context, buffers[i], type, size, num_elements, pbuf + size*j);
             }
@@ -2165,26 +3114,37 @@
         case VAProfileVC1Main:
         case VAProfileVC1Advanced:
             for (j=0; j<num_elements; j++) {
-                va_TraceMsg(idx, "\t---------------------------\n", j);
-                va_TraceMsg(idx, "\telement[%d] = ", j);
+                va_TraceMsg(trace_ctx, "\telement[%d] =\n", j);
                 
                 va_TraceVC1Buf(dpy, context, buffers[i], type, size, num_elements, pbuf + size*j);
             }
             break;
         case VAProfileH263Baseline:
             for (j=0; j<num_elements; j++) {
-                va_TraceMsg(idx, "\t---------------------------\n", j);
-                va_TraceMsg(idx, "\telement[%d] = ", j);
+                va_TraceMsg(trace_ctx, "\telement[%d] =\n", j);
                 
                 va_TraceH263Buf(dpy, context, buffers[i], type, size, num_elements, pbuf + size*j);
             }
             break;
         case VAProfileJPEGBaseline:
             for (j=0; j<num_elements; j++) {
-                va_TraceMsg(idx, "\t---------------------------\n", j);
-                va_TraceMsg(idx, "\telement[%d] = ", j);
+                va_TraceMsg(trace_ctx, "\telement[%d] =\n", j);
                 
-                va_TraceJPEGBuf(dpy, context, buffers[i], type, size, num_elements, pbuf + size*j);
+                va_TraceJPEGBuf (dpy, context, buffers[i], type, size, num_elements, pbuf + size*j);
+            }
+            break;
+        case VAProfileVP8Version0_3:
+            for (j=0; j<num_elements; j++) {
+                va_TraceMsg(trace_ctx, "\telement[%d] =\n", j);
+
+                va_TraceVP8Buf(dpy, context, buffers[i], type, size, num_elements, pbuf + size*j);
+            }
+            break;
+        case VAProfileNone:
+            for (j=0; j<num_elements; j++) {
+                va_TraceMsg(trace_ctx, "\telement[%d] =\n", j);
+
+                va_TraceNoneBuf(dpy, context, buffers[i], type, size, num_elements, pbuf + size*j);
             }
             break;
         default:
@@ -2194,76 +3154,84 @@
         vaUnmapBuffer(dpy, buffers[i]);
     }
 
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 void va_TraceEndPicture(
     VADisplay dpy,
-    VAContextID context,
-    int endpic_done
+    VAContextID __maybe_unused context,
+    int __maybe_unused endpic_done
 )
 {
     int encode, decode, jpeg;
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
 
-    va_TraceMsg(idx, "\tcontext = 0x%08x\n", context);
-    va_TraceMsg(idx, "\trender_targets = 0x%08x\n", trace_context[idx].trace_rendertarget);
+    va_TraceMsg(trace_ctx, "\trender_targets = 0x%08x\n", trace_ctx->trace_rendertarget);
 
-    encode = (trace_context[idx].trace_entrypoint == VAEntrypointEncSlice) &&
-        (trace_flag & VA_TRACE_FLAG_SURFACE_ENCODE);
-    decode = (trace_context[idx].trace_entrypoint == VAEntrypointVLD) &&
-        (trace_flag & VA_TRACE_FLAG_SURFACE_DECODE);
-    jpeg = (trace_context[idx].trace_entrypoint == VAEntrypointEncPicture) &&
-        (trace_flag & VA_TRACE_FLAG_SURFACE_JPEG);
+    /* avoid to create so many empty files */
+    encode = (trace_ctx->trace_entrypoint == VAEntrypointEncSlice);
+    decode = (trace_ctx->trace_entrypoint == VAEntrypointVLD);
+    jpeg = (trace_ctx->trace_entrypoint == VAEntrypointEncPicture);
 
     /* trace encode source surface, can do it before HW completes rendering */
-    if (encode || jpeg)
+    if ((encode && (trace_flag & VA_TRACE_FLAG_SURFACE_ENCODE))||
+        (jpeg && (trace_flag & VA_TRACE_FLAG_SURFACE_JPEG)))
         va_TraceSurface(dpy);
     
-    /* trace coded buffer, do it after HW completes rendering */
-    if ((encode || jpeg) && (trace_flag & VA_TRACE_FLAG_CODEDBUF)) {
-        vaSyncSurface(dpy, trace_context[idx].trace_rendertarget);
-        va_TraceCodedBuf(dpy);
-    }
-
     /* trace decoded surface, do it after HW completes rendering */
-    if (decode) {
-        vaSyncSurface(dpy, trace_context[idx].trace_rendertarget);
+    if (decode && ((trace_flag & VA_TRACE_FLAG_SURFACE_DECODE))) {
+        vaSyncSurface(dpy, trace_ctx->trace_rendertarget);
         va_TraceSurface(dpy);
     }
 
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
+
 void va_TraceSyncSurface(
     VADisplay dpy,
-    VASurfaceID render_target
+    VASurfaceID __maybe_unused render_target
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
 
-    va_TraceMsg(idx, "\trender_target = 0x%08x\n", render_target);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
+}
+
+void va_TraceQuerySurfaceAttributes(
+    VADisplay           dpy,
+    VAConfigID          __maybe_unused config,
+    VASurfaceAttrib    *attrib_list,
+    unsigned int       *num_attribs
+)
+{
+    DPY2TRACECTX(dpy);
+
+    TRACE_FUNCNAME(idx);
+    va_TraceSurfaceAttributes(trace_ctx, attrib_list, num_attribs);
+    
+    va_TraceMsg(trace_ctx, NULL);
+
 }
 
 
 void va_TraceQuerySurfaceStatus(
     VADisplay dpy,
-    VASurfaceID render_target,
+    VASurfaceID __maybe_unused render_target,
     VASurfaceStatus *status    /* out */
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
 
-    va_TraceMsg(idx, "\trender_target = 0x%08x\n", render_target);
-    va_TraceMsg(idx, "\tstatus = 0x%08x\n", *status);
-    va_TraceMsg(idx, NULL);
+    if (status)
+        va_TraceMsg(trace_ctx, "\tstatus = 0x%08x\n", *status);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 
@@ -2274,21 +3242,21 @@
     void **error_info       /*out*/
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
-    va_TraceMsg(idx, "\tsurface = 0x%08x\n", surface);
-    va_TraceMsg(idx, "\terror_status = 0x%08x\n", error_status);
-    if (error_status == VA_STATUS_ERROR_DECODING_ERROR) {
+    va_TraceMsg(trace_ctx, "\tsurface = 0x%08x\n", surface);
+    va_TraceMsg(trace_ctx, "\terror_status = 0x%08x\n", error_status);
+    if (error_info && (error_status == VA_STATUS_ERROR_DECODING_ERROR)) {
         VASurfaceDecodeMBErrors *p = *error_info;
-        while (p->status != -1) {
-            va_TraceMsg(idx, "\t\tstatus = %d\n", p->status);
-            va_TraceMsg(idx, "\t\tstart_mb = %d\n", p->start_mb);
-            va_TraceMsg(idx, "\t\tend_mb = %d\n", p->end_mb);
+        while (p && (p->status != -1)) {
+            va_TraceMsg(trace_ctx, "\t\tstatus = %d\n", p->status);
+            va_TraceMsg(trace_ctx, "\t\tstart_mb = %d\n", p->start_mb);
+            va_TraceMsg(trace_ctx, "\t\tend_mb = %d\n", p->end_mb);
             p++; /* next error record */
         }
     }
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 void va_TraceMaxNumDisplayAttributes (
@@ -2296,12 +3264,12 @@
     int number
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
     
-    va_TraceMsg(idx, "\tmax_display_attributes = %d\n", number);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "\tmax_display_attributes = %d\n", number);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 void va_TraceQueryDisplayAttributes (
@@ -2312,42 +3280,47 @@
 {
     int i;
     
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
     
-    va_TraceMsg(idx, "\tnum_attributes = %d\n", *num_attributes);
+    if (attr_list == NULL || num_attributes == NULL)
+        return;
 
+    va_TraceMsg(trace_ctx, "\tnum_attributes = %d\n", *num_attributes);
+    
     for (i=0; i<*num_attributes; i++) {
-        va_TraceMsg(idx, "\tattr_list[%d] =\n");
-        va_TraceMsg(idx, "\t  typ = 0x%08x\n", attr_list[i].type);
-        va_TraceMsg(idx, "\t  min_value = %d\n", attr_list[i].min_value);
-        va_TraceMsg(idx, "\t  max_value = %d\n", attr_list[i].max_value);
-        va_TraceMsg(idx, "\t  value = %d\n", attr_list[i].value);
-        va_TraceMsg(idx, "\t  flags = %d\n", attr_list[i].flags);
+        va_TraceMsg(trace_ctx, "\tattr_list[%d] =\n");
+        va_TraceMsg(trace_ctx, "\t  typ = 0x%08x\n", attr_list[i].type);
+        va_TraceMsg(trace_ctx, "\t  min_value = %d\n", attr_list[i].min_value);
+        va_TraceMsg(trace_ctx, "\t  max_value = %d\n", attr_list[i].max_value);
+        va_TraceMsg(trace_ctx, "\t  value = %d\n", attr_list[i].value);
+        va_TraceMsg(trace_ctx, "\t  flags = %d\n", attr_list[i].flags);
     }
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 
 static void va_TraceDisplayAttributes (
     VADisplay dpy,
     VADisplayAttribute *attr_list,
-    int num_attributes
+    int __maybe_unused num_attributes
 )
 {
     int i;
     
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
     
-    va_TraceMsg(idx, "\tnum_attributes = %d\n", num_attributes);
+    if (attr_list == NULL)
+        return;
+    
     for (i=0; i<num_attributes; i++) {
-        va_TraceMsg(idx, "\tattr_list[%d] =\n");
-        va_TraceMsg(idx, "\t  typ = 0x%08x\n", attr_list[i].type);
-        va_TraceMsg(idx, "\t  min_value = %d\n", attr_list[i].min_value);
-        va_TraceMsg(idx, "\t  max_value = %d\n", attr_list[i].max_value);
-        va_TraceMsg(idx, "\t  value = %d\n", attr_list[i].value);
-        va_TraceMsg(idx, "\t  flags = %d\n", attr_list[i].flags);
+        va_TraceMsg(trace_ctx, "\tattr_list[%d] =\n");
+        va_TraceMsg(trace_ctx, "\t  typ = 0x%08x\n", attr_list[i].type);
+        va_TraceMsg(trace_ctx, "\t  min_value = %d\n", attr_list[i].min_value);
+        va_TraceMsg(trace_ctx, "\t  max_value = %d\n", attr_list[i].max_value);
+        va_TraceMsg(trace_ctx, "\t  value = %d\n", attr_list[i].value);
+        va_TraceMsg(trace_ctx, "\t  flags = %d\n", attr_list[i].flags);
     }
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, NULL);
 }
 
 
@@ -2357,7 +3330,7 @@
     int num_attributes
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
 
@@ -2370,7 +3343,7 @@
     int num_attributes
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
 
@@ -2395,22 +3368,22 @@
     unsigned int flags /* de-interlacing flags */
 )
 {
-    DPY2INDEX(dpy);
+    DPY2TRACECTX(dpy);
 
     TRACE_FUNCNAME(idx);
     
-    va_TraceMsg(idx, "\tsurface = 0x%08x\n", surface);
-    va_TraceMsg(idx, "\tdraw = 0x%08x\n", draw);
-    va_TraceMsg(idx, "\tsrcx = %d\n", srcx);
-    va_TraceMsg(idx, "\tsrcy = %d\n", srcy);
-    va_TraceMsg(idx, "\tsrcw = %d\n", srcw);
-    va_TraceMsg(idx, "\tsrch = %d\n", srch);
-    va_TraceMsg(idx, "\tdestx = %d\n", destx);
-    va_TraceMsg(idx, "\tdesty = %d\n", desty);
-    va_TraceMsg(idx, "\tdestw = %d\n", destw);
-    va_TraceMsg(idx, "\tdesth = %d\n", desth);
-    va_TraceMsg(idx, "\tcliprects = 0x%08x\n", cliprects);
-    va_TraceMsg(idx, "\tnumber_cliprects = %d\n", number_cliprects);
-    va_TraceMsg(idx, "\tflags = 0x%08x\n", flags);
-    va_TraceMsg(idx, NULL);
+    va_TraceMsg(trace_ctx, "\tsurface = 0x%08x\n", surface);
+    va_TraceMsg(trace_ctx, "\tdraw = 0x%08x\n", draw);
+    va_TraceMsg(trace_ctx, "\tsrcx = %d\n", srcx);
+    va_TraceMsg(trace_ctx, "\tsrcy = %d\n", srcy);
+    va_TraceMsg(trace_ctx, "\tsrcw = %d\n", srcw);
+    va_TraceMsg(trace_ctx, "\tsrch = %d\n", srch);
+    va_TraceMsg(trace_ctx, "\tdestx = %d\n", destx);
+    va_TraceMsg(trace_ctx, "\tdesty = %d\n", desty);
+    va_TraceMsg(trace_ctx, "\tdestw = %d\n", destw);
+    va_TraceMsg(trace_ctx, "\tdesth = %d\n", desth);
+    va_TraceMsg(trace_ctx, "\tcliprects = 0x%08x\n", cliprects);
+    va_TraceMsg(trace_ctx, "\tnumber_cliprects = %d\n", number_cliprects);
+    va_TraceMsg(trace_ctx, "\tflags = 0x%08x\n", flags);
+    va_TraceMsg(trace_ctx, NULL);
 }
diff --git a/va/va_trace.h b/va/va_trace.h
old mode 100755
new mode 100644
index 269bd75..b2182b0
--- a/va/va_trace.h
+++ b/va/va_trace.h
@@ -43,24 +43,18 @@
                                        VA_TRACE_FLAG_SURFACE_ENCODE | \
                                        VA_TRACE_FLAG_SURFACE_JPEG)
 
-#define VA_TRACE_FUNC(trace_func,...)           \
-    if (trace_flag) {                           \
-        trace_func(__VA_ARGS__);                \
-    }
 #define VA_TRACE_LOG(trace_func,...)            \
     if (trace_flag & VA_TRACE_FLAG_LOG) {       \
         trace_func(__VA_ARGS__);                \
     }
-#define VA_TRACE_SURFACE(trace_func,...)        \
-    if (trace_flag & (VA_TRACE_FLAG_LOG | VA_TRACE_FLAG_SURFACE | VA_TRACE_FLAG_CODEDBUF)) { \
-        trace_func(__VA_ARGS__);                                        \
+#define VA_TRACE_ALL(trace_func,...)            \
+    if (trace_flag) {                           \
+        trace_func(__VA_ARGS__);                \
     }
 
 void va_TraceInit(VADisplay dpy);
 void va_TraceEnd(VADisplay dpy);
 
-void va_TraceMsg(int idx, const char *msg, ...);
-
 void va_TraceInitialize (
     VADisplay dpy,
     int *major_version,	 /* out */
@@ -91,6 +85,12 @@
     unsigned int        num_attribs
 );
 
+void va_TraceDestroySurfaces(
+    VADisplay dpy,
+    VASurfaceID *surface_list,
+    int num_surfaces
+);
+    
 void va_TraceCreateContext(
     VADisplay dpy,
     VAConfigID config_id,
@@ -102,6 +102,20 @@
     VAContextID *context		/* out */
 );
 
+void va_TraceCreateBuffer (
+    VADisplay dpy,
+    VAContextID context,	/* in */
+    VABufferType type,		/* in */
+    unsigned int size,		/* in */
+    unsigned int num_elements,	/* in */
+    void *data,			/* in */
+    VABufferID *buf_id		/* out */
+);
+    
+void va_TraceDestroyBuffer (
+    VADisplay dpy,
+    VABufferID buf_id    /* in */
+);
 
 void va_TraceMapBuffer (
     VADisplay dpy,
@@ -134,6 +148,13 @@
     VASurfaceID render_target
 );
 
+void va_TraceQuerySurfaceAttributes(
+    VADisplay           dpy,
+    VAConfigID          config,
+    VASurfaceAttrib    *attrib_list,
+    unsigned int       *num_attribs
+);
+
 void va_TraceQuerySurfaceStatus(
     VADisplay dpy,
     VASurfaceID render_target,
diff --git a/va/va_vpp.h b/va/va_vpp.h
index 0d23cbf..4b4f648 100644
--- a/va/va_vpp.h
+++ b/va/va_vpp.h
@@ -236,27 +236,28 @@
 
 /** \brief Video filter types. */
 typedef enum _VAProcFilterType {
-    VAProcFilterNone                = 0,
-    /** \brief Dering filter. */
-    VAProcFilterDering              = 1,
-    /** \brief De-blocking filter. */
-    VAProcFilterDeblocking          = 2,
+    VAProcFilterNone = 0,
     /** \brief Noise reduction filter. */
-    VAProcFilterNoiseReduction      = 3,
+    VAProcFilterNoiseReduction,
     /** \brief Deinterlacing filter. */
-    VAProcFilterDeinterlacing       = 4,
+    VAProcFilterDeinterlacing,
     /** \brief Sharpening filter. */
-    VAProcFilterSharpening          = 5,
+    VAProcFilterSharpening,
     /** \brief Color balance parameters. */
-    VAProcFilterColorBalance        = 6,
-    /** \brief Color standard conversion. */
-    VAProcFilterColorStandard       = 7,
+    VAProcFilterColorBalance,
+    /** \brief Deblocking filter. */
+    VAProcFilterDeblocking,
+    /** \brief Frame rate conversion. */
+    VAProcFilterFrameRateConversion,
+    /** \brief Skin Tone Enhancement. */
+    VAProcFilterSkinToneEnhancement,
+    /** \brief Total Color Correction. */
+    VAProcFilterTotalColorCorrection,
+    /** \brief Non-Linear Anamorphic Scaling. */
+    VAProcFilterNonLinearAnamorphicScaling,
+    /** \brief Image Stabilization. */
+    VAProcFilterImageStabilization,
     /** \brief Number of video filters. */
-    VAProcFilterColorEnhancement    = 8,
-    VAProcFilterProcAmp             = 9,
-    VAProcFilterComposition         = 10,
-    /** \brief Frame rate convert filter. */
-    VAProcFilterFrameRateConversion = 11,
     VAProcFilterCount
 } VAProcFilterType;
 
@@ -313,10 +314,91 @@
     VAProcColorStandardSMPTE240M,
     /** \brief Generic film. */
     VAProcColorStandardGenericFilm,
+    /** \brief sRGB. */
+    VAProcColorStandardSRGB,
+    /** \brief stRGB. */
+    VAProcColorStandardSTRGB,
+    /** \brief xvYCC601. */
+    VAProcColorStandardXVYCC601,
+    /** \brief xvYCC709. */
+    VAProcColorStandardXVYCC709,
+    /** \brief ITU-R BT.2020. */
+    VAProcColorStandardBT2020,
     /** \brief Number of color standards. */
     VAProcColorStandardCount
 } VAProcColorStandardType;
 
+/** \brief Total color correction types. */
+typedef enum _VAProcTotalColorCorrectionType {
+    VAProcTotalColorCorrectionNone = 0,
+    /** \brief Red Saturation. */
+    VAProcTotalColorCorrectionRed,
+    /** \brief Green Saturation. */
+    VAProcTotalColorCorrectionGreen,
+    /** \brief Blue Saturation. */
+    VAProcTotalColorCorrectionBlue,
+    /** \brief Cyan Saturation. */
+    VAProcTotalColorCorrectionCyan,
+    /** \brief Magenta Saturation. */
+    VAProcTotalColorCorrectionMagenta,
+    /** \brief Yellow Saturation. */
+    VAProcTotalColorCorrectionYellow,
+    /** \brief Number of color correction attributes. */
+    VAProcTotalColorCorrectionCount
+} VAProcTotalColorCorrectionType;
+
+/** \brief ImageStabilization Types. */
+typedef enum _VAProcImageStabilizationType {
+    VAProcImageStabilizationTypeNone = 0,
+    /** \brief Mode Crop - crops the frame by the app provided percentage. */
+    VAProcImageStabilizationTypeCrop,
+    /** \brief Mode Crop Min Zoom - crops and then upscales the frame to half the black boundary. */
+    VAProcImageStabilizationTypeMinZoom,
+    /** \brief Mode Crop Full Zoom - crops and upscales the frame to original size. */
+    VAProcImageStabilizationTypeFullZoom,
+    /** \brief Number of Image Stabilization Type. */
+    VAProcImageStabilizationTypeCount
+} VAProcImageStabilizationType;
+
+/** @name Video blending flags */
+/**@{*/
+/** \brief Global alpha blending. */
+#define VA_BLEND_GLOBAL_ALPHA           0x0002
+/** \brief Premultiplied alpha blending (RGBA surfaces only). */
+#define VA_BLEND_PREMULTIPLIED_ALPHA    0x0008
+/** \brief Luma color key (YUV surfaces only). */
+#define VA_BLEND_LUMA_KEY               0x0010
+/**@}*/
+
+/** \brief Video blending state definition. */
+typedef struct _VABlendState {
+    /** \brief Video blending flags. */
+    unsigned int        flags;
+    /**
+     * \brief Global alpha value.
+     *
+     * Valid if \flags has VA_BLEND_GLOBAL_ALPHA.
+     * Valid range is 0.0 to 1.0 inclusive.
+     */
+    float               global_alpha;
+    /**
+     * \brief Minimum luma value.
+     *
+     * Valid if \flags has VA_BLEND_LUMA_KEY.
+     * Valid range is 0.0 to 1.0 inclusive.
+     * \ref min_luma shall be set to a sensible value lower than \ref max_luma.
+     */
+    float               min_luma;
+    /**
+     * \brief Maximum luma value.
+     *
+     * Valid if \flags has VA_BLEND_LUMA_KEY.
+     * Valid range is 0.0 to 1.0 inclusive.
+     * \ref max_luma shall be set to a sensible value larger than \ref min_luma.
+     */
+    float               max_luma;
+} VABlendState;
+
 /** @name Video pipeline flags */
 /**@{*/
 /** \brief Specifies whether to apply subpictures when processing a surface. */
@@ -343,13 +425,26 @@
 /** @name Pipeline end flags */
 /**@{*/
 /** \brief Specifies the pipeline is the last. */
-#define VA_PIPELINE_FLAG_END 0x8
+#define VA_PIPELINE_FLAG_END		0x00000004
+/**@}*/
+
+/** @name Chroma Siting flag */
+/**@{*/
+#define VA_CHROMA_SITING_UNKNOWN              0x00000000
+/** \brief Chroma samples are co-sited vertically on the top with the luma samples. */
+#define VA_CHROMA_SITING_VERTICAL_TOP         0x00000001
+/** \brief Chroma samples are not co-sited vertically with the luma samples. */
+#define VA_CHROMA_SITING_VERTICAL_CENTER      0x00000002
+/** \brief Chroma samples are co-sited vertically on the bottom with the luma samples. */
+#define VA_CHROMA_SITING_VERTICAL_BOTTOM      0x00000003
+/** \brief Chroma samples are co-sited horizontally on the left with the luma samples. */
+#define VA_CHROMA_SITING_HORIZONTAL_LEFT      0x00000004
+/** \brief Chroma samples are not co-sited horizontally with the luma samples. */
+#define VA_CHROMA_SITING_HORIZONTAL_CENTER    0x00000008
 /**@}*/
 
 /** \brief Video processing pipeline capabilities. */
 typedef struct _VAProcPipelineCaps {
-    /** \brief Video filter flags. See video pipeline flags. */
-    unsigned int        flags;
     /** \brief Pipeline flags. See VAProcPipelineParameterBuffer::pipeline_flags. */
     unsigned int        pipeline_flags;
     /** \brief Extra filter flags. See VAProcPipelineParameterBuffer::filter_flags. */
@@ -366,6 +461,45 @@
     VAProcColorStandardType *output_color_standards;
     /** \brief Number of elements in \ref output_color_standards array. */
     unsigned int        num_output_color_standards;
+    /**
+     * \brief Rotation flags.
+     *
+     * For each rotation angle supported by the underlying hardware,
+     * the corresponding bit is set in \ref rotation_flags. See
+     * "Rotation angles" for a description of rotation angles.
+     *
+     * A value of 0 means the underlying hardware does not support any
+     * rotation. Otherwise, a check for a specific rotation angle can be
+     * performed as follows:
+     *
+     * \code
+     * VAProcPipelineCaps pipeline_caps;
+     * ...
+     * vaQueryVideoProcPipelineCaps(va_dpy, vpp_ctx,
+     *     filter_bufs, num_filter_bufs,
+     *     &pipeline_caps
+     * );
+     * ...
+     * if (pipeline_caps.rotation_flags & (1 << VA_ROTATION_xxx)) {
+     *     // Clockwise rotation by xxx degrees is supported
+     *     ...
+     * }
+     * \endcode
+     */
+    unsigned int        rotation_flags;
+    /** \brief Blend flags. See "Video blending flags". */
+    unsigned int        blend_flags;
+    /**
+     * \brief Mirroring flags.
+     *
+     * For each mirroring direction supported by the underlying hardware,
+     * the corresponding bit is set in \ref mirror_flags. See
+     * "Mirroring directions" for a description of mirroring directions.
+     *
+     */
+    unsigned int        mirror_flags;
+    /** \brief Number of additional output surfaces supported by the pipeline  */
+    unsigned int        num_additional_outputs;
 } VAProcPipelineCaps;
 
 /** \brief Specification of values supported by the filter. */
@@ -487,10 +621,10 @@
      *   \c VA_BOTTOM_FIELD. Note that any deinterlacing filter
      *   (#VAProcFilterDeinterlacing) will override those flags.
      * - Color space conversion: \c VA_SRC_BT601, \c VA_SRC_BT709,
-     *   \c VA_SRC_SMPTE_240. Note that any color standard filter
-     *   (#VAProcFilterColorStandard) will override those flags.
+     *   \c VA_SRC_SMPTE_240. 
      * - Scaling: \c VA_FILTER_SCALING_DEFAULT, \c VA_FILTER_SCALING_FAST,
      *   \c VA_FILTER_SCALING_HQ, \c VA_FILTER_SCALING_NL_ANAMORPHIC.
+     * - Enable auto noise reduction: \c VA_FILTER_NOISEREDUCTION_AUTO.
      */
     unsigned int        filter_flags;
     /**
@@ -520,6 +654,76 @@
     VASurfaceID        *backward_references;
     /** \brief Number of backward reference frames that were supplied. */
     unsigned int        num_backward_references;
+    /**
+     * \brief Rotation state. See rotation angles.
+     *
+     * The rotation angle is clockwise. There is no specific rotation
+     * center for this operation. Rather, The source \ref surface is
+     * first rotated by the specified angle and then scaled to fit the
+     * \ref output_region.
+     *
+     * This means that the top-left hand corner (0,0) of the output
+     * (rotated) surface is expressed as follows:
+     * - \ref VA_ROTATION_NONE: (0,0) is the top left corner of the
+     *   source surface -- no rotation is performed ;
+     * - \ref VA_ROTATION_90: (0,0) is the bottom-left corner of the
+     *   source surface ;
+     * - \ref VA_ROTATION_180: (0,0) is the bottom-right corner of the
+     *   source surface -- the surface is flipped around the X axis ;
+     * - \ref VA_ROTATION_270: (0,0) is the top-right corner of the
+     *   source surface.
+     *
+     * Check VAProcPipelineCaps::rotation_flags first prior to
+     * defining a specific rotation angle. Otherwise, the hardware can
+     * perfectly ignore this variable if it does not support any
+     * rotation.
+     */
+    unsigned int        rotation_state;
+    /**
+     * \brief blending state. See "Video blending state definition".
+     *
+     * If \ref blend_state is NULL, then default operation mode depends
+     * on the source \ref surface format:
+     * - RGB: per-pixel alpha blending ;
+     * - YUV: no blending, i.e override the underlying pixels.
+     *
+     * Otherwise, \ref blend_state is a pointer to a #VABlendState
+     * structure that shall be live until vaEndPicture().
+     *
+     * Implementation note: the driver is responsible for checking the
+     * blend state flags against the actual source \ref surface format.
+     * e.g. premultiplied alpha blending is only applicable to RGB
+     * surfaces, and luma keying is only applicable to YUV surfaces.
+     * If a mismatch occurs, then #VA_STATUS_ERROR_INVALID_BLEND_STATE
+     * is returned.
+     */
+    const VABlendState *blend_state;
+    /**
+     * \bried mirroring state. See "Mirroring directions".
+     * 
+     * Mirroring of an image can be performed either along the 
+     * horizontal or vertical axis. It is assumed that the rotation
+     * operation is always performed before the mirroring operation.
+     */
+    unsigned int      mirror_state;
+    /** \brief Array of additional output surfaces. */
+    VASurfaceID        *additional_outputs;
+    /** \brief Number of additional output surfaces. */
+    unsigned int        num_additional_outputs;
+    /**
+     * \brief Flag to indicate the input surface flag such as chroma-siting,
+     * range flag and so on.
+     *
+     * The lower 4 bits are still used as chroma-siting flag
+     * The range_flag bit is used to indicate that the range flag of color-space conversion.
+     * -\ref VA_SOURCE_RANGE_FULL(Full range): Y/Cb/Cr is in [0, 255].It is
+     *   mainly used for JPEG/JFIF formats. The combination with the BT601 flag
+     *   means that JPEG/JFIF color-space conversion matrix is used.
+     * -\ref VA_SOURCE_RANGE_FULL(Reduced range): Y is in [16, 235] and Cb/Cr
+     *   is in [16, 240]. It is mainly used for the YUV<->RGB color-space
+     *   conversion in SDTV/HDTV/UHDTV.
+     */
+    unsigned int        input_surface_flag;
 } VAProcPipelineParameterBuffer;
 
 /**
@@ -547,12 +751,39 @@
     float               value;
 } VAProcFilterParameterBuffer;
 
+/** @name De-interlacing flags */
+/**@{*/
+/** 
+ * \brief Bottom field first in the input frame. 
+ * if this is not set then assumes top field first.
+ */
+#define VA_DEINTERLACING_BOTTOM_FIELD_FIRST	0x0001
+/** 
+ * \brief Bottom field used in deinterlacing. 
+ * if this is not set then assumes top field is used.
+ */
+#define VA_DEINTERLACING_BOTTOM_FIELD		0x0002
+/** 
+ * \brief A single field is stored in the input frame. 
+ * if this is not set then assumes the frame contains two interleaved fields.
+ */
+#define VA_DEINTERLACING_ONE_FIELD		0x0004
+/** 
+ * \brief Film Mode Detection is enabled. If enabled, driver performs inverse
+ * of various pulldowns, such as 3:2 pulldown.
+ * if this is not set then assumes FMD is disabled.
+ */
+#define VA_DEINTERLACING_FMD_ENABLE		0x0008
+/**@}*/
+
 /** \brief Deinterlacing filter parametrization. */
 typedef struct _VAProcFilterParameterBufferDeinterlacing {
     /** \brief Filter type. Shall be set to #VAProcFilterDeinterlacing. */
     VAProcFilterType            type;
     /** \brief Deinterlacing algorithm. */
     VAProcDeinterlacingType     algorithm;
+    /** \brief Deinterlacing flags. */
+    unsigned int     		flags;
 } VAProcFilterParameterBufferDeinterlacing;
 
 /**
@@ -616,31 +847,80 @@
     float                       value;
 } VAProcFilterParameterBufferColorBalance;
 
-/** \brief Color standard filter parametrization. */
-typedef struct _VAProcFilterParameterBufferColorStandard {
-    /** \brief Filter type. Shall be set to #VAProcFilterColorStandard. */
-    VAProcFilterType            type;
-    /** \brief Color standard to use. */
-    VAProcColorStandardType     standard;
-} VAProcFilterParameterBufferColorStandard;
+/** @name FRC Custom Rate types. */
+/**@{*/
+/** \brief 24p to 60p. */
+#define VA_FRAME_RATE_CONVERSION_24p_60p    0x0001
+/** \brief 30p to 60p. */
+#define VA_FRAME_RATE_CONVERSION_30p_60p    0x0002
+/**@}*/
 
 /** \brief Frame rate conversion filter parametrization. */
 typedef struct _VAProcFilterParamterBufferFrameRateConversion {
     /** \brief filter type. Shall be set to #VAProcFilterFrameRateConversion. */
-    VAProcFilterType            type;
+    VAProcFilterType                    type;
     /** \brief FPS of input sequence. */
-    unsigned int                input_fps;
+    unsigned int                        input_fps;
     /** \brief FPS of output sequence. */
-    unsigned int                output_fps;
-    /** \brief Number of output frames in addition to the first output frame. */
-    unsigned int num_output_frames;
+    unsigned int                        output_fps;
+    /** \brief Number of output frames in addition to the first output frame.
+        \brief If num_output_frames returned from pipeline query is 0,
+        \brief vaRenderPicture() will only produce one output frame with each call*/ 
+    unsigned int                        num_output_frames;
     /** 
      * \brief Array to store output frames in addition to the first one. 
-     * The first output frame is stored in the render target from vaBeginPicture(). 
-     */
-    VASurfaceID* output_frames;
+     * \brief The first output frame is stored in the render target from vaBeginPicture(). */
+    VASurfaceID*                        output_frames;   
+    /** \brief if frame repeat or not. 1: repeat 0: do not repeat */
+    unsigned int                        repeat_frame;  
+    /** \brief Counter within one complete FRC Cycle.
+        \brief The counter would run from 0 to 4 for 24to60p in each cycle.
+        \brief The counter would run from 0 to 1 for 30to60p in each cycle. */
+    unsigned int                        cyclic_counter;
 } VAProcFilterParameterBufferFrameRateConversion;
 
+/** \brief Total color correction filter parametrization. */
+typedef struct _VAProcFilterParameterBufferTotalColorCorrection {
+    /** \brief Filter type. Shall be set to #VAProcFilterTotalColorCorrection. */
+    VAProcFilterType                  type;
+    /** \brief Color to correct. */
+    VAProcTotalColorCorrectionType    attrib;
+    /** \brief Color correction value. */
+    float                             value;
+} VAProcFilterParameterBufferTotalColorCorrection;
+
+/** @name ImageStabilization Perf Types. */
+/**@{*/
+/** \brief Fast Mode. */
+#define VA_IMAGE_STABILIZATION_PERF_TYPE_FAST       0x0001
+ /** \brief Quality Mode. */
+#define VA_IMAGE_STABILIZATION_PERF_TYPE_QUALITY    0x0002
+/**@}*/
+
+/** \brief Image Stabilization filter parametrization. */
+typedef struct _VAProcFilterParameterBufferImageStabilization {
+    /** \brief Filter type. Shall be set to #VAProcFilterImageStabilization. */
+    VAProcFilterType                  type;
+    /** \brief Image Stabilization Mode. */
+    VAProcImageStabilizationType      mode;
+    /** \brief Image Stabilization Crop percentage. */
+    float                             crop;
+    /** \brief Image Stabilization Perf type. */
+    unsigned int                      perf_type;
+} VAProcFilterParameterBufferImageStabilization;
+
+/** \brief Non-Linear Anamorphic Scaling filter parametrization. */
+typedef struct _VAProcFilterParameterBufferNonLinearAnamorphicScaling {
+    /** \brief filter type. Shall be set to #VAProcFilterNonLinearAnamorphicScaling. */
+    VAProcFilterType    type;
+    /** \brief Vertical crop. */
+    float               vertical_crop;
+    /** \brief HLinear region. */
+    float               horizontal_linear_region;
+    /** \brief Non-linear crop. */
+    float               nonlinear_crop;
+} VAProcFilterParameterBufferNonLinearAnamorphicScaling;
+
 /**
  * \brief Default filter cap specification (single range value).
  *
@@ -666,20 +946,55 @@
     VAProcFilterValueRange      range;
 } VAProcFilterCapColorBalance;
 
-/** \brief Capabilities specification for the color standard filter. */
-typedef struct _VAProcFilterCapColorStandard {
-    /** \brief Color standard type. */
-    VAProcColorStandardType     type;
-} VAProcFilterCapColorStandard;
+/** \brief Capabilities specification for the Total Color Correction filter. */
+typedef struct _VAProcFilterCapTotalColorCorrection {
+    /** \brief Color to correct. */
+    VAProcTotalColorCorrectionType    type;
+    /** \brief Range of supported values for the specified color. */
+    VAProcFilterValueRange            range;
+} VAProcFilterCapTotalColorCorrection;
 
-/** \brief Capabilities specification for the amplifier filter. */
-typedef struct _VAProcFilterCapProcAmp
-{
-    VAProcFilterValueRange brightness_range;
-    VAProcFilterValueRange contrast_range;
-    VAProcFilterValueRange saturation_range;
-    VAProcFilterValueRange hue_range;
-} VAProcFilterCapProcAmp;
+/** \brief Capabilities specification for the Image Stabilization filter. */
+typedef struct _VAProcFilterCapImageStabilization {
+    /** \brief IS modes supported. */
+    VAProcImageStabilizationType       type[VAProcImageStabilizationTypeCount];
+    /** \brief Range of supported values for crop ratio. */
+    VAProcFilterValueRange             crop_range;
+    /** \brief Maximum number of forward reference frames supported. */
+    unsigned int                       max_forward_reference;
+    /** \brief Maximum number of IS perf modes supported. */
+    unsigned int                       perf_type;
+} VAProcFilterCapImageStabilization;
+
+/** \brief Capabilities specification for the Non-Linear Anamorphic Scaling filter. */
+typedef struct _VAProcFilterCapNonLinearAnamorphicScaling {
+    /** \brief Range of supported values for the vertical crop. */
+    VAProcFilterValueRange      vertical_crop_range;
+    /** \brief Range of supported values for the horizontal linear region. */
+    VAProcFilterValueRange      horizontal_linear_region_range;
+    /** \brief Range of supported values for the non-linear crop. */
+    VAProcFilterValueRange      nonlinear_crop_range;
+} VAProcFilterCapNonLinearAnamorphicScaling;
+
+/** \brief Capabilities specification for the Frame Rate Conversion filter. */
+typedef struct _VAProcFilterCapFrameRateConversion { 
+    /** \brief Should be set to 1 if only supported rates are requested.
+        \brief Set to 0 to get the rest of the caps for the particular custom rate */
+    unsigned int                        bget_custom_rates;
+    /** \brief FRC custom rates supported by the pipeline in the first query
+        \brief App request caps for a custom rate in the second query */
+    unsigned int                        frc_custom_rates;
+    /** \brief FPS of input sequence. */
+    unsigned int                        input_fps;
+    /** \brief FPS of output sequence. */
+    unsigned int                        output_fps;
+    /** \brief Number of input frames. */   
+    unsigned int                        input_frames;
+    /** \brief Number of output frames. */
+    unsigned int                        output_frames;
+   /** \brief Set to 1 if interlaced input is supoorted. */
+    unsigned int                        input_interlaced;
+} VAProcFilterCapFrameRateConversion;
 
 /**
  * \brief Queries video processing filters.
diff --git a/va/va_x11.h b/va/va_x11.h
index c6f9670..c9be38d 100644
--- a/va/va_x11.h
+++ b/va/va_x11.h
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
 #ifndef _VA_X11_H_
 #define _VA_X11_H_
 
diff --git a/va/vendor/intel/va_intel_fei.h b/va/vendor/intel/va_intel_fei.h
new file mode 100644
index 0000000..a036bea
--- /dev/null
+++ b/va/vendor/intel/va_intel_fei.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2007-2013 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file va_intel_fei.h
+ * \brief The Intel FEI (Flexible Encoding Infrastructure) encoding API
+ *
+ * This file contains the \ref api_intel_fei "Intel FEI (Flexible Encoding Infrastructure) encoding API".
+ */
+
+#ifndef VA_INTEL_FEI_H
+#define VA_INTEL_FEI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <va/va_enc.h>
+
+/**
+ * \defgroup api_intel_fei Intel FEI (Flexible Encoding Infrastructure) encoding API
+ *
+ * @{
+ */
+
+/** \brief FEI frame level control buffer for H.264 */
+typedef struct _VAEncMiscParameterFEIFrameControlH264Intel {
+    unsigned int function; /* one of the VAConfigAttribEncFunctionType values */   
+    /** \brief MB (16x16) control input surface. It is valid only when (mb_input | mb_size_ctrl) 
+     * is set to 1. The data in this buffer correspond to the input source. 16x16 MB is in raster scan order, 
+     * each MB control data structure is defined by VAEncFEIMBControlBufferH264. 
+     * Buffer size shall not be less than the number of 16x16 blocks multiplied by 
+     * sizeof(VAEncFEIMBControlBufferH264Intel). 
+     * Note: if mb_qp is set, VAEncQpBufferH264 is expected.
+     */
+    VASurfaceID       mb_ctrl;
+    /** \brief MV predictor. It is valid only when mv_predictor_enable is set to 1. 
+     * Each 16x16 block has one or more pair of motion vectors and the corresponding 
+     * reference indexes as defined by VAEncMVPredictorBufferH264. 16x16 block is in raster scan order. 
+     * Buffer size shall not be less than the number of 16x16 blocks multiplied by 
+     * sizeof(VAEncMVPredictorBufferH264). */
+    VASurfaceID       mv_predictor;
+
+    /** \brief number of MV predictors. It must not be greater than maximum supported MV predictor. */
+    unsigned int      num_mv_predictors;
+
+    /** \brief control parameters */
+    unsigned int      max_len_sp                : 8;     
+    unsigned int      len_sp                    : 8;     
+    unsigned int      reserved0	                : 16;    
+
+    unsigned int      sub_mb_part_mask          : 7;     
+    unsigned int      intra_part_mask           : 5;     
+    unsigned int      multi_pred_l0             : 1;     
+    unsigned int      multi_pred_l1             : 1;     
+    unsigned int      sub_pel_mode              : 2;     
+    unsigned int      inter_sad 	            : 2;
+    unsigned int      intra_sad                 : 2;     
+    unsigned int      distortion_type           : 1;     
+    unsigned int      repartition_check_enable  : 1;     
+    unsigned int      adaptive_search           : 1;     
+    unsigned int      mv_predictor_enable       : 1;     
+    unsigned int      mb_qp                     : 1;     
+    unsigned int      mb_input                  : 1;     
+    unsigned int      mb_size_ctrl              : 1;
+    unsigned int      reserved1	                : 5;    
+
+    unsigned int      ref_width                 : 8;     
+    unsigned int      ref_height                : 8;
+    unsigned int      search_window             : 3;     
+    unsigned int      reserved2                 : 13;
+} VAEncMiscParameterFEIFrameControlH264Intel;
+
+
+/** \brief FEI MB level control data structure */
+typedef struct _VAEncFEIMBControlH264Intel {
+    /** \brief when set, correposndent MB is coded as skip */
+    unsigned int force_to_skip       : 1;     
+    /** \brief when set, correposndent MB is coded as intra */
+    unsigned int force_to_intra      : 1;     
+    unsigned int reserved1           : 30;    
+
+    /** \brief when mb_size_ctrl is set, size here is used to budget accumulatively. Set to 0xFF if don't care. */
+    unsigned int max_size_in_word    : 8;     
+    unsigned int target_size_in_word : 8;     
+    unsigned int reserved2           : 16;    
+
+    unsigned int reserved3;    
+} VAEncFEIMBControlH264Intel;
+
+
+/** \brief Application can use this definition as reference to allocate the buffer 
+ * based on MaxNumPredictor returned from attribute VAConfigAttribEncMVPredictorsIntel query. 
+ **/
+typedef struct _VAEncMVPredictorH264Intel {
+    /** \brief Reference index corresponding to the entry of RefPicList0 & RefPicList1 in VAEncSliceParameterBufferH264. 
+     * Note that RefPicList0 & RefPicList1 needs to be the same for all slices. 
+     * ref_idx_l0_x : index to RefPicList0; ref_idx_l1_x : index to RefPicList1; x : 0 - MaxNumPredictor. 
+     **/
+    unsigned int ref_idx_l0_0 : 4;     
+    unsigned int ref_idx_l1_0 : 4;     
+    unsigned int ref_idx_l0_1 : 4;     
+    unsigned int ref_idx_l1_1 : 4;     
+    unsigned int ref_idx_l0_2 : 4;     
+    unsigned int ref_idx_l1_2 : 4;     
+    unsigned int ref_idx_l0_3 : 4;     
+    unsigned int ref_idx_l1_3 : 4;     
+    unsigned int reserved;
+    /** \brief MV. MaxNumPredictor must be the returned value from attribute VAConfigAttribEncMVPredictors query. 
+     * Even application doesn't use the maximum predictors, the VAEncMVPredictorH264 structure size 
+     * has to be defined as maximum so each MB can be at a fixed location. 
+     * Note that 0x8000 must be used for correspondent intra block. 
+     **/
+    struct _mv
+    {
+    /** \brief Motion vector corresponding to ref0x_index. 
+     * mv0[0] is horizontal motion vector and mv0[1] is vertical motion vector. */
+        short    mv0[2];
+    /** \brief Motion vector corresponding to ref1x_index. 
+     * mv1[0] is horizontal motion vector and mv1[1] is vertical motion vector. */
+        short    mv1[2];
+    } mv[4]; /* MaxNumPredictor is 4 */
+} VAEncMVPredictorH264Intel;
+
+
+/** \brief FEI output */
+/**
+ * Motion vector output is per 4x4 block. For each 4x4 block there is a pair of MVs 
+ * for RefPicList0 and RefPicList1 and each MV is 4 bytes including horizontal and vertical directions. 
+ * Depending on Subblock partition, for the shape that is not 4x4, the MV is replicated 
+ * so each 4x4 block has a pair of MVs. The 16x16 block has 32 MVs (128 bytes). 
+ * 0x8000 is used for correspondent intra block. The 16x16 block is in raster scan order, 
+ * within the 16x16 block, each 4x4 block MV is ordered as below in memory. 
+ * The buffer size shall be greater than or equal to the number of 16x16 blocks multiplied by 128 bytes. 
+ * Note that, when separate ENC and PAK is enabled, the exact layout of this buffer is needed for PAK input. 
+ * App can reuse this buffer, or copy to a different buffer as PAK input. 
+ *                      16x16 Block        
+ *        -----------------------------------------
+ *        |    1    |    2    |    5    |    6    |
+ *        -----------------------------------------
+ *        |    3    |    4    |    7    |    8    |
+ *        -----------------------------------------
+ *        |    9    |    10   |    13   |    14   |
+ *        -----------------------------------------
+ *        |    11   |    12   |    15   |    16   |
+ *        -----------------------------------------
+ **/
+
+/** \brief VAEncFEIModeBufferIntel defines the data structure for VAEncFEIModeBufferTypeIntel per 16x16 MB block. 
+ * The 16x16 block is in raster scan order. Buffer size shall not be less than the number of 16x16 blocks 
+ * multiplied by sizeof(VAEncFEIModeBufferH264Intel). Note that, when separate ENC and PAK is enabled, 
+ * the exact layout of this buffer is needed for PAK input. App can reuse this buffer, 
+ * or copy to a different buffer as PAK input, reserved elements must not be modified when used as PAK input. 
+ **/
+typedef struct _VAEncFEIModeBufferH264Intel {
+    unsigned int    reserved0;
+    unsigned int    reserved1[3];
+
+    unsigned int    inter_mb_mode            : 2;
+    unsigned int    mb_skip_flag             : 1;
+    unsigned int    reserved00               : 1; 
+    unsigned int    intra_mb_mode            : 2;
+    unsigned int    reserved01               : 1; 
+    unsigned int    field_mb_polarity_flag   : 1;
+    unsigned int    mb_type                  : 5;
+    unsigned int    intra_mb_flag	         : 1;
+    unsigned int    field_mb_flag            : 1;
+    unsigned int    transform8x8_flag        : 1;
+    unsigned int    reserved02               : 1; 
+    unsigned int    dc_block_coded_cr_flag   : 1;
+    unsigned int    dc_block_coded_cb_flag   : 1;
+    unsigned int    dc_block_coded_y_flag    : 1;
+    unsigned int    reserved03               : 12; 
+
+    unsigned int    horz_origin              : 8;
+    unsigned int    vert_origin              : 8;
+    unsigned int    cbp_y                    : 16;
+
+    unsigned int    cbp_cb                   : 16;
+    unsigned int    cbp_cr                   : 16;
+
+    unsigned int    qp_prime_y               : 8;
+    unsigned int    reserved30               : 17; 
+    unsigned int    mb_skip_conv_disable     : 1;
+    unsigned int    is_last_mb               : 1;
+    unsigned int    enable_coefficient_clamp : 1; 
+    unsigned int    direct8x8_pattern        : 4;
+ 
+    union 
+    {
+        /* Intra MBs */
+        struct 
+        {
+            unsigned int   luma_intra_pred_modes0 : 16;
+            unsigned int   luma_intra_pred_modes1 : 16;
+
+            unsigned int   luma_intra_pred_modes2 : 16;
+            unsigned int   luma_intra_pred_modes3 : 16;
+
+            unsigned int   mb_intra_struct        : 8; 
+            unsigned int   reserved60             : 24; 
+        } intra_mb;
+
+        /* Inter MBs */
+        struct 
+        {
+            unsigned int   sub_mb_shapes          : 8; 
+            unsigned int   sub_mb_pred_modes      : 8;
+            unsigned int   reserved40             : 16; 
+ 
+            unsigned int   ref_idx_l0_0           : 8; 
+            unsigned int   ref_idx_l0_1           : 8; 
+            unsigned int   ref_idx_l0_2           : 8; 
+            unsigned int   ref_idx_l0_3           : 8; 
+
+            unsigned int   ref_idx_l1_0           : 8; 
+            unsigned int   ref_idx_l1_1           : 8; 
+            unsigned int   ref_idx_l1_2           : 8; 
+            unsigned int   ref_idx_l1_3           : 8; 
+        } inter_mb;
+    } mb_mode;
+
+    unsigned int   reserved70                : 16; 
+    unsigned int   target_size_in_word       : 8;
+    unsigned int   max_size_in_word          : 8; 
+
+    unsigned int   reserved2[4];
+} VAEncFEIModeBufferH264Intel;
+
+/** \brief VAEncFEIDistortionBufferIntel defines the data structure for 
+ * VAEncFEIDistortionBufferType per 16x16 MB block. The 16x16 block is in raster scan order. 
+ * Buffer size shall not be less than the number of 16x16 blocks multiple by sizeof(VAEncFEIDistortionBufferIntel). 
+ **/
+typedef struct _VAEncFEIDistortionBufferH264Intel {
+    /** \brief Inter-prediction-distortion associated with motion vector i (co-located with subblock_4x4_i). 
+     * Its meaning is determined by sub-shape. It must be zero if the corresponding sub-shape is not chosen. 
+     **/
+    unsigned short  inter_distortion[16];
+    unsigned short  best_inter_distortion;
+    unsigned short  best_intra_distortion;
+} VAEncFEIDistortionBufferH264Intel;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_INTEL_FEI_H */
diff --git a/va/vendor/intel/va_intel_statistics.h b/va/vendor/intel/va_intel_statistics.h
new file mode 100644
index 0000000..8b326e1
--- /dev/null
+++ b/va/vendor/intel/va_intel_statistics.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file va_intel_statistics.h
+ * \brief the Intel statistics API
+ *
+*/
+
+#ifndef VA_INTEL_STATISTICS_H
+#define VA_INTEL_STATISTICS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \brief Processing function for getting motion vectors and statistics. */
+
+/** This processing function can output motion vectors, distortions (pure pixel distortion, no cost), 
+ * number of non-zero coefficients, MB variance and MB pixel average.  
+ * The purpose is to assist application to perform SCD, complexity analysis, segmentation, BRC, etc. 
+ **/
+
+
+/** \brief Motion Vector and Statistics frame level controls. 
+ * VAStatsStatisticsParameterBufferTypeIntel for 16x16 block
+ **/
+typedef struct _VAStatsStatisticsParameter16x16Intel 
+{
+    /** \brief Source surface ID.  */
+    VASurfaceID     input;
+
+    VASurfaceID     *past_references;
+    unsigned int    num_past_references;
+    VASurfaceID     *future_references;
+    unsigned int    num_future_references;
+
+    /** \brief ID of the output surface. 
+     * The number of outputs is determined by below DisableMVOutput and DisableStatisticsOutput. 
+     * The output layout is defined by VAStatsStatisticsBufferType and VAStatsMotionVectorBufferType. 
+     **/
+    VASurfaceID     *outputs;
+
+    /** \brief MV predictor. It is valid only when mv_predictor_ctrl is not 0. 
+     * Each 16x16 block has a pair of MVs, one for past and one for future reference 
+     * as defined by VAMotionVector. The 16x16 block is in raster scan order. 
+     * Buffer size shall not be less than the number of 16x16 blocks multiplied by sizeof(VAMotionVector). 
+     **/
+    VASurfaceID     mv_predictor;
+
+    /** \brief Qp input surface. It is valid only when mb_qp is set to 1. 
+     * The data in this buffer correspond to the input source. 
+     * One Qp per 16x16 block in raster scan order, each Qp is a signed char (8-bit) value. 
+     **/
+    VASurfaceID     qp;
+
+    unsigned int    frame_qp                    : 8;     
+    unsigned int    len_sp                      : 8;     
+    unsigned int    max_len_sp                  : 8;     
+    unsigned int    reserved0                   : 8;     
+
+    unsigned int    sub_mb_part_mask            : 7;     
+    unsigned int    sub_pel_mode                : 2;     
+    unsigned int    inter_sad                   : 2;     
+    unsigned int    intra_sad                   : 2;     
+    unsigned int    adaptive_search	            : 1;     
+    /** \brief indicate if future or/and past MV in mv_predictor buffer is valid. 
+     * 0: MV predictor disabled
+     * 1: MV predictor enabled for past reference
+     * 2: MV predictor enabled for future reference
+     * 3: MV predictor enabled for both past and future references
+     **/
+    unsigned int    mv_predictor_ctrl           : 3;     
+    unsigned int    mb_qp                       : 1;     
+    unsigned int    ft_enable                   : 1;
+    unsigned int    reserved1                   : 13;    
+
+    unsigned int    ref_width                   : 8;     
+    unsigned int    ref_height                  : 8;
+    unsigned int    search_window               : 3;     
+    unsigned int    reserved2                   : 13;    
+
+    /** \brief MVOutput. When set to 1, MV output is NOT provided */
+    unsigned int	disable_mv_output           : 1;    
+    /** \brief StatisticsOutput. When set to 1, Statistics output is NOT provided. */
+    unsigned int    disable_statistics_output   : 1;    
+    unsigned int    reserved3                   : 30;    
+
+} VAStatsStatisticsParameter16x16Intel;
+
+/** \brief VAStatsMotionVectorBufferTypeIntel. Motion vector buffer layout.
+ * Motion vector output is per 4x4 block. For each 4x4 block there is a pair of past and future 
+ * reference MVs as defined in VAMotionVector. Depending on Subblock partition, 
+ * for the shape that is not 4x4, the MV is replicated so each 4x4 block has a pair of MVs. 
+ * If only past reference is used, future MV should be ignored, and vice versa. 
+ * The 16x16 block is in raster scan order, within the 16x16 block, each 4x4 block MV is ordered as below in memory. 
+ * The buffer size shall be greater than or equal to the number of 16x16 blocks multiplied by (sizeof(VAMotionVector) * 16).
+ *
+ *                      16x16 Block        
+ *        -----------------------------------------
+ *        |    1    |    2    |    5    |    6    |
+ *        -----------------------------------------
+ *        |    3    |    4    |    7    |    8    |
+ *        -----------------------------------------
+ *        |    9    |    10   |    13   |    14   |
+ *        -----------------------------------------
+ *        |    11   |    12   |    15   |    16   |
+ *        -----------------------------------------
+ *
+ **/
+
+/** \brief VAStatsStatisticsBufferTypeIntel. Statistics buffer layout.
+ * Statistics output is per 16x16 block. Data structure per 16x16 block is defined below. 
+ * The 16x16 block is in raster scan order. The buffer size shall be greater than or equal to 
+ * the number of 16x16 blocks multiplied by sizeof(VAStatsStatistics16x16Intel). 
+ **/
+typedef struct _VAStatsStatistics16x16Intel 
+{
+    /** \brief past reference  */
+    unsigned int    best_inter_distortion0 : 16;     
+    unsigned int    inter_mode0            : 16;     
+
+    /** \brief future reference  */
+    unsigned int    best_inter_distortion1 : 16;     
+    unsigned int    inter_mode1            : 16;     
+
+    unsigned int    best_intra_distortion  : 16;     
+    unsigned int    intra_mode             : 16;     
+
+    unsigned int    num_non_zero_coef      : 16;     
+    unsigned int    reserved               : 16;     
+
+    unsigned int    sum_coef; 
+
+    unsigned int    variance;     
+    unsigned int    pixel_average;
+} VAStatsStatistics16x16Intel;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_INTEL_STATISTICS_H */
diff --git a/va/wayland/Makefile.am b/va/wayland/Makefile.am
new file mode 100644
index 0000000..a9f9546
--- /dev/null
+++ b/va/wayland/Makefile.am
@@ -0,0 +1,66 @@
+# Copyright (C) 2012 Intel Corporation. All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sub license, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+# 
+# The above copyright notice and this permission notice (including the
+# next paragraph) shall be included in all copies or substantial portions
+# of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+SUBDIRS = protocol
+
+INCLUDES = \
+	-DLINUX			\
+	-I$(top_srcdir)		\
+	-I$(top_srcdir)/va	\
+	$(WAYLAND_CFLAGS)	\
+	$(DRM_CFLAGS)		\
+	$(NULL)
+
+source_c = \
+	va_wayland.c		\
+	va_wayland_drm.c	\
+	va_wayland_emgd.c	\
+	$(top_srcdir)/va/drm/va_drm_utils.c \
+	$(NULL)
+
+source_h = \
+	va_backend_wayland.h	\
+	va_wayland.h		\
+	$(NULL)
+
+source_h_priv = \
+	va_wayland_drm.h	\
+	va_wayland_emgd.h	\
+	va_wayland_private.h	\
+	$(NULL)
+
+protocol_source_h = \
+	wayland-drm-client-protocol.h	\
+	$(NULL)
+
+noinst_LTLIBRARIES		= libva_wayland.la
+libva_waylandincludedir		= ${includedir}/va
+libva_waylandinclude_HEADERS	= $(source_h)
+libva_wayland_la_SOURCES	= $(source_c) $(protocol_source_h)
+noinst_HEADERS			= $(source_h_priv)
+
+# Wayland protocol
+va_wayland_drm.c: $(protocol_source_h)
+@wayland_scanner_rules@
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/va/android/Makefile.am b/va/wayland/protocol/Makefile.am
similarity index 77%
rename from va/android/Makefile.am
rename to va/wayland/protocol/Makefile.am
index 8e532ac..614d8a4 100644
--- a/va/android/Makefile.am
+++ b/va/wayland/protocol/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 Intel Corporation. All Rights Reserved.
+# Copyright (C) 2012 Intel Corporation. All Rights Reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the
@@ -20,13 +20,9 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-AM_CFLAGS = -DLINUX -I$(top_srcdir)/va -I$(top_srcdir)/va/x11 $(DRM_CFLAGS)
+EXTRA_DIST = \
+	wayland-drm.xml		\
+	$(NULL)
 
-noinst_LTLIBRARIES = libva_dummy.la	
-
-libva_dummy_la_LIBADD = $(LIBVA_LIBS) -ldl -ludev
-
-libva_dummyincludedir = ${includedir}/va
-
-libva_dummy_la_SOURCES = va_dummy.c drmtest.c
-
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/va/wayland/protocol/wayland-drm.xml b/va/wayland/protocol/wayland-drm.xml
new file mode 100644
index 0000000..265d4f8
--- /dev/null
+++ b/va/wayland/protocol/wayland-drm.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="drm">
+
+  <copyright>
+    Copyright © 2008-2011 Kristian Høgsberg
+    Copyright © 2010-2011 Intel Corporation
+
+    Permission to use, copy, modify, distribute, and sell this
+    software and its documentation for any purpose is hereby granted
+    without fee, provided that\n the above copyright notice appear in
+    all copies and that both that copyright notice and this permission
+    notice appear in supporting documentation, and that the name of
+    the copyright holders not be used in advertising or publicity
+    pertaining to distribution of the software without specific,
+    written prior permission.  The copyright holders make no
+    representations about the suitability of this software for any
+    purpose.  It is provided "as is" without express or implied
+    warranty.
+
+    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+    THIS SOFTWARE.
+  </copyright>
+
+  <!-- drm support. This object is created by the server and published
+       using the display's global event. -->
+  <interface name="wl_drm" version="1">
+    <enum name="error">
+      <entry name="authenticate_fail" value="0"/>
+      <entry name="invalid_format" value="1"/>
+      <entry name="invalid_name" value="2"/>
+    </enum>
+
+    <enum name="format">
+      <!-- The drm format codes match the #defines in drm_fourcc.h.
+           The formats actually supported by the compositor will be
+           reported by the format event. -->
+      <entry name="c8" value="0x20203843"/>
+      <entry name="rgb332" value="0x38424752"/>
+      <entry name="bgr233" value="0x38524742"/>
+      <entry name="xrgb4444" value="0x32315258"/>
+      <entry name="xbgr4444" value="0x32314258"/>
+      <entry name="rgbx4444" value="0x32315852"/>
+      <entry name="bgrx4444" value="0x32315842"/>
+      <entry name="argb4444" value="0x32315241"/>
+      <entry name="abgr4444" value="0x32314241"/>
+      <entry name="rgba4444" value="0x32314152"/>
+      <entry name="bgra4444" value="0x32314142"/>
+      <entry name="xrgb1555" value="0x35315258"/>
+      <entry name="xbgr1555" value="0x35314258"/>
+      <entry name="rgbx5551" value="0x35315852"/>
+      <entry name="bgrx5551" value="0x35315842"/>
+      <entry name="argb1555" value="0x35315241"/>
+      <entry name="abgr1555" value="0x35314241"/>
+      <entry name="rgba5551" value="0x35314152"/>
+      <entry name="bgra5551" value="0x35314142"/>
+      <entry name="rgb565" value="0x36314752"/>
+      <entry name="bgr565" value="0x36314742"/>
+      <entry name="rgb888" value="0x34324752"/>
+      <entry name="bgr888" value="0x34324742"/>
+      <entry name="xrgb8888" value="0x34325258"/>
+      <entry name="xbgr8888" value="0x34324258"/>
+      <entry name="rgbx8888" value="0x34325852"/>
+      <entry name="bgrx8888" value="0x34325842"/>
+      <entry name="argb8888" value="0x34325241"/>
+      <entry name="abgr8888" value="0x34324241"/>
+      <entry name="rgba8888" value="0x34324152"/>
+      <entry name="bgra8888" value="0x34324142"/>
+      <entry name="xrgb2101010" value="0x30335258"/>
+      <entry name="xbgr2101010" value="0x30334258"/>
+      <entry name="rgbx1010102" value="0x30335852"/>
+      <entry name="bgrx1010102" value="0x30335842"/>
+      <entry name="argb2101010" value="0x30335241"/>
+      <entry name="abgr2101010" value="0x30334241"/>
+      <entry name="rgba1010102" value="0x30334152"/>
+      <entry name="bgra1010102" value="0x30334142"/>
+      <entry name="yuyv" value="0x56595559"/>
+      <entry name="yvyu" value="0x55595659"/>
+      <entry name="uyvy" value="0x59565955"/>
+      <entry name="vyuy" value="0x59555956"/>
+      <entry name="ayuv" value="0x56555941"/>
+      <entry name="nv12" value="0x3231564e"/>
+      <entry name="nv21" value="0x3132564e"/>
+      <entry name="nv16" value="0x3631564e"/>
+      <entry name="nv61" value="0x3136564e"/>
+      <entry name="yuv410" value="0x39565559"/>
+      <entry name="yvu410" value="0x39555659"/>
+      <entry name="yuv411" value="0x31315559"/>
+      <entry name="yvu411" value="0x31315659"/>
+      <entry name="yuv420" value="0x32315559"/>
+      <entry name="yvu420" value="0x32315659"/>
+      <entry name="yuv422" value="0x36315559"/>
+      <entry name="yvu422" value="0x36315659"/>
+      <entry name="yuv444" value="0x34325559"/>
+      <entry name="yvu444" value="0x34325659"/>
+    </enum>
+
+    <!-- Call this request with the magic received from drmGetMagic().
+         It will be passed on to the drmAuthMagic() or
+         DRIAuthConnection() call.  This authentication must be
+         completed before create_buffer could be used. -->
+    <request name="authenticate">
+      <arg name="id" type="uint"/>
+    </request>
+
+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
+         surface must have a name using the flink ioctl -->
+    <request name="create_buffer">
+      <arg name="id" type="new_id" interface="wl_buffer"/>
+      <arg name="name" type="uint"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+      <arg name="stride" type="uint"/>
+      <arg name="format" type="uint"/>
+    </request>
+
+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
+         surface must have a name using the flink ioctl -->
+    <request name="create_planar_buffer">
+      <arg name="id" type="new_id" interface="wl_buffer"/>
+      <arg name="name" type="uint"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+      <arg name="format" type="uint"/>
+      <arg name="offset0" type="int"/>
+      <arg name="stride0" type="int"/>
+      <arg name="offset1" type="int"/>
+      <arg name="stride1" type="int"/>
+      <arg name="offset2" type="int"/>
+      <arg name="stride2" type="int"/>
+    </request>
+
+    <!-- Notification of the path of the drm device which is used by
+         the server.  The client should use this device for creating
+         local buffers.  Only buffers created from this device should
+         be be passed to the server using this drm object's
+         create_buffer request. -->
+    <event name="device">
+      <arg name="name" type="string"/>
+    </event>
+
+    <event name="format">
+      <arg name="format" type="uint"/>
+    </event>
+
+    <!-- Raised if the authenticate request succeeded -->
+    <event name="authenticated"/>
+  </interface>
+
+</protocol>
diff --git a/va/wayland/va_backend_wayland.h b/va/wayland/va_backend_wayland.h
new file mode 100644
index 0000000..b33e3a1
--- /dev/null
+++ b/va/wayland/va_backend_wayland.h
@@ -0,0 +1,65 @@
+/*
+ * va_backend_wayland.h - VA driver implementation hooks for Wayland
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_BACKEND_WAYLAND_H
+#define VA_BACKEND_WAYLAND_H
+
+#include <va/va.h>
+#include <wayland-client.h>
+
+/** \brief VA/Wayland API version. */
+#define VA_WAYLAND_API_VERSION  (0x574c4400) /* WLD0 */
+
+/* Forward declarations */
+struct VADriverContext;
+
+/** \brief VA/Wayland implementation hooks. */
+struct VADriverVTableWayland {
+    /**
+     * \brief Interface version.
+     *
+     * Implementations shall set this field to \ref VA_WAYLAND_API_VERSION.
+     */
+    unsigned int version;
+
+    /** \brief Hook to return Wayland buffer associated with the VA surface. */
+    VAStatus (*vaGetSurfaceBufferWl)(
+        struct VADriverContext *ctx,
+        VASurfaceID             surface,
+        unsigned int            flags,
+        struct wl_buffer      **out_buffer
+    );
+
+    /** \brief Hook to return Wayland buffer associated with the VA image. */
+    VAStatus (*vaGetImageBufferWl)(
+        struct VADriverContext *ctx,
+        VAImageID               image,
+        unsigned int            flags,
+        struct wl_buffer      **out_buffer
+    );
+};
+
+#endif /* VA_BACKEND_WAYLAND_H */
diff --git a/va/wayland/va_wayland.c b/va/wayland/va_wayland.c
new file mode 100644
index 0000000..88a841f
--- /dev/null
+++ b/va/wayland/va_wayland.c
@@ -0,0 +1,194 @@
+/*
+ * va_wayland.c - Wayland API
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "sysdeps.h"
+#include <stdarg.h>
+#include "va_wayland.h"
+#include "va_wayland_drm.h"
+#include "va_wayland_emgd.h"
+#include "va_wayland_private.h"
+#include "va_backend.h"
+#include "va_backend_wayland.h"
+
+static inline VADriverContextP
+get_driver_context(VADisplay dpy)
+{
+    if (!vaDisplayIsValid(dpy))
+        return NULL;
+    return ((VADisplayContextP)dpy)->pDriverContext;
+}
+
+void
+va_wayland_error(const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+    fprintf(stderr, "VA error: wayland: ");
+    vfprintf(stderr, format, args);
+    fprintf(stderr, "\n");
+    va_end(args);
+}
+
+static int
+va_DisplayContextIsValid(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP const pDriverContext = pDisplayContext->pDriverContext;
+
+    return (pDriverContext &&
+            pDriverContext->display_type == VA_DISPLAY_WAYLAND);
+}
+
+static void
+va_DisplayContextDestroy(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP pDriverContext;
+    VADisplayContextWaylandP pDisplayContextWl;
+
+    if (!pDisplayContext)
+        return;
+
+    pDisplayContextWl = pDisplayContext->opaque;
+    if (pDisplayContextWl && pDisplayContextWl->destroy)
+        pDisplayContextWl->destroy(pDisplayContext);
+
+    pDriverContext = pDisplayContext->pDriverContext;
+    if (pDriverContext) {
+        free(pDriverContext->vtable_wayland);
+        pDriverContext->vtable_wayland = NULL;
+        free(pDriverContext);
+        pDisplayContext->pDriverContext = NULL;
+    }
+
+    free(pDisplayContext->opaque);
+    pDisplayContext->opaque = NULL;
+    free(pDisplayContext);
+}
+
+static VAStatus
+va_DisplayContextGetDriverName(VADisplayContextP pDisplayContext, char **name)
+{
+    *name = NULL;
+    return VA_STATUS_ERROR_UNKNOWN;
+}
+
+/* -------------------------------------------------------------------------- */
+/* --- Public interface                                                   --- */
+/* -------------------------------------------------------------------------- */
+
+struct va_wayland_backend {
+    VADisplayContextCreateFunc  create;
+    VADisplayContextDestroyFunc destroy;
+};
+
+static const struct va_wayland_backend g_backends[] = {
+    { va_wayland_drm_create,
+      va_wayland_drm_destroy },
+    { va_wayland_emgd_create,
+      va_wayland_emgd_destroy },
+    { NULL, }
+};
+
+VADisplay
+vaGetDisplayWl(struct wl_display *display)
+{
+    VADisplayContextP pDisplayContext = NULL;
+    VADriverContextP pDriverContext;
+    struct VADriverVTableWayland *vtable;
+    unsigned int i;
+
+    pDisplayContext = calloc(1, sizeof(*pDisplayContext));
+    if (!pDisplayContext)
+        return NULL;
+
+    pDisplayContext->vadpy_magic        = VA_DISPLAY_MAGIC;
+    pDisplayContext->vaIsValid          = va_DisplayContextIsValid;
+    pDisplayContext->vaDestroy          = va_DisplayContextDestroy;
+    pDisplayContext->vaGetDriverName    = va_DisplayContextGetDriverName;
+
+    pDriverContext = calloc(1, sizeof(*pDriverContext));
+    if (!pDriverContext)
+        goto error;
+    pDisplayContext->pDriverContext     = pDriverContext;
+
+    pDriverContext->native_dpy          = display;
+    pDriverContext->display_type        = VA_DISPLAY_WAYLAND;
+
+    vtable = calloc(1, sizeof(*vtable));
+    if (!vtable)
+        goto error;
+    pDriverContext->vtable_wayland      = vtable;
+
+    vtable->version                     = VA_WAYLAND_API_VERSION;
+
+    for (i = 0; g_backends[i].create != NULL; i++) {
+        if (g_backends[i].create(pDisplayContext))
+            break;
+        g_backends[i].destroy(pDisplayContext);
+    }
+
+    return (VADisplay)pDisplayContext;
+
+error:
+    va_DisplayContextDestroy(pDisplayContext);
+    return NULL;
+}
+
+VAStatus
+vaGetSurfaceBufferWl(
+    VADisplay           dpy,
+    VASurfaceID         surface,
+    unsigned int        flags,
+    struct wl_buffer  **out_buffer
+)
+{
+    VADriverContextP const ctx = get_driver_context(dpy);
+
+    if (!ctx)
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+    if (!ctx->vtable_wayland || !ctx->vtable_wayland->vaGetSurfaceBufferWl)
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+    return ctx->vtable_wayland->vaGetSurfaceBufferWl(ctx, surface, flags,
+                                                     out_buffer);
+}
+
+VAStatus
+vaGetImageBufferWl(
+    VADisplay           dpy,
+    VAImageID           image,
+    unsigned int        flags,
+    struct wl_buffer  **out_buffer
+)
+{
+    VADriverContextP const ctx = get_driver_context(dpy);
+
+    if (!ctx)
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+    if (!ctx->vtable_wayland || !ctx->vtable_wayland->vaGetImageBufferWl)
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+    return ctx->vtable_wayland->vaGetImageBufferWl(ctx, image, flags,
+                                                   out_buffer);
+}
diff --git a/va/wayland/va_wayland.h b/va/wayland/va_wayland.h
new file mode 100644
index 0000000..46fbf2c
--- /dev/null
+++ b/va/wayland/va_wayland.h
@@ -0,0 +1,131 @@
+/*
+ * va_wayland.h - Wayland API
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_WAYLAND_H
+#define VA_WAYLAND_H
+
+#include <va/va.h>
+#include <wayland-client.h>
+
+/**
+ * \file va_wayland.h
+ * \brief The Wayland rendering API
+ *
+ * This file contains the \ref api_wayland "Wayland rendering API".
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup api_wayland Wayland rendering API
+ *
+ * @{
+ *
+ * Theory of operations:
+ * - Create a VA display for an active Wayland display ;
+ * - Perform normal VA-API operations, e.g. decode to a VA surface ;
+ * - Get wl_buffer associated to the VA surface ;
+ * - Attach wl_buffer to wl_surface ;
+ */
+
+/**
+ * \brief Returns a VA display wrapping the specified Wayland display.
+ *
+ * This functions returns a (possibly cached) VA display from the
+ * specified Wayland @display.
+ *
+ * @param[in]   display         the native Wayland display
+ * @return the VA display
+ */
+VADisplay
+vaGetDisplayWl(struct wl_display *display);
+
+/**
+ * \brief Returns the Wayland buffer associated with a VA surface.
+ *
+ * This function returns a wl_buffer handle that can be used as an
+ * argument to wl_surface_attach(). This buffer references the
+ * underlying VA @surface. As such, the VA @surface and Wayland
+ * @out_buffer have the same size and color format. Should specific
+ * color conversion be needed, then VA/VPP API can fulfill this
+ * purpose.
+ *
+ * The @flags describe the desired picture structure. This is useful
+ * to expose a de-interlaced buffer. If the VA driver does not support
+ * any of the supplied flags, then #VA_STATUS_ERROR_FLAG_NOT_SUPPORTED
+ * is returned. The following flags are allowed: \c VA_FRAME_PICTURE,
+ * \c VA_TOP_FIELD, \c VA_BOTTOM_FIELD.
+ *
+ * @param[in]   dpy         the VA display
+ * @param[in]   surface     the VA surface
+ * @param[in]   flags       the deinterlacing flags
+ * @param[out]  out_buffer  a wl_buffer wrapping the VA @surface
+ * @return VA_STATUS_SUCCESS if successful
+ */
+VAStatus
+vaGetSurfaceBufferWl(
+    VADisplay           dpy,
+    VASurfaceID         surface,
+    unsigned int        flags,
+    struct wl_buffer  **out_buffer
+);
+
+/**
+ * \brief Returns the Wayland buffer associated with a VA image.
+ *
+ * This function returns a wl_buffer handle that can be used as an
+ * argument to wl_surface_attach(). This buffer references the
+ * underlying VA @image. As such, the VA @image and Wayland
+ * @out_buffer have the same size and color format. Should specific
+ * color conversion be needed, then VA/VPP API can fulfill this
+ * purpose.
+ *
+ * The @flags describe the desired picture structure. See
+ * vaGetSurfaceBufferWl() description for more details.
+ *
+ * @param[in]   dpy         the VA display
+ * @param[in]   image       the VA image
+ * @param[in]   flags       the deinterlacing flags
+ * @param[out]  out_buffer  a wl_buffer wrapping the VA @image
+ * @return VA_STATUS_SUCCESS if successful
+ */
+VAStatus
+vaGetImageBufferWl(
+    VADisplay           dpy,
+    VAImageID           image,
+    unsigned int        flags,
+    struct wl_buffer  **out_buffer
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_WAYLAND_H */
diff --git a/va/wayland/va_wayland_drm.c b/va/wayland/va_wayland_drm.c
new file mode 100644
index 0000000..d292316
--- /dev/null
+++ b/va/wayland/va_wayland_drm.c
@@ -0,0 +1,223 @@
+/*
+ * va_wayland_drm.c - Wayland/DRM helpers
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "sysdeps.h"
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <sys/stat.h>
+#include <xf86drm.h>
+#include "va_drmcommon.h"
+#include "drm/va_drm_utils.h"
+#include "va_wayland_drm.h"
+#include "va_wayland_private.h"
+#include "wayland-drm-client-protocol.h"
+
+/* XXX: Wayland/DRM support currently lives in Mesa libEGL.so.* library */
+#define LIBWAYLAND_DRM_NAME "libEGL.so.1"
+
+typedef struct va_wayland_drm_context {
+    struct va_wayland_context   base;
+    void                       *handle;
+    struct wl_drm              *drm;
+    struct wl_registry         *registry;
+    void                       *drm_interface;
+    unsigned int                is_authenticated        : 1;
+} VADisplayContextWaylandDRM;
+
+static void
+drm_handle_device(void *data, struct wl_drm *drm, const char *device)
+{
+    VADisplayContextP const pDisplayContext = data;
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque;
+    struct drm_state * const drm_state = ctx->drm_state;
+    drm_magic_t magic;
+    struct stat st;
+
+    if (stat(device, &st) < 0) {
+        va_wayland_error("failed to identify %s: %s (errno %d)",
+                         device, strerror(errno), errno);
+        return;
+    }
+
+    if (!S_ISCHR(st.st_mode)) {
+        va_wayland_error("%s is not a device", device);
+        return;
+    }
+
+    drm_state->fd = open(device, O_RDWR);
+    if (drm_state->fd < 0) {
+        va_wayland_error("failed to open %s: %s (errno %d)",
+                         device, strerror(errno), errno);
+        return;
+    }
+
+    drmGetMagic(drm_state->fd, &magic);
+    wl_drm_authenticate(wl_drm_ctx->drm, magic);
+}
+
+static void
+drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
+{
+}
+
+static void
+drm_handle_authenticated(void *data, struct wl_drm *drm)
+{
+    VADisplayContextP const pDisplayContext = data;
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque;
+    struct drm_state * const drm_state = ctx->drm_state;
+
+    wl_drm_ctx->is_authenticated = 1;
+    drm_state->auth_type         = VA_DRM_AUTH_CUSTOM;
+}
+
+static const struct wl_drm_listener drm_listener = {
+    drm_handle_device,
+    drm_handle_format,
+    drm_handle_authenticated
+};
+
+static VAStatus
+va_DisplayContextGetDriverName(
+    VADisplayContextP pDisplayContext,
+    char            **driver_name_ptr
+)
+{
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+
+    return VA_DRM_GetDriverName(ctx, driver_name_ptr);
+}
+
+void
+va_wayland_drm_destroy(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    struct va_wayland_drm_context * const wl_drm_ctx = pDisplayContext->opaque;
+    struct drm_state * const drm_state = ctx->drm_state;
+
+    if (wl_drm_ctx->drm) {
+        wl_drm_destroy(wl_drm_ctx->drm);
+        wl_drm_ctx->drm = NULL;
+    }
+    wl_drm_ctx->is_authenticated = 0;
+
+    if (wl_drm_ctx->handle) {
+        dlclose(wl_drm_ctx->handle);
+        wl_drm_ctx->handle = NULL;
+    }
+
+    if (drm_state) {
+        if (drm_state->fd >= 0) {
+            close(drm_state->fd);
+            drm_state->fd = -1;
+        }
+        free(ctx->drm_state);
+        ctx->drm_state = NULL;
+    }
+}
+
+static void
+registry_handle_global(
+    void               *data,
+    struct wl_registry *registry,
+    uint32_t            id,
+    const char         *interface,
+    uint32_t            version
+)
+{
+    struct va_wayland_drm_context *wl_drm_ctx = data;
+
+    if (strcmp(interface, "wl_drm") == 0) {
+        wl_drm_ctx->drm =
+            wl_registry_bind(wl_drm_ctx->registry, id, wl_drm_ctx->drm_interface, 1);
+    }
+}
+
+static const struct wl_registry_listener registry_listener = {
+    registry_handle_global,
+    NULL,
+};
+
+bool
+va_wayland_drm_create(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    struct va_wayland_drm_context *wl_drm_ctx;
+    struct drm_state *drm_state;
+    uint32_t id;
+
+    wl_drm_ctx = malloc(sizeof(*wl_drm_ctx));
+    if (!wl_drm_ctx)
+        return false;
+    wl_drm_ctx->base.destroy            = va_wayland_drm_destroy;
+    wl_drm_ctx->handle                  = NULL;
+    wl_drm_ctx->drm                     = NULL;
+    wl_drm_ctx->drm_interface           = NULL;
+    wl_drm_ctx->is_authenticated        = 0;
+    pDisplayContext->opaque             = wl_drm_ctx;
+    pDisplayContext->vaGetDriverName    = va_DisplayContextGetDriverName;
+
+    drm_state = calloc(1, sizeof(struct drm_state));
+    if (!drm_state)
+        return false;
+    drm_state->fd        = -1;
+    drm_state->auth_type = 0;
+    ctx->drm_state       = drm_state;
+
+    wl_drm_ctx->handle = dlopen(LIBWAYLAND_DRM_NAME, RTLD_LAZY|RTLD_LOCAL);
+    if (!wl_drm_ctx->handle)
+        return false;
+
+    wl_drm_ctx->drm_interface =
+        dlsym(wl_drm_ctx->handle, "wl_drm_interface");
+    if (!wl_drm_ctx->drm_interface)
+        return false;
+
+    wl_drm_ctx->registry = wl_display_get_registry(ctx->native_dpy);
+    wl_registry_add_listener(wl_drm_ctx->registry, &registry_listener, wl_drm_ctx);
+    wl_display_roundtrip(ctx->native_dpy);
+
+    /* registry_handle_global should have been called by the
+     * wl_display_roundtrip above
+     */
+
+    if (!wl_drm_ctx->drm)
+        return false;
+
+    wl_drm_add_listener(wl_drm_ctx->drm, &drm_listener, pDisplayContext);
+    wl_display_roundtrip(ctx->native_dpy);
+    if (drm_state->fd < 0)
+        return false;
+
+    wl_display_roundtrip(ctx->native_dpy);
+    if (!wl_drm_ctx->is_authenticated)
+        return false;
+    return true;
+}
diff --git a/va/wayland/va_wayland_drm.h b/va/wayland/va_wayland_drm.h
new file mode 100644
index 0000000..6fb8f52
--- /dev/null
+++ b/va/wayland/va_wayland_drm.h
@@ -0,0 +1,52 @@
+/*
+ * va_wayland_drm.h - Wayland/DRM helpers
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_WAYLAND_DRM_H
+#define VA_WAYLAND_DRM_H
+
+#include <stdbool.h>
+#include "va_wayland.h"
+#include "va_backend.h"
+#include "va_backend_wayland.h"
+
+/**
+ * \brief Initializes Wayland/DRM layer.
+ *
+ * This is an internal function used to initialize the VA/DRM subsystem
+ * if the application is running on a DRM-based server.
+ *
+ * @param[in]   pDisplayContext the VA display context
+ * @return true if successful
+ */
+DLL_HIDDEN
+bool
+va_wayland_drm_create(VADisplayContextP pDisplayContext);
+
+DLL_HIDDEN
+void
+va_wayland_drm_destroy(VADisplayContextP pDisplayContext);
+
+#endif /* VA_WAYLAND_DRM_H */
diff --git a/va/wayland/va_wayland_emgd.c b/va/wayland/va_wayland_emgd.c
new file mode 100644
index 0000000..cb885d1
--- /dev/null
+++ b/va/wayland/va_wayland_emgd.c
@@ -0,0 +1,157 @@
+/*
+ * va_wayland_emgd.c - Wayland/EMGD helpers
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "sysdeps.h"
+#include <unistd.h>
+#include <dlfcn.h>
+#include "va_drmcommon.h"
+#include "va_wayland_emgd.h"
+#include "va_wayland_private.h"
+
+/* XXX: Wayland/EMGD support currently lives in libwayland-emgd.so.* library */
+#define LIBWAYLAND_EMGD_NAME "libwayland-emgd.so.1"
+
+typedef struct va_wayland_emgd_context {
+    struct va_wayland_context   base;
+    void                       *handle;
+    struct wl_emgd             *emgd;
+    void                       *emgd_interface;
+    unsigned int                is_created      : 1;
+    struct wl_registry         *registry;
+} VADisplayContextWaylandEMGD;
+
+static inline void
+wl_emgd_destroy(struct wl_emgd *emgd)
+{
+    wl_proxy_destroy((struct wl_proxy *)emgd);
+}
+
+static VAStatus
+va_DisplayContextGetDriverName(
+    VADisplayContextP pDisplayContext,
+    char            **driver_name_ptr
+)
+{
+    *driver_name_ptr = strdup("emgd");
+    return VA_STATUS_SUCCESS;
+}
+
+void
+va_wayland_emgd_destroy(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    VADisplayContextWaylandEMGD * const wl_emgd_ctx = pDisplayContext->opaque;
+    struct drm_state * const drm_state = ctx->drm_state;
+
+    if (wl_emgd_ctx->emgd) {
+        wl_emgd_destroy(wl_emgd_ctx->emgd);
+        wl_emgd_ctx->emgd = NULL;
+    }
+    wl_emgd_ctx->is_created = 0;
+
+    if (wl_emgd_ctx->handle) {
+        dlclose(wl_emgd_ctx->handle);
+        wl_emgd_ctx->handle = NULL;
+    }
+
+    if (drm_state) {
+        if (drm_state->fd >= 0) {
+            close(drm_state->fd);
+            drm_state->fd = -1;
+        }
+        free(ctx->drm_state);
+        ctx->drm_state = NULL;
+    }
+}
+
+static void
+registry_handle_global(
+    void               *data,
+    struct wl_registry *registry,
+    uint32_t            id,
+    const char         *interface,
+    uint32_t            version
+)
+{
+    VADisplayContextWaylandEMGD *wl_emgd_ctx = data;
+
+    if (strcmp(interface, "wl_emgd") == 0) {
+        wl_emgd_ctx->emgd =
+            wl_registry_bind(registry, id, wl_emgd_ctx->emgd_interface, 1);
+    }
+}
+
+static const struct wl_registry_listener registry_listener = {
+    registry_handle_global,
+    NULL,
+};
+
+bool
+va_wayland_emgd_create(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    VADisplayContextWaylandEMGD *wl_emgd_ctx;
+    struct drm_state *drm_state;
+    uint32_t id;
+
+    wl_emgd_ctx = malloc(sizeof(*wl_emgd_ctx));
+    if (!wl_emgd_ctx)
+        return false;
+    wl_emgd_ctx->base.destroy           = va_wayland_emgd_destroy;
+    wl_emgd_ctx->handle                 = NULL;
+    wl_emgd_ctx->emgd                   = NULL;
+    wl_emgd_ctx->emgd_interface         = NULL;
+    wl_emgd_ctx->is_created             = 0;
+    pDisplayContext->opaque             = wl_emgd_ctx;
+    pDisplayContext->vaGetDriverName    = va_DisplayContextGetDriverName;
+
+    drm_state = calloc(1, sizeof(struct drm_state));
+    if (!drm_state)
+        return false;
+    drm_state->fd        = -1;
+    drm_state->auth_type = 0;
+    ctx->drm_state       = drm_state;
+
+    wl_emgd_ctx->handle = dlopen(LIBWAYLAND_EMGD_NAME, RTLD_LAZY|RTLD_LOCAL);
+    if (!wl_emgd_ctx->handle)
+        return false;
+
+    wl_emgd_ctx->emgd_interface =
+        dlsym(wl_emgd_ctx->handle, "wl_emgd_interface");
+    if (!wl_emgd_ctx->emgd_interface)
+        return false;
+
+    wl_emgd_ctx->registry = wl_display_get_registry(ctx->native_dpy);
+    wl_registry_add_listener(wl_emgd_ctx->registry, &registry_listener, wl_emgd_ctx);
+    wl_display_roundtrip(ctx->native_dpy);
+
+    /* registry_handle_global should have been called by the
+     * wl_display_roundtrip above
+     */
+    if (!wl_emgd_ctx->emgd)
+        return false;
+    return true;
+}
diff --git a/va/wayland/va_wayland_emgd.h b/va/wayland/va_wayland_emgd.h
new file mode 100644
index 0000000..053b6b4
--- /dev/null
+++ b/va/wayland/va_wayland_emgd.h
@@ -0,0 +1,52 @@
+/*
+ * va_wayland_emgd.h - Wayland/EMGD helpers
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_WAYLAND_EMGD_H
+#define VA_WAYLAND_EMGD_H
+
+#include <stdbool.h>
+#include "va_wayland.h"
+#include "va_backend.h"
+#include "va_backend_wayland.h"
+
+/**
+ * \brief Initializes Wayland/EMGD layer.
+ *
+ * This is an internal function used to initialize the VA/EMGD subsystem
+ * if the application is running on an EMGD-based server.
+ *
+ * @param[in]   pDisplayContext the VA display context
+ * @return true if successful
+ */
+DLL_HIDDEN
+bool
+va_wayland_emgd_create(VADisplayContextP pDisplayContext);
+
+DLL_HIDDEN
+void
+va_wayland_emgd_destroy(VADisplayContextP pDisplayContext);
+
+#endif /* VA_WAYLAND_EMGD_H */
diff --git a/va/wayland/va_wayland_private.h b/va/wayland/va_wayland_private.h
new file mode 100644
index 0000000..f09f4b7
--- /dev/null
+++ b/va/wayland/va_wayland_private.h
@@ -0,0 +1,44 @@
+/*
+ * va_wayland_private.h - Wayland private API
+ *
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_WAYLAND_PRIVATE_H
+#define VA_WAYLAND_PRIVATE_H
+
+struct va_wayland_context;
+
+typedef bool (*VADisplayContextCreateFunc)(VADisplayContextP pDisplayContext);
+typedef void (*VADisplayContextDestroyFunc)(VADisplayContextP pDisplayContext);
+
+/* VA/Wayland base display context */
+typedef struct va_wayland_context {
+    VADisplayContextDestroyFunc destroy;
+} VADisplayContextWayland, *VADisplayContextWaylandP;
+
+DLL_HIDDEN
+void
+va_wayland_error(const char *format, ...);
+
+#endif /* VA_WAYLAND_PRIVATE_H */
diff --git a/va/wayland/wayland-drm-client-protocol.h b/va/wayland/wayland-drm-client-protocol.h
new file mode 100644
index 0000000..cba188e
--- /dev/null
+++ b/va/wayland/wayland-drm-client-protocol.h
@@ -0,0 +1,213 @@
+/* 
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2010-2011 Intel Corporation
+ * 
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that\n the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ * 
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+
+#ifndef DRM_CLIENT_PROTOCOL_H
+#define DRM_CLIENT_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-client.h"
+
+struct wl_client;
+struct wl_resource;
+
+struct wl_drm;
+
+extern const struct wl_interface wl_drm_interface;
+
+#ifndef WL_DRM_ERROR_ENUM
+#define WL_DRM_ERROR_ENUM
+enum wl_drm_error {
+	WL_DRM_ERROR_AUTHENTICATE_FAIL = 0,
+	WL_DRM_ERROR_INVALID_FORMAT = 1,
+	WL_DRM_ERROR_INVALID_NAME = 2,
+};
+#endif /* WL_DRM_ERROR_ENUM */
+
+#ifndef WL_DRM_FORMAT_ENUM
+#define WL_DRM_FORMAT_ENUM
+enum wl_drm_format {
+	WL_DRM_FORMAT_C8 = 0x20203843,
+	WL_DRM_FORMAT_RGB332 = 0x38424752,
+	WL_DRM_FORMAT_BGR233 = 0x38524742,
+	WL_DRM_FORMAT_XRGB4444 = 0x32315258,
+	WL_DRM_FORMAT_XBGR4444 = 0x32314258,
+	WL_DRM_FORMAT_RGBX4444 = 0x32315852,
+	WL_DRM_FORMAT_BGRX4444 = 0x32315842,
+	WL_DRM_FORMAT_ARGB4444 = 0x32315241,
+	WL_DRM_FORMAT_ABGR4444 = 0x32314241,
+	WL_DRM_FORMAT_RGBA4444 = 0x32314152,
+	WL_DRM_FORMAT_BGRA4444 = 0x32314142,
+	WL_DRM_FORMAT_XRGB1555 = 0x35315258,
+	WL_DRM_FORMAT_XBGR1555 = 0x35314258,
+	WL_DRM_FORMAT_RGBX5551 = 0x35315852,
+	WL_DRM_FORMAT_BGRX5551 = 0x35315842,
+	WL_DRM_FORMAT_ARGB1555 = 0x35315241,
+	WL_DRM_FORMAT_ABGR1555 = 0x35314241,
+	WL_DRM_FORMAT_RGBA5551 = 0x35314152,
+	WL_DRM_FORMAT_BGRA5551 = 0x35314142,
+	WL_DRM_FORMAT_RGB565 = 0x36314752,
+	WL_DRM_FORMAT_BGR565 = 0x36314742,
+	WL_DRM_FORMAT_RGB888 = 0x34324752,
+	WL_DRM_FORMAT_BGR888 = 0x34324742,
+	WL_DRM_FORMAT_XRGB8888 = 0x34325258,
+	WL_DRM_FORMAT_XBGR8888 = 0x34324258,
+	WL_DRM_FORMAT_RGBX8888 = 0x34325852,
+	WL_DRM_FORMAT_BGRX8888 = 0x34325842,
+	WL_DRM_FORMAT_ARGB8888 = 0x34325241,
+	WL_DRM_FORMAT_ABGR8888 = 0x34324241,
+	WL_DRM_FORMAT_RGBA8888 = 0x34324152,
+	WL_DRM_FORMAT_BGRA8888 = 0x34324142,
+	WL_DRM_FORMAT_XRGB2101010 = 0x30335258,
+	WL_DRM_FORMAT_XBGR2101010 = 0x30334258,
+	WL_DRM_FORMAT_RGBX1010102 = 0x30335852,
+	WL_DRM_FORMAT_BGRX1010102 = 0x30335842,
+	WL_DRM_FORMAT_ARGB2101010 = 0x30335241,
+	WL_DRM_FORMAT_ABGR2101010 = 0x30334241,
+	WL_DRM_FORMAT_RGBA1010102 = 0x30334152,
+	WL_DRM_FORMAT_BGRA1010102 = 0x30334142,
+	WL_DRM_FORMAT_YUYV = 0x56595559,
+	WL_DRM_FORMAT_YVYU = 0x55595659,
+	WL_DRM_FORMAT_UYVY = 0x59565955,
+	WL_DRM_FORMAT_VYUY = 0x59555956,
+	WL_DRM_FORMAT_AYUV = 0x56555941,
+	WL_DRM_FORMAT_NV12 = 0x3231564e,
+	WL_DRM_FORMAT_NV21 = 0x3132564e,
+	WL_DRM_FORMAT_NV16 = 0x3631564e,
+	WL_DRM_FORMAT_NV61 = 0x3136564e,
+	WL_DRM_FORMAT_YUV410 = 0x39565559,
+	WL_DRM_FORMAT_YVU410 = 0x39555659,
+	WL_DRM_FORMAT_YUV411 = 0x31315559,
+	WL_DRM_FORMAT_YVU411 = 0x31315659,
+	WL_DRM_FORMAT_YUV420 = 0x32315559,
+	WL_DRM_FORMAT_YVU420 = 0x32315659,
+	WL_DRM_FORMAT_YUV422 = 0x36315559,
+	WL_DRM_FORMAT_YVU422 = 0x36315659,
+	WL_DRM_FORMAT_YUV444 = 0x34325559,
+	WL_DRM_FORMAT_YVU444 = 0x34325659,
+};
+#endif /* WL_DRM_FORMAT_ENUM */
+
+struct wl_drm_listener {
+	/**
+	 * device - device
+	 * @name: name
+	 */
+	void (*device)(void *data,
+		       struct wl_drm *wl_drm,
+		       const char *name);
+	/**
+	 * format - format
+	 * @format: format
+	 */
+	void (*format)(void *data,
+		       struct wl_drm *wl_drm,
+		       uint32_t format);
+	/**
+	 * authenticated - authenticated
+	 */
+	void (*authenticated)(void *data,
+			      struct wl_drm *wl_drm);
+};
+
+static inline int
+wl_drm_add_listener(struct wl_drm *wl_drm,
+		    const struct wl_drm_listener *listener, void *data)
+{
+	return wl_proxy_add_listener((struct wl_proxy *) wl_drm,
+				     (void (**)(void)) listener, data);
+}
+
+#define WL_DRM_AUTHENTICATE	0
+#define WL_DRM_CREATE_BUFFER	1
+#define WL_DRM_CREATE_PLANAR_BUFFER	2
+
+static inline void
+wl_drm_set_user_data(struct wl_drm *wl_drm, void *user_data)
+{
+	wl_proxy_set_user_data((struct wl_proxy *) wl_drm, user_data);
+}
+
+static inline void *
+wl_drm_get_user_data(struct wl_drm *wl_drm)
+{
+	return wl_proxy_get_user_data((struct wl_proxy *) wl_drm);
+}
+
+static inline void
+wl_drm_destroy(struct wl_drm *wl_drm)
+{
+	wl_proxy_destroy((struct wl_proxy *) wl_drm);
+}
+
+static inline void
+wl_drm_authenticate(struct wl_drm *wl_drm, uint32_t id)
+{
+	wl_proxy_marshal((struct wl_proxy *) wl_drm,
+			 WL_DRM_AUTHENTICATE, id);
+}
+
+static inline struct wl_buffer *
+wl_drm_create_buffer(struct wl_drm *wl_drm, uint32_t name, int32_t width, int32_t height, uint32_t stride, uint32_t format)
+{
+	struct wl_proxy *id;
+
+	id = wl_proxy_create((struct wl_proxy *) wl_drm,
+			     &wl_buffer_interface);
+	if (!id)
+		return NULL;
+
+	wl_proxy_marshal((struct wl_proxy *) wl_drm,
+			 WL_DRM_CREATE_BUFFER, id, name, width, height, stride, format);
+
+	return (struct wl_buffer *) id;
+}
+
+static inline struct wl_buffer *
+wl_drm_create_planar_buffer(struct wl_drm *wl_drm, uint32_t name, int32_t width, int32_t height, uint32_t format, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
+{
+	struct wl_proxy *id;
+
+	id = wl_proxy_create((struct wl_proxy *) wl_drm,
+			     &wl_buffer_interface);
+	if (!id)
+		return NULL;
+
+	wl_proxy_marshal((struct wl_proxy *) wl_drm,
+			 WL_DRM_CREATE_PLANAR_BUFFER, id, name, width, height, format, offset0, stride0, offset1, stride1, offset2, stride2);
+
+	return (struct wl_buffer *) id;
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/va/x11/Makefile.am b/va/x11/Makefile.am
index c1cbc7e..508506e 100644
--- a/va/x11/Makefile.am
+++ b/va/x11/Makefile.am
@@ -20,7 +20,15 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-INCLUDES = -DLINUX -I$(top_srcdir) -I$(top_srcdir)/va $(DRM_CFLAGS)
+INCLUDES = \
+	-DLINUX			\
+	-I$(top_srcdir)		\
+	-I$(top_srcdir)/va	\
+	$(X11_CFLAGS)		\
+	$(XEXT_CFLAGS)		\
+	$(XFIXES_CFLAGS)	\
+	$(DRM_CFLAGS)		\
+	$(NULL)
 
 source_c = \
 	dri1_util.c		\
diff --git a/va/x11/dri1_util.c b/va/x11/dri1_util.c
index 7e5abf8..d3da81b 100644
--- a/va/x11/dri1_util.c
+++ b/va/x11/dri1_util.c
@@ -59,21 +59,21 @@
 static void
 dri1Close(VADriverContextP ctx)
 {
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
 
     free_drawable_hashtable(ctx);
     VA_DRIDestroyContext(ctx->native_dpy, ctx->x11_screen, dri_state->hwContextID);
     assert(dri_state->pSAREA != MAP_FAILED);
     drmUnmap(dri_state->pSAREA, SAREA_MAX);
-    assert(dri_state->fd >= 0);
-    drmCloseOnce(dri_state->fd);
+    assert(dri_state->base.fd >= 0);
+    drmCloseOnce(dri_state->base.fd);
     VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen);
 }
 
 Bool 
 isDRI1Connected(VADriverContextP ctx, char **driver_name)
 {
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
     int direct_capable;
     int driver_major;
     int driver_minor;
@@ -83,9 +83,9 @@
     drm_magic_t magic;        
 
     *driver_name = NULL;
-    dri_state->fd = -1;
+    dri_state->base.fd = -1;
     dri_state->pSAREA = MAP_FAILED;
-    dri_state->driConnectedFlag = VA_NONE;
+    dri_state->base.auth_type = VA_NONE;
 
     if (!VA_DRIQueryDirectRenderingCapable(ctx->native_dpy, 
                                            ctx->x11_screen, 
@@ -105,20 +105,20 @@
         goto err_out0;
 
     
-    dri_state->fd = drmOpenOnce(NULL, BusID, &newlyopened);
+    dri_state->base.fd = drmOpenOnce(NULL, BusID, &newlyopened);
     XFree(BusID);
 
-    if (dri_state->fd < 0)
+    if (dri_state->base.fd < 0)
         goto err_out1;
 
 
-    if (drmGetMagic(dri_state->fd, &magic))
+    if (drmGetMagic(dri_state->base.fd, &magic))
         goto err_out1;
 
     if (newlyopened && !VA_DRIAuthConnection(ctx->native_dpy, ctx->x11_screen, magic))
         goto err_out1;
 
-    if (drmMap(dri_state->fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA))
+    if (drmMap(dri_state->base.fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA))
         goto err_out1;
 
     if (!VA_DRICreateContext(ctx->native_dpy, ctx->x11_screen,
@@ -126,7 +126,7 @@
                              &dri_state->hwContextID, &dri_state->hwContext))
         goto err_out1;
 
-    dri_state->driConnectedFlag = VA_DRI1;
+    dri_state->base.auth_type = VA_DRI1;
     dri_state->createDrawable = dri1CreateDrawable;
     dri_state->destroyDrawable = dri1DestroyDrawable;
     dri_state->swapBuffer = dri1SwapBuffer;
@@ -139,8 +139,8 @@
     if (dri_state->pSAREA != MAP_FAILED)
         drmUnmap(dri_state->pSAREA, SAREA_MAX);
 
-    if (dri_state->fd >= 0)
-        drmCloseOnce(dri_state->fd);
+    if (dri_state->base.fd >= 0)
+        drmCloseOnce(dri_state->base.fd);
 
     VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen);
 
@@ -149,7 +149,7 @@
         XFree(*driver_name);
 
     dri_state->pSAREA = MAP_FAILED;
-    dri_state->fd = -1;
+    dri_state->base.fd = -1;
     *driver_name = NULL;
     
     return False;
diff --git a/va/x11/dri2_util.c b/va/x11/dri2_util.c
index 995f235..3d490d0 100644
--- a/va/x11/dri2_util.c
+++ b/va/x11/dri2_util.c
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -141,50 +164,51 @@
 void
 dri2Close(VADriverContextP ctx)
 {
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
 
     free_drawable_hashtable(ctx);
 
-    if (dri_state->fd >= 0);
-	close(dri_state->fd);
+    if (dri_state->base.fd >= 0);
+	close(dri_state->base.fd);
 }
 
 Bool 
 isDRI2Connected(VADriverContextP ctx, char **driver_name)
 {
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
     int major, minor;
     int error_base;
     int event_base;
     char *device_name = NULL;
     drm_magic_t magic;        
     *driver_name = NULL;
-    dri_state->fd = -1;
-    dri_state->driConnectedFlag = VA_NONE;
+    dri_state->base.fd = -1;
+    dri_state->base.auth_type = VA_NONE;
     if (!VA_DRI2QueryExtension(ctx->native_dpy, &event_base, &error_base))
         goto err_out;
 
     if (!VA_DRI2QueryVersion(ctx->native_dpy, &major, &minor))
         goto err_out;
 
+
     if (!VA_DRI2Connect(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
-                     driver_name, &device_name))
+                     driver_name, &device_name) || !device_name)
         goto err_out;
 
-    dri_state->fd = open(device_name, O_RDWR);
-    assert(dri_state->fd >= 0);
+    dri_state->base.fd = open(device_name, O_RDWR);
+    assert(dri_state->base.fd >= 0);
 
-    if (dri_state->fd < 0)
+    if (dri_state->base.fd < 0)
         goto err_out;
 
-    if (drmGetMagic(dri_state->fd, &magic))
+    if (drmGetMagic(dri_state->base.fd, &magic))
         goto err_out;
 
     if (!VA_DRI2Authenticate(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
                           magic))
         goto err_out;
 
-    dri_state->driConnectedFlag = VA_DRI2;
+    dri_state->base.auth_type = VA_DRI2;
     dri_state->createDrawable = dri2CreateDrawable;
     dri_state->destroyDrawable = dri2DestroyDrawable;
     dri_state->swapBuffer = dri2SwapBuffer;
@@ -192,8 +216,7 @@
     dri_state->close = dri2Close;
     gsDRI2SwapAvailable = (minor >= 2);
 
-    if (device_name)
-        Xfree(device_name);
+    Xfree(device_name);
 
     return True;
 
@@ -204,11 +227,11 @@
     if (*driver_name)
         Xfree(*driver_name);
 
-    if (dri_state->fd >= 0)
-        close(dri_state->fd);
+    if (dri_state->base.fd >= 0)
+        close(dri_state->base.fd);
 
     *driver_name = NULL;
-    dri_state->fd = -1;
+    dri_state->base.fd = -1;
     
     return False;
 }
diff --git a/va/x11/va_dricommon.c b/va/x11/va_dricommon.c
index 07dc50c..c0cbbcc 100644
--- a/va/x11/va_dricommon.c
+++ b/va/x11/va_dricommon.c
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
 #include "va_dricommon.h"
 
 // X error trap
@@ -38,7 +61,7 @@
 static struct dri_drawable *
 do_drawable_hash(VADriverContextP ctx, XID drawable)
 {
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
     int index = drawable % DRAWABLE_HASH_SZ;
     struct dri_drawable *dri_drawable = dri_state->drawable_hash[index];
 
@@ -60,7 +83,7 @@
 void
 free_drawable(VADriverContextP ctx, struct dri_drawable* dri_drawable)
 {
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
     int i = 0;
 
     while (i++ < DRAWABLE_HASH_SZ) {
@@ -74,7 +97,7 @@
 void
 free_drawable_hashtable(VADriverContextP ctx)
 {
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
     int i;
     struct dri_drawable *dri_drawable, *prev;
 
@@ -100,7 +123,7 @@
 void 
 dri_swap_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
 {
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
 
     dri_state->swapBuffer(ctx, dri_drawable);
 }
@@ -108,7 +131,7 @@
 union dri_buffer *
 dri_get_rendering_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
 {
-    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
     
     return dri_state->getRenderingBuffer(ctx, dri_drawable);
 }
diff --git a/va/x11/va_dricommon.h b/va/x11/va_dricommon.h
index 357cc8e..ca25d2d 100644
--- a/va/x11/va_dricommon.h
+++ b/va/x11/va_dricommon.h
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
 #ifndef _VA_DRICOMMON_H_
 #define _VA_DRICOMMON_H_
 
@@ -9,18 +32,19 @@
 #endif
 
 #include <va/va_backend.h>
+#include <va/va_drmcommon.h>
 
 #ifdef ANDROID
 #define XID unsigned int
 #define Bool int
 #endif
 
-enum
-{
-    VA_NONE = 0,
-    VA_DRI1 = 1,
-    VA_DRI2 = 2,
-    VA_DUMMY = 3
+enum {
+    /* Compatibility. Do not use for newly-written code. */
+    VA_NONE     = VA_DRM_AUTH_NONE,
+    VA_DRI1     = VA_DRM_AUTH_DRI1,
+    VA_DRI2     = VA_DRM_AUTH_DRI2,
+    VA_DUMMY    = VA_DRM_AUTH_CUSTOM
 };
 
 union dri_buffer 
@@ -51,8 +75,7 @@
 #define DRAWABLE_HASH_SZ 32
 struct dri_state 
 {
-    int fd;
-    int driConnectedFlag; /* 0: disconnected, 1: DRI, 2: DRI2 */
+    struct drm_state base;
 #ifndef ANDROID
     drm_handle_t hSAREA;
     drm_context_t hwContext;
diff --git a/va/x11/va_fglrx.c b/va/x11/va_fglrx.c
index 77149cb..a437bce 100644
--- a/va/x11/va_fglrx.c
+++ b/va/x11/va_fglrx.c
@@ -153,27 +153,27 @@
     dlerror();
     ADL_Main_Control_Create = (ADL_MAIN_CONTROL_CREATE)
         dlsym(libadl_handle,"ADL_Main_Control_Create");
-    if (dlerror())
+    if (dlerror() || !ADL_Main_Control_Create)
         goto end;
 
     ADL_Main_Control_Destroy = (ADL_MAIN_CONTROL_DESTROY)
         dlsym(libadl_handle,"ADL_Main_Control_Destroy");
-    if (dlerror())
+    if (dlerror() || !ADL_Main_Control_Destroy)
         goto end;
 
     ADL_Adapter_NumberOfAdapters_Get = (ADL_ADAPTER_NUMBEROFADAPTERS_GET)
         dlsym(libadl_handle,"ADL_Adapter_NumberOfAdapters_Get");
-    if (dlerror())
+    if (dlerror() || !ADL_Adapter_NumberOfAdapters_Get)
         goto end;
 
     ADL_Adapter_AdapterInfo_Get = (ADL_ADAPTER_ADAPTERINFO_GET)
         dlsym(libadl_handle,"ADL_Adapter_AdapterInfo_Get");
-    if (dlerror())
+    if (dlerror() || !ADL_Adapter_AdapterInfo_Get)
         goto end;
 
     ADL_Adapter_XScreenInfo_Get = (ADL_ADAPTER_XSCREENINFO_GET)
         dlsym(libadl_handle,"ADL_Adapter_XScreenInfo_Get");
-    if (dlerror())
+    if (dlerror() || !ADL_Adapter_XScreenInfo_Get)
         goto end;
 
     if (ADL_Main_Control_Create(ADL_Main_Memory_Alloc, 1) != ADL_OK)
diff --git a/va/x11/va_x11.c b/va/x11/va_x11.c
index 86b040a..c78bd8a 100644
--- a/va/x11/va_x11.c
+++ b/va/x11/va_x11.c
@@ -63,12 +63,12 @@
         return;
 
     ctx = pDisplayContext->pDriverContext;
-    dri_state = ctx->dri_state;
+    dri_state = ctx->drm_state;
 
     if (dri_state && dri_state->close)
         dri_state->close(ctx);
 
-    free(pDisplayContext->pDriverContext->dri_state);
+    free(pDisplayContext->pDriverContext->drm_state);
     free(pDisplayContext->pDriverContext);
     free(pDisplayContext);
 }
@@ -150,7 +150,9 @@
 
     if (driver_name)
 	*driver_name = NULL;
-
+    else
+        return VA_STATUS_ERROR_UNKNOWN;
+    
     vaStatus = va_DRI2GetDriverName(pDisplayContext, driver_name);
     if (vaStatus != VA_STATUS_SUCCESS)
         vaStatus = va_DRIGetDriverName(pDisplayContext, driver_name);
@@ -185,12 +187,13 @@
 	  pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC;          
 
 	  pDriverContext->native_dpy       = (void *)native_dpy;
+          pDriverContext->display_type     = VA_DISPLAY_X11;
 	  pDisplayContext->pDriverContext  = pDriverContext;
 	  pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
 	  pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
 	  pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
           pDisplayContext->opaque          = NULL;
-	  pDriverContext->dri_state 	   = dri_state;
+	  pDriverContext->drm_state 	   = dri_state;
 	  dpy                              = (VADisplay)pDisplayContext;
       }
       else
@@ -253,9 +256,9 @@
   CHECK_DISPLAY(dpy);
   ctx = CTX(dpy);
   
-  VA_TRACE_FUNC(va_TracePutSurface, dpy, surface, (void *)draw, srcx, srcy, srcw, srch,
-                destx, desty, destw, desth,
-           cliprects, number_cliprects, flags );
+  VA_TRACE_LOG(va_TracePutSurface, dpy, surface, (void *)draw, srcx, srcy, srcw, srch,
+               destx, desty, destw, desth,
+               cliprects, number_cliprects, flags );
   
   return ctx->vtable->vaPutSurface( ctx, surface, (void *)draw, srcx, srcy, srcw, srch,
                                    destx, desty, destw, desth,