Description: Undocumented upstream changes
 This patch has been created by dpkg-source during the package build
 but it might have accumulated changes from several uploads. Please
 check the changelog to (hopefully) learn more on those changes.

--- mplayer-1.0~rc4~try1.dsfg1.orig/cfg-common.h
+++ mplayer-1.0~rc4~try1.dsfg1/cfg-common.h
@@ -520,6 +520,7 @@ const m_option_t common_opts[] = {
     {"vfm", &video_fm_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
     {"ac", &audio_codec_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
     {"vc", &video_codec_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
+    {"va", &video_hwaccel_name, CONF_TYPE_STRING, 0, 0, 0, NULL},
 
     // postprocessing:
 #ifdef CONFIG_LIBAVCODEC
--- mplayer-1.0~rc4~try1.dsfg1.orig/codec-cfg.c
+++ mplayer-1.0~rc4~try1.dsfg1/codec-cfg.c
@@ -224,6 +224,13 @@ static const struct {
     {"VDPAU_VC1",IMGFMT_VDPAU_VC1},
     {"VDPAU_MPEG4",IMGFMT_VDPAU_MPEG4},
 
+    {"VAAPI_MPEG2", IMGFMT_VAAPI_MPEG2},
+    {"VAAPI_MPEG4", IMGFMT_VAAPI_MPEG4},
+    {"VAAPI_H263",  IMGFMT_VAAPI_H263},
+    {"VAAPI_H264",  IMGFMT_VAAPI_H264},
+    {"VAAPI_WMV3",  IMGFMT_VAAPI_WMV3},
+    {"VAAPI_VC1",   IMGFMT_VAAPI_VC1},
+
     {NULL,    0}
 };
 
--- mplayer-1.0~rc4~try1.dsfg1.orig/fmt-conversion.c
+++ mplayer-1.0~rc4~try1.dsfg1/fmt-conversion.c
@@ -18,12 +18,14 @@
 
 #include "mp_msg.h"
 #include "libavutil/avutil.h"
+#include "libavcodec/avcodec.h"
 #include "libmpcodecs/img_format.h"
 #include "fmt-conversion.h"
 
 static const struct {
     int fmt;
     enum PixelFormat pix_fmt;
+    enum CodecID codec_id;
 } conversion_map[] = {
     {IMGFMT_ARGB, PIX_FMT_ARGB},
     {IMGFMT_BGRA, PIX_FMT_BGRA},
@@ -89,12 +91,25 @@ static const struct {
 
     {IMGFMT_XVMC_MOCO_MPEG2, PIX_FMT_XVMC_MPEG2_MC},
     {IMGFMT_XVMC_IDCT_MPEG2, PIX_FMT_XVMC_MPEG2_IDCT},
-    {IMGFMT_VDPAU_MPEG1,     PIX_FMT_VDPAU_MPEG1},
-    {IMGFMT_VDPAU_MPEG2,     PIX_FMT_VDPAU_MPEG2},
-    {IMGFMT_VDPAU_H264,      PIX_FMT_VDPAU_H264},
-    {IMGFMT_VDPAU_WMV3,      PIX_FMT_VDPAU_WMV3},
-    {IMGFMT_VDPAU_VC1,       PIX_FMT_VDPAU_VC1},
-    {IMGFMT_VDPAU_MPEG4,     PIX_FMT_VDPAU_MPEG4},
+
+    /* VA-API formats */
+    {IMGFMT_VAAPI_MPEG2,     PIX_FMT_VAAPI_VLD,  CODEC_ID_MPEG2VIDEO},
+    {IMGFMT_VAAPI_MPEG2_IDCT,PIX_FMT_VAAPI_IDCT, CODEC_ID_MPEG2VIDEO},
+    {IMGFMT_VAAPI_MPEG2_MOCO,PIX_FMT_VAAPI_MOCO, CODEC_ID_MPEG2VIDEO},
+    {IMGFMT_VAAPI_MPEG4,     PIX_FMT_VAAPI_VLD,  CODEC_ID_MPEG4},
+    {IMGFMT_VAAPI_H263,      PIX_FMT_VAAPI_VLD,  CODEC_ID_H263},
+    {IMGFMT_VAAPI_H264,      PIX_FMT_VAAPI_VLD,  CODEC_ID_H264},
+    {IMGFMT_VAAPI_WMV3,      PIX_FMT_VAAPI_VLD,  CODEC_ID_WMV3},
+    {IMGFMT_VAAPI_VC1,       PIX_FMT_VAAPI_VLD,  CODEC_ID_VC1},
+
+    /* VDPAU formats */
+    {IMGFMT_VDPAU_MPEG1,     PIX_FMT_VDPAU, CODEC_ID_MPEG1VIDEO},
+    {IMGFMT_VDPAU_MPEG2,     PIX_FMT_VDPAU, CODEC_ID_MPEG2VIDEO},
+    {IMGFMT_VDPAU_MPEG4,     PIX_FMT_VDPAU, CODEC_ID_MPEG4},
+    {IMGFMT_VDPAU_H264,      PIX_FMT_VDPAU, CODEC_ID_H264},
+    {IMGFMT_VDPAU_WMV3,      PIX_FMT_VDPAU, CODEC_ID_WMV3},
+    {IMGFMT_VDPAU_VC1,       PIX_FMT_VDPAU, CODEC_ID_VC1},
+
     {0, PIX_FMT_NONE}
 };
 
@@ -111,12 +126,14 @@ enum PixelFormat imgfmt2pixfmt(int fmt)
     return pix_fmt;
 }
 
-int pixfmt2imgfmt(enum PixelFormat pix_fmt)
+int pixfmt2imgfmt(enum PixelFormat pix_fmt, int codec_id)
 {
     int i;
     int fmt;
     for (i = 0; conversion_map[i].pix_fmt != PIX_FMT_NONE; i++)
-        if (conversion_map[i].pix_fmt == pix_fmt)
+        if (conversion_map[i].pix_fmt == pix_fmt &&
+            (conversion_map[i].codec_id == 0 ||
+             conversion_map[i].codec_id == codec_id))
             break;
     fmt = conversion_map[i].fmt;
     if (!fmt)
--- mplayer-1.0~rc4~try1.dsfg1.orig/fmt-conversion.h
+++ mplayer-1.0~rc4~try1.dsfg1/fmt-conversion.h
@@ -23,6 +23,6 @@
 #include "libavutil/avutil.h"
 
 enum PixelFormat imgfmt2pixfmt(int fmt);
-int pixfmt2imgfmt(enum PixelFormat pix_fmt);
+int pixfmt2imgfmt(enum PixelFormat pix_fmt, int codec_id);
 
 #endif /* MPLAYER_FMT_CONVERSION_H */
--- mplayer-1.0~rc4~try1.dsfg1.orig/Makefile
+++ mplayer-1.0~rc4~try1.dsfg1/Makefile
@@ -623,6 +623,7 @@ SRCS_MPLAYER-$(TDFXVID)       += libvo/v
 SRCS_MPLAYER-$(TGA)           += libvo/vo_tga.c
 SRCS_MPLAYER-$(V4L2)          += libvo/vo_v4l2.c
 SRCS_MPLAYER-$(V4L2)          += libao2/ao_v4l2.c
+SRCS_MPLAYER-$(VAAPI)         += libvo/vo_vaapi.c
 SRCS_MPLAYER-$(VDPAU)         += libvo/vo_vdpau.c
 SRCS_MPLAYER-$(VESA)          += libvo/gtf.c libvo/vo_vesa.c libvo/vesa_lvo.c
 SRCS_MPLAYER-$(VIDIX)         += libvo/vo_cvidix.c \
@@ -676,6 +677,7 @@ SRCS_MPLAYER = command.c \
                libvo/aspect.c \
                libvo/geometry.c \
                libvo/spuenc.c \
+               libvo/stats.c \
                libvo/video_out.c \
                libvo/vo_mpegpes.c \
                libvo/vo_null.c \
--- mplayer-1.0~rc4~try1.dsfg1.orig/configure
+++ mplayer-1.0~rc4~try1.dsfg1/configure
@@ -385,6 +385,9 @@ Codecs:
   --disable-muxer=MUXER     disable specified FFmpeg muxer
   --enable-muxer=MUXER      enable specified FFmpeg muxer
 
+Hardware acceleration:
+  --enable-vaapi            enable VA-API acceleration [disable]
+
 Video output:
   --disable-vidix          disable VIDIX [for x86 *nix]
   --with-vidix-drivers[=*] list of VIDIX drivers to be compiled in
@@ -414,6 +417,7 @@ Video output:
   --enable-dvb             enable DVB video output [autodetect]
   --enable-mga             enable mga_vid video output [autodetect]
   --enable-xmga            enable mga_vid X11 video output [autodetect]
+  --enable-xrender	   enable Xrender video output [autodetect]
   --enable-xv              enable Xv video output [autodetect]
   --enable-xvmc            enable XvMC acceleration [disable]
   --enable-vdpau           enable VDPAU acceleration [autodetect]
@@ -582,8 +586,7 @@ libavparsers=$libavparsers_all
 libavbsfs_all=$(sed -n 's/^[^#]*BSF.*(.*, *\(.*\)).*/\1_bsf/p' libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]')
 libavbsfs=$libavbsfs_all
 libavhwaccels_all=$(sed -n 's/^[^#]*HWACCEL.*(.*, *\(.*\)).*/\1_hwaccel/p' libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]')
-# Disable all hardware accelerators for now.
-libavhwaccels=
+libavhwaccels=$(for h in $libavhwaccels_all; do case $h in (*_VAAPI_HWACCEL|*_VDPAU_HWACCEL) echo $h;; esac; done)
 libavdemuxers_all=$(sed -n 's/^[^#]*DEMUX.*(.*, *\(.*\)).*/\1_demuxer/p' libavformat/allformats.c | tr '[a-z]' '[A-Z]')
 libavdemuxers=$(echo $libavdemuxers_all | sed -e 's/ LIB[A-Z0-9_]*_DEMUXER//g' -e s/REDIR_DEMUXER// -e s/AVISYNTH_DEMUXER//)
 libavmuxers_all=$(sed -n 's/^[^#]*_MUX.*(.*, *\(.*\)).*/\1_muxer/p' libavformat/allformats.c | tr '[a-z]' '[A-Z]')
@@ -600,11 +603,15 @@ _libswscale_so=auto
 _libavcodec_mpegaudio_hp=yes
 _mencoder=yes
 _mplayer=yes
+_vaapi=auto
+_vaapi_glx=no
+_libgtop=auto
 _x11=auto
 _xshape=auto
 _xss=auto
 _dga1=auto
 _dga2=auto
+_xrender=auto
 _xv=auto
 _xvmc=no  #auto when complete
 _vdpau=auto
@@ -944,10 +951,14 @@ for ac_option do
   --disable-xshape)     _xshape=no      ;;
   --enable-xss)         _xss=yes        ;;
   --disable-xss)        _xss=no         ;;
+  --enable-xrender)     _xrender=yes    ;;
+  --disable-xrender)    _xrender=no     ;;
   --enable-xv)          _xv=yes         ;;
   --disable-xv)         _xv=no          ;;
   --enable-xvmc)        _xvmc=yes       ;;
   --disable-xvmc)       _xvmc=no        ;;
+  --enable-vaapi)       _vaapi=yes      ;;
+  --disable-vaapi)      _vaapi=no       ;;
   --enable-vdpau)       _vdpau=yes      ;;
   --disable-vdpau)      _vdpau=no       ;;
   --enable-sdl)         _sdl=yes        ;;
@@ -3961,6 +3972,28 @@ fi
 echores "$_gettimeofday"
 
 
+echocheck "clock_gettime()"
+cat > $TMPC << EOF
+#include <time.h>
+int main(void) {
+    struct timespec t;
+    clock_gettime(CLOCK_REALTIME, &t);
+    return 0;
+}
+EOF
+_clock_gettime=no
+cc_check -lrt && _clock_gettime=yes
+if test "$_clock_gettime" = yes ; then
+  def_clock_gettime='#define HAVE_CLOCK_GETTIME 1'
+  extra_ldflags="$extra_ldflags -lrt"
+  _need_clock_gettime=no
+else
+  def_clock_gettime='#undef HAVE_CLOCK_GETTIME'
+  _need_clock_gettime=yes
+fi
+echores "$_clock_gettime"
+
+
 echocheck "glob()"
 cat > $TMPC << EOF
 #include <stdio.h>
@@ -4400,7 +4433,7 @@ else
   novomodules="x11 $novomodules"
   res_comment="check if the dev(el) packages are installed"
   # disable stuff that depends on X
-  _xv=no ; _xvmc=no ; _xinerama=no ; _vm=no ; _xf86keysym=no ; _vdpau=no
+  _xv=no ; _xvmc=no ; _xinerama=no ; _vm=no ; _xf86keysym=no ; _vaapi=no ; _vdpau=no
 fi
 echores "$_x11"
 
@@ -4457,6 +4490,30 @@ else
 fi
 
 
+echocheck "Xrender"
+if test "$_xrender" = auto ; then
+  cat > $TMPC <<EOF
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrender.h>
+int main(void) {
+  (void) XRenderCreatePicture(0, 0, 0, 0, 0);
+  return 0; }
+EOF
+  _xrender=no
+  cc_check -lXrender && _xrender=yes
+fi
+
+if test "$_xrender" = yes ; then
+  def_xrender='#define CONFIG_XRENDER 1'
+  libs_mplayer="$libs_mplayer -lXrender"
+  vomodules="xrender $vomodules"
+else
+  def_xrender='#undef CONFIG_XRENDER'
+  novomodules="xrender $novomodules"
+fi
+echores "$_xrender"
+
+
 echocheck "Xv"
 if test "$_xv" = auto ; then
   cat > $TMPC <<EOF
@@ -4531,7 +4588,7 @@ if test "$_vdpau" = yes ; then
 else
   def_vdpau='#define CONFIG_VDPAU 0'
   novomodules="vdpau $novomodules"
-  libavdecoders=$(echo $libavdecoders | sed -e s/MPEG_VDPAU_DECODER// -e s/MPEG1_VDPAU_DECODER// -e s/H264_VDPAU_DECODER// -e s/WMV3_VDPAU_DECODER// -e s/VC1_VDPAU_DECODER// -e s/MPEG4_VDPAU_DECODER//)
+  libavhwaccels=$(echo $libavhwaccels | sed -e "s/\(MPEG[124]\|H26[34]\|WMV3\|VC1\)_VDPAU_HWACCEL//g")
 fi
 echores "$_vdpau"
 
@@ -4987,6 +5044,31 @@ echores "$_corevideo"
 fi #if darwin
 
 
+echocheck "libgtop"
+if test "$_libgtop" = auto ; then
+  _libgtop=no
+  if $_pkg_config --exists 'libgtop-2.0' ; then
+
+cat > $TMPC << EOF
+#include <glibtop/cpu.h>
+#include <glibtop/proctime.h>
+int main(void) { return 0; }
+EOF
+cc_check $($_pkg_config --libs --cflags libgtop-2.0) && tmp_run && _libgtop=yes
+
+  fi
+fi
+echores "$_libgtop"
+
+if test "$_libgtop" = yes ; then
+  def_libgtop='#define CONFIG_LIBGTOP 1'
+  libs_mplayer="$libs_mplayer $($_pkg_config --libs libgtop-2.0)"
+  extra_cflags="$extra_cflags $($_pkg_config --cflags libgtop-2.0)"
+else
+  def_libgtop='#define CONFIG_LIBGTOP 0'
+fi
+
+
 echocheck "PNG support"
 if test "$_png" = auto ; then
   _png=no
@@ -5370,6 +5452,23 @@ else
 fi
 echores "$_gl"
 
+echocheck "OpenGL utilities (GLU)"
+_glu=no
+if test "$_gl" = yes; then
+  cat > $TMPC << EOF
+#include <GL/glu.h>
+int main(void) {
+  gluPerspective(0.0, 0.0, 0.0, 0.0);
+  return 0;
+}
+EOF
+  cc_check -lGLU && _glu=yes
+fi
+if test "$_glu" = yes; then
+  libs_mplayer="$libs_mplayer -lGLU"
+fi
+echores "$_glu"
+
 
 echocheck "MatrixView"
 if test "$_gl" = no ; then
@@ -5990,6 +6089,67 @@ echores "$_dart"
 fi #if os2
 
 
+#########################
+# HARDWARE ACCELERATORS #
+#########################
+
+echocheck "VA-API"
+if test "$_vaapi" = yes -o "$_vaapi" = auto; then
+  _vaapi=no
+  _vaapi_old=no
+  cat > $TMPC <<EOF
+#include <va/va_x11.h>
+int main(void) { (void) vaGetDisplay(0); return 0; }
+EOF
+  cc_check -lva-x11 && _vaapi=yes || {
+    cat > $TMPC <<EOF
+#include <va_x11.h>
+int main(void) { (void) vaGetDisplay(0); return 0; }
+EOF
+    cc_check -lva && _vaapi=yes _vaapi_old=yes
+  }
+fi
+
+if test "$_vaapi" = yes ; then
+  def_vaapi='#define CONFIG_VAAPI 1'
+  if test "$_vaapi_old" = no ; then
+    def_vaapi_old='#define CONFIG_VAAPI_OLD 0'
+    libs_mencoder="$libs_mencoder -lva"
+    libs_mplayer="$libs_mplayer -lva-x11"
+  else
+    def_vaapi_old='#define CONFIG_VAAPI_OLD 1'
+    _mencoder="no"
+    libs_mplayer="$libs_mplayer -lva"
+  fi
+  vomodules="vaapi $vomodules"
+else
+  def_vaapi='#define CONFIG_VAAPI 0'
+  def_vaapi_old='#define CONFIG_VAAPI_OLD 0'
+  novomodules="vaapi $novomodules"
+  libavhwaccels=`echo $libavhwaccels | sed -e "s/\(MPEG[124]\|H26[34]\|WMV3\|VC1\)_VAAPI_HWACCEL//g"`
+fi
+echores "$_vaapi"
+
+echocheck "VA-API (with GLX support)"
+if test "$_vaapi" = yes; then
+  _vaapi_glx=no
+  if test "$_gl" = "yes" -a "$_glu" = yes; then
+    cat > $TMPC <<EOF
+#include <va/va_glx.h>
+int main(void) { (void) vaGetDisplayGLX(0); return 0; }
+EOF
+    cc_check -lva-glx && _vaapi_glx=yes
+  fi
+fi
+if test "$_vaapi_glx" = yes; then
+  def_vaapi_glx='#define CONFIG_VAAPI_GLX 1'
+  libs_mplayer="$libs_mplayer -lva-glx"
+else
+  def_vaapi_glx='#define CONFIG_VAAPI_GLX 0'
+fi
+echores "$_vaapi_glx"
+
+
 # set default CD/DVD devices
 if win32 || os2 ; then
   default_cdrom_device="D:"
@@ -8672,6 +8832,7 @@ TV_V4L2 = $_tv_v4l2
 TWOLAME=$_twolame
 UNRAR_EXEC = $_unrar_exec
 V4L2 = $_v4l2
+VAAPI = $_vaapi
 VCD = $_vcd
 VDPAU = $_vdpau
 VESA = $_vesa
@@ -8769,7 +8930,10 @@ CONFIG_GPL      = yes
 CONFIG_MLIB     = $_mlib
 CONFIG_MUXERS   = $_mencoder
 CONFIG_POSTPROC = yes
+CONFIG_VAAPI    = $_vaapi
+CONFIG_VAAPI_OLD= $_vaapi_old
 CONFIG_VDPAU    = $_vdpau
+CONFIG_XRENDER	= $_xrender
 CONFIG_XVMC     = $_xvmc
 CONFIG_ZLIB     = $_zlib
 
@@ -8887,6 +9051,7 @@ $def_winsock2_h
 
 
 /* system functions */
+$def_clock_gettime
 $def_gethostbyname2
 $def_gettimeofday
 $def_glob
@@ -8918,6 +9083,7 @@ $def_extern_asm
 $def_extern_prefix
 $def_iconv
 $def_kstat
+$def_libgtop
 $def_macosx_bundle
 $def_macosx_finder
 $def_maemo
@@ -9148,6 +9314,9 @@ $def_tdfxfb
 $def_tdfxvid
 $def_tga
 $def_v4l2
+$def_vaapi
+$def_vaapi_old
+$def_vaapi_glx
 $def_vdpau
 $def_vesa
 $def_vidix
@@ -9173,6 +9342,7 @@ $def_xf86keysym
 $def_xinerama
 $def_xmga
 $def_xss
+$def_xrender
 $def_xv
 $def_xvmc
 $def_xvr100
--- mplayer-1.0~rc4~try1.dsfg1.orig/etc/codecs.conf
+++ mplayer-1.0~rc4~try1.dsfg1/etc/codecs.conf
@@ -136,6 +136,7 @@ videocodec ffmpeg1
   fourcc m1v1
   driver ffmpeg
   dll "mpeg1video"
+  out VDPAU_MPEG1
   out YV12,I420,IYUV
 
 videocodec ffmpeg2
@@ -172,6 +173,8 @@ videocodec ffmpeg2
   fourcc slif ; SoftLab MPEG-2 I-frames Codec
   driver ffmpeg
   dll "mpeg2video"
+  out VAAPI_MPEG2
+  out VDPAU_MPEG2
   out YV12,I420,IYUV
   out 422P,444P
 
@@ -212,6 +215,7 @@ videocodec ffmpeg12
   fourcc slif ; SoftLab MPEG-2 I-frames Codec
   driver ffmpeg
   dll "mpegvideo"
+  out VDPAU_MPEG1,VDPAU_MPEG2
   out YV12,I420,IYUV
   out 422P,444P
 
@@ -291,41 +295,6 @@ videocodec ffmpeg12mc
   out IDCT_MPEG2
   out MOCO_MPEG2
 
-videocodec ffmpeg12vdpau
-  info "FFmpeg MPEG-1/2 (VDPAU)"
-  status working
-  format 0x10000001  ; MPEG-1
-  format 0x10000002  ; MPEG-2
-  fourcc mpg1,mpg2,MPG2
-  fourcc PIM1        ; Pinnacle hardware-MPEG-1
-  fourcc PIM2        ; Pinnacle hardware-MPEG-2
-  fourcc "DVR "
-  fourcc hdv2
-  fourcc MPEG
-  fourcc hdv1
-  fourcc hdv3        ; HDV 1080i50
-  fourcc hdv5        ; HDV  720p25
-  fourcc mx5p        ; MPEG IMX 625/50 (50 Mb/s)
-  fourcc hdv6,hdv7,hdv8
-  fourcc xdv1,xdv2,xdv3
-  fourcc xdv4,xdv5,xdv6
-  fourcc xdv7,xdv8,xdv9
-  fourcc xdva,xdvb,xdvc
-  fourcc xdvd,xdve,xdvf
-  fourcc xd5a,xd5b,xd5c
-  fourcc xd5d,xd5e,xd5f
-  fourcc xd59
-  fourcc mx5n,mx4n,mx4p
-  fourcc mx3n,mx3p
-  fourcc AVmp
-  fourcc mp2v,mpgv
-  fourcc LMP2 ; Lead mpeg2 in avi
-  fourcc m2v1,m1v1
-  driver ffmpeg
-  dll "mpegvideo_vdpau"
-  out VDPAU_MPEG1
-  out VDPAU_MPEG2
-
 videocodec mpegpes
   info "MPEG-PES output (.mpg or DXR3/IVTV/DVB/V4L2 card)"
   comment "for hardware decoding"
@@ -901,15 +870,9 @@ videocodec ffwmv3
   fourcc WMV3,wmv3
   driver ffmpeg
   dll wmv3
-  out YV12,I420,IYUV
-
-videocodec ffwmv3vdpau
-  info "FFmpeg WMV3/WMV9 (VDPAU)"
-  status buggy
-  fourcc WMV3,wmv3
-  driver ffmpeg
-  dll wmv3_vdpau
+  out VAAPI_WMV3
   out VDPAU_WMV3
+  out YV12,I420,IYUV
 
 videocodec ffvc1
   info "FFmpeg WVC1"
@@ -918,16 +881,9 @@ videocodec ffvc1
   fourcc vc-1,VC-1
   driver ffmpeg
   dll vc1
-  out YV12,I420,IYUV
-
-videocodec ffvc1vdpau
-  info "FFmpeg WVC1 (VDPAU)"
-  status buggy
-  fourcc WVC1,wvc1,WMVA
-  fourcc vc-1,VC-1
-  driver ffmpeg
-  dll vc1_vdpau
+  out VAAPI_VC1
   out VDPAU_VC1
+  out YV12,I420,IYUV
 
 videocodec ffh264
   info "FFmpeg H.264"
@@ -939,19 +895,9 @@ videocodec ffh264
   format 0x10000005
   driver ffmpeg
   dll h264
-  out YV12,I420,IYUV
-
-videocodec ffh264vdpau
-  info "FFmpeg H.264 (VDPAU)"
-  status working
-  fourcc H264,h264
-  fourcc X264,x264
-  fourcc avc1,AVC1
-  fourcc davc,DAVC
-  format 0x10000005
-  driver ffmpeg
-  dll h264_vdpau
+  out VAAPI_H264
   out VDPAU_H264
+  out YV12,I420,IYUV
 
 videocodec coreavcwindows
   info "CoreAVC H.264 for x86 - http://corecodec.org/"
@@ -1008,40 +954,9 @@ videocodec ffodivx
   fourcc SIPP ; Samsung SHR-6040
   driver ffmpeg
   dll mpeg4 ;opendivx
-  out YV12,I420,IYUV
-
-videocodec ffodivxvdpau
-  info "FFmpeg MPEG-4,DIVX-4/5 (VDPAU)"
-  status working
-  fourcc FMP4,fmp4
-  fourcc DIVX,divx
-  fourcc DIV1,div1 divx
-  fourcc MP4S,mp4s ; ISO MPEG-4 Video V1
-  fourcc M4S2,m4s2
-  fourcc xvid,XVID,XviD,XVIX
-  fourcc DX50,dx50,BLZ0 DX50
-  fourcc mp4v,MP4V
-  format 0x4
-  fourcc UMP4
-  fourcc RMP4
-  fourcc 3IV2,3iv2  ; 3ivx Delta 4
-  fourcc DXGM
-  fourcc SEDG ; diskless camcorder Samsung Miniket VP-M110
-  fourcc SMP4,smp4 ; Samsung SMP4 video codec
-  fourcc VIDM ; vidm 4.01 codec
-  format 0x10000004  ; mpeg 4 es
-  fourcc m4cc,M4CC
-  fourcc hdx4,HDX4
-  fourcc FVFW,fvfw
-  fourcc FFDS
-  fourcc DCOD,MVXM,EM4A,PM4V
-  fourcc M4T3,DMK2,DIGI,INMC
-  fourcc EPHV,SN40
-  fourcc uldx,ULDX,VSPX
-  fourcc SIPP ; Samsung SHR-6040
-  driver ffmpeg
-  dll mpeg4_vdpau
+  out VAAPI_MPEG4
   out VDPAU_MPEG4
+  out YV12,I420,IYUV
 
 videocodec ffwv1f
   info "WV1F MPEG-4"
@@ -1577,6 +1492,7 @@ videocodec ffh263
   fourcc VX1K     ; Agora Labs VX1000S H263
   driver ffmpeg
   dll h263
+  out VAAPI_H263
   out YV12,I420,IYUV
 
 videocodec ffzygo
--- mplayer-1.0~rc4~try1.dsfg1.orig/gui/mplayer/gtk/opts.c
+++ mplayer-1.0~rc4~try1.dsfg1/gui/mplayer/gtk/opts.c
@@ -66,9 +66,11 @@ static GtkWidget * CLVDrivers;
        GtkWidget * prEFontName;
        GtkWidget * prEDVDDevice;
        GtkWidget * prECDRomDevice;
+static GtkWidget * EVHW;
 static GtkWidget * EVFM;
 static GtkWidget * EAFM;
 
+static GtkWidget * CBVHW;
 static GtkWidget * CBVFM;
 static GtkWidget * CBAFM;
 static GtkWidget * CBAudioEqualizer;
@@ -354,6 +356,26 @@ void ShowPreferences( void )
 // -- 5. page
  gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( CBNonInterlaved ),force_ni );
  if ( index_mode == 1 ) gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( CBIndex ),1 );
+
+ {
+     int     i;
+     GList * Items = NULL;
+     char  * name  = NULL;
+
+     Items = g_list_append(Items, MSGTR_PREFERENCES_None);
+     for (i = 0; i < HWACCEL_COUNT; i++) {
+         const char *hwaccel_name = get_video_hwaccel_name(i);
+         if (!hwaccel_name)
+             continue;
+         Items = g_list_append(Items, hwaccel_name);
+         if (video_hwaccel_name && !gstrcmp(video_hwaccel_name, get_video_hwaccel_short_name(i) ) ) name = hwaccel_name;
+     }
+     gtk_combo_set_popdown_strings(GTK_COMBO(CBVHW), Items);
+     g_list_free(Items);
+     if (name)
+         gtk_entry_set_text(GTK_ENTRY(EVHW), name);
+ }
+
  {
   int     i;
   GList * Items = NULL;
@@ -600,6 +622,17 @@ static void prButton( GtkButton * button
 	if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( CBIndex ) ) ) index_mode=1;
 
 	{
+            int i;
+            const char *tmp = gtk_entry_get_text(GTK_ENTRY(EVHW));
+            for (i = 0; i < HWACCEL_COUNT; i++) {
+                if (!gstrcmp(tmp, get_video_hwaccel_name(i))) {
+                    video_hwaccel_name = get_video_hwaccel_short_name(i);
+                    break;
+                }
+            }
+        }
+
+	{
 	 int i;
 	 const char * tmp = gtk_entry_get_text( GTK_ENTRY( EVFM ) );
          for( i=0;mpcodecs_vd_drivers[i];i++ )
@@ -1199,6 +1232,20 @@ GtkWidget * create_Preferences( void )
 
   hbox5=AddHBox( vbox602,1 );
 
+  AddLabel( MSGTR_PREFERENCES_VideoHardwareAcceleration,hbox5 );
+
+  CBVHW=gtk_combo_new();
+  gtk_widget_set_name( CBVHW,"CBVHW" );
+  gtk_widget_show( CBVHW );
+  gtk_box_pack_start( GTK_BOX( hbox5 ),CBVHW,TRUE,TRUE,0 );
+
+  EVHW=GTK_COMBO( CBVHW )->entry;
+  gtk_widget_set_name( EVHW,"CEVHW" );
+  gtk_entry_set_editable( GTK_ENTRY( EVHW ),FALSE );
+  gtk_widget_show( EVHW );
+
+  hbox5=AddHBox( vbox602,1 );
+
   AddLabel( MSGTR_PREFERENCES_VideoCodecFamily,hbox5 );
 
   CBVFM=gtk_combo_new();
--- mplayer-1.0~rc4~try1.dsfg1.orig/help/help_mp-en.h
+++ mplayer-1.0~rc4~try1.dsfg1/help/help_mp-en.h
@@ -717,6 +717,7 @@ static const char help_text[]=
 #define MSGTR_PREFERENCES_IDX "Rebuild index table, if needed"
 #define MSGTR_PREFERENCES_VideoCodecFamily "Video codec family:"
 #define MSGTR_PREFERENCES_AudioCodecFamily "Audio codec family:"
+#define MSGTR_PREFERENCES_VideoHardwareAcceleration "Video hardware acceleration:"
 #define MSGTR_PREFERENCES_FRAME_OSD_Level "OSD level"
 #define MSGTR_PREFERENCES_FRAME_Subtitle "Subtitle"
 #define MSGTR_PREFERENCES_FRAME_Font "Font"
@@ -1653,6 +1654,7 @@ static const char help_text[]=
 #define MSGTR_MPCODECS_UnexpectedInitVoError "[VD_FFMPEG] Unexpected init_vo error.\n"
 #define MSGTR_MPCODECS_UnrecoverableErrorRenderBuffersNotTaken "[VD_FFMPEG] Unrecoverable error, render buffers not taken.\n"
 #define MSGTR_MPCODECS_OnlyBuffersAllocatedByVoXvmcAllowed "[VD_FFMPEG] Only buffers allocated by vo_xvmc allowed.\n"
+#define MSGTR_MPCODECS_VAAPIAcceleratedCodec "[VD_FFMPEG] VA API accelerated codec.\n"
 
 // libmpcodecs/ve_lavc.c
 #define MSGTR_MPCODECS_HighQualityEncodingSelected "[VE_LAVC] High quality encoding selected (non-realtime)!\n"
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/allcodecs.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/allcodecs.c
@@ -64,6 +64,13 @@ void avcodec_register_all(void)
     REGISTER_HWACCEL (WMV3_DXVA2, wmv3_dxva2);
     REGISTER_HWACCEL (WMV3_VAAPI, wmv3_vaapi);
 
+    REGISTER_HWACCEL (H264_VDPAU, h264_vdpau);
+    REGISTER_HWACCEL (MPEG1_VDPAU, mpeg1_vdpau);
+    REGISTER_HWACCEL (MPEG2_VDPAU, mpeg2_vdpau);
+    REGISTER_HWACCEL (MPEG4_VDPAU, mpeg4_vdpau);
+    REGISTER_HWACCEL (VC1_VDPAU, vc1_vdpau);
+    REGISTER_HWACCEL (WMV3_VDPAU, wmv3_vdpau);
+
     /* video codecs */
     REGISTER_DECODER (AASC, aasc);
     REGISTER_DECODER (AMV, amv);
@@ -112,7 +119,6 @@ void avcodec_register_all(void)
     REGISTER_DECODER (H263I, h263i);
     REGISTER_ENCODER (H263P, h263p);
     REGISTER_DECODER (H264, h264);
-    REGISTER_DECODER (H264_VDPAU, h264_vdpau);
     REGISTER_ENCDEC  (HUFFYUV, huffyuv);
     REGISTER_DECODER (IDCIN, idcin);
     REGISTER_DECODER (IFF_BYTERUN1, iff_byterun1);
@@ -136,10 +142,7 @@ void avcodec_register_all(void)
     REGISTER_ENCDEC  (MPEG1VIDEO, mpeg1video);
     REGISTER_ENCDEC  (MPEG2VIDEO, mpeg2video);
     REGISTER_ENCDEC  (MPEG4, mpeg4);
-    REGISTER_DECODER (MPEG4_VDPAU, mpeg4_vdpau);
     REGISTER_DECODER (MPEGVIDEO, mpegvideo);
-    REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau);
-    REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau);
     REGISTER_ENCDEC  (MSMPEG4V1, msmpeg4v1);
     REGISTER_ENCDEC  (MSMPEG4V2, msmpeg4v2);
     REGISTER_ENCDEC  (MSMPEG4V3, msmpeg4v3);
@@ -190,7 +193,6 @@ void avcodec_register_all(void)
     REGISTER_DECODER (V210X, v210x);
     REGISTER_DECODER (VB, vb);
     REGISTER_DECODER (VC1, vc1);
-    REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);
     REGISTER_DECODER (VCR1, vcr1);
     REGISTER_DECODER (VMDVIDEO, vmdvideo);
     REGISTER_DECODER (VMNC, vmnc);
@@ -203,7 +205,6 @@ void avcodec_register_all(void)
     REGISTER_ENCDEC  (WMV1, wmv1);
     REGISTER_ENCDEC  (WMV2, wmv2);
     REGISTER_DECODER (WMV3, wmv3);
-    REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau);
     REGISTER_DECODER (WNV1, wnv1);
     REGISTER_DECODER (XAN_WC3, xan_wc3);
     REGISTER_DECODER (XL, xl);
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/avcodec.h
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/avcodec.h
@@ -629,10 +629,6 @@ typedef struct RcOverride{
  */
 #define CODEC_CAP_SMALL_LAST_FRAME 0x0040
 /**
- * Codec can export data for HW decoding (VDPAU).
- */
-#define CODEC_CAP_HWACCEL_VDPAU    0x0080
-/**
  * Codec can output multiple frames per AVPacket
  * Normally demuxers return one frame at a time, demuxers which do not do
  * are connected to a parser to split what they return into proper frames.
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/error_resilience.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/error_resilience.c
@@ -759,7 +759,6 @@ void ff_er_frame_end(MpegEncContext *s){
 
     if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
        s->avctx->hwaccel ||
-       s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
        s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
        s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
 
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/h263dec.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/h263dec.c
@@ -33,7 +33,6 @@
 #include "h263_parser.h"
 #include "mpeg4video_parser.h"
 #include "msmpeg4.h"
-#include "vdpau_internal.h"
 #include "flv.h"
 #include "mpeg4video.h"
 
@@ -619,11 +618,6 @@ retry:
     if(MPV_frame_start(s, avctx) < 0)
         return -1;
 
-    if (CONFIG_MPEG4_VDPAU_DECODER && (s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)) {
-        ff_vdpau_mpeg4_decode_picture(s, s->gb.buffer, s->gb.buffer_end - s->gb.buffer);
-        goto frame_end;
-    }
-
     if (avctx->hwaccel) {
         if (avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer) < 0)
             return -1;
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/h264.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/h264.c
@@ -36,7 +36,6 @@
 #include "golomb.h"
 #include "mathops.h"
 #include "rectangle.h"
-#include "vdpau_internal.h"
 
 #include "cabac.h"
 
@@ -1632,9 +1631,6 @@ static void field_end(H264Context *h){
     s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264;
     s->current_picture_ptr->pict_type= s->pict_type;
 
-    if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_h264_set_reference_frames(s);
-
     if(!s->dropable) {
         ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
         h->prev_poc_msb= h->poc_msb;
@@ -1648,9 +1644,6 @@ static void field_end(H264Context *h){
             av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n");
     }
 
-    if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_h264_picture_complete(s);
-
     /*
      * FIXME: Error handling code does not seem to support interlaced
      * when slices span multiple rows
@@ -2686,8 +2679,6 @@ static void execute_decode_slices(H264Co
 
     if (s->avctx->hwaccel)
         return;
-    if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-        return;
     if(context_count == 1) {
         decode_slice(avctx, &h);
     } else {
@@ -2823,8 +2814,6 @@ static int decode_nal_units(H264Context
             if (h->current_slice == 1) {
                 if (s->avctx->hwaccel && s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0)
                     return -1;
-                if(CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-                    ff_vdpau_h264_picture_start(s);
             }
 
             s->current_picture_ptr->key_frame |=
@@ -2839,11 +2828,6 @@ static int decode_nal_units(H264Context
                     if (avctx->hwaccel->decode_slice(avctx, &buf[buf_index - consumed], consumed) < 0)
                         return -1;
                 }else
-                if(CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){
-                    static const uint8_t start_code[] = {0x00, 0x00, 0x01};
-                    ff_vdpau_add_data_chunk(s, start_code, sizeof(start_code));
-                    ff_vdpau_add_data_chunk(s, &buf[buf_index - consumed], consumed );
-                }else
                     context_count++;
             }
             break;
@@ -3373,20 +3357,3 @@ AVCodec h264_decoder = {
     .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
     .pix_fmts= ff_hwaccel_pixfmt_list_420,
 };
-
-#if CONFIG_H264_VDPAU_DECODER
-AVCodec h264_vdpau_decoder = {
-    "h264_vdpau",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_H264,
-    sizeof(H264Context),
-    ff_h264_decode_init,
-    NULL,
-    ff_h264_decode_end,
-    decode_frame,
-    CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
-    .flush= flush_dpb,
-    .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"),
-    .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_H264, PIX_FMT_NONE},
-};
-#endif
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/mpeg12.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/mpeg12.c
@@ -35,7 +35,6 @@
 #include "mpeg12data.h"
 #include "mpeg12decdata.h"
 #include "bytestream.h"
-#include "vdpau_internal.h"
 #include "xvmc_internal.h"
 
 //#undef NDEBUG
@@ -1226,12 +1225,7 @@ static enum PixelFormat mpeg_get_pixelfo
 
     if(avctx->xvmc_acceleration)
         return avctx->get_format(avctx,pixfmt_xvmc_mpg2_420);
-    else if(avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){
-        if(avctx->codec_id == CODEC_ID_MPEG1VIDEO)
-            return PIX_FMT_VDPAU_MPEG1;
-        else
-            return PIX_FMT_VDPAU_MPEG2;
-    }else{
+    else{
         if(s->chroma_format <  2)
             return avctx->get_format(avctx,ff_hwaccel_pixfmt_list_420);
         else if(s->chroma_format == 2)
@@ -1324,9 +1318,7 @@ static int mpeg_decode_postinit(AVCodecC
         avctx->pix_fmt = mpeg_get_pixelformat(avctx);
         avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
         //until then pix_fmt may be changed right after codec init
-        if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ||
-            avctx->hwaccel ||
-            s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU )
+        if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel )
             if( avctx->idct_algo == FF_IDCT_AUTO )
                 avctx->idct_algo = FF_IDCT_SIMPLE;
 
@@ -2065,8 +2057,7 @@ static int vcr2_init_sequence(AVCodecCon
     avctx->pix_fmt = mpeg_get_pixelformat(avctx);
     avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
 
-    if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel ||
-        s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU )
+    if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel )
         if( avctx->idct_algo == FF_IDCT_AUTO )
             avctx->idct_algo = FF_IDCT_SIMPLE;
 
@@ -2297,9 +2288,6 @@ static int decode_chunks(AVCodecContext
                         s2->error_count += s2->thread_context[i]->error_count;
                 }
 
-                if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-                    ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
-
                 if (slice_end(avctx, picture)) {
                     if(s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
                         *data_size = sizeof(AVPicture);
@@ -2446,11 +2434,6 @@ static int decode_chunks(AVCodecContext
                     return -1;
                 }
 
-                if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
-                    s->slice_count++;
-                    break;
-                }
-
                 if(avctx->thread_count > 1){
                     int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count;
                     if(threshold <= mb_y){
@@ -2575,36 +2558,3 @@ AVCodec mpeg_xvmc_decoder = {
 };
 
 #endif
-
-#if CONFIG_MPEG_VDPAU_DECODER
-AVCodec mpeg_vdpau_decoder = {
-    "mpegvideo_vdpau",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_MPEG2VIDEO,
-    sizeof(Mpeg1Context),
-    mpeg_decode_init,
-    NULL,
-    mpeg_decode_end,
-    mpeg_decode_frame,
-    CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
-    .flush= flush,
-    .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
-};
-#endif
-
-#if CONFIG_MPEG1_VDPAU_DECODER
-AVCodec mpeg1_vdpau_decoder = {
-    "mpeg1video_vdpau",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_MPEG1VIDEO,
-    sizeof(Mpeg1Context),
-    mpeg_decode_init,
-    NULL,
-    mpeg_decode_end,
-    mpeg_decode_frame,
-    CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
-    .flush= flush,
-    .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"),
-};
-#endif
-
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/mpeg4videodec.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/mpeg4videodec.c
@@ -2248,20 +2248,3 @@ AVCodec mpeg4_decoder = {
     .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
     .pix_fmts= ff_hwaccel_pixfmt_list_420,
 };
-
-
-#if CONFIG_MPEG4_VDPAU_DECODER
-AVCodec mpeg4_vdpau_decoder = {
-    "mpeg4_vdpau",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_MPEG4,
-    sizeof(MpegEncContext),
-    decode_init,
-    NULL,
-    ff_h263_decode_end,
-    ff_h263_decode_frame,
-    CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
-    .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"),
-    .pix_fmts= (const enum PixelFormat[]){PIX_FMT_VDPAU_MPEG4, PIX_FMT_NONE},
-};
-#endif
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/mpegvideo.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/mpegvideo.c
@@ -115,6 +115,7 @@ const enum PixelFormat ff_pixfmt_list_42
 const enum PixelFormat ff_hwaccel_pixfmt_list_420[] = {
     PIX_FMT_DXVA2_VLD,
     PIX_FMT_VAAPI_VLD,
+    PIX_FMT_VDPAU,
     PIX_FMT_YUV420P,
     PIX_FMT_NONE
 };
@@ -1051,7 +1052,6 @@ void MPV_frame_end(MpegEncContext *s)
     if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
         ff_xvmc_field_end(s);
     }else if(!s->avctx->hwaccel
-       && !(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
        && s->unrestricted_mv
        && s->current_picture.reference
        && !s->intra_only
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/vaapi_mpeg4.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/vaapi_mpeg4.c
@@ -54,42 +54,42 @@ static int vaapi_mpeg4_start_frame(AVCod
     pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG4));
     if (!pic_param)
         return -1;
-    pic_param->vop_width                                = s->width;
-    pic_param->vop_height                               = s->height;
-    pic_param->forward_reference_picture                = VA_INVALID_ID;
-    pic_param->backward_reference_picture               = VA_INVALID_ID;
-    pic_param->vol_fields.value                         = 0; /* reset all bits */
-    pic_param->vol_fields.bits.short_video_header       = avctx->codec->id == CODEC_ID_H263;
-    pic_param->vol_fields.bits.chroma_format            = CHROMA_420;
-    pic_param->vol_fields.bits.interlaced               = !s->progressive_sequence;
-    pic_param->vol_fields.bits.obmc_disable             = 1;
-    pic_param->vol_fields.bits.sprite_enable            = s->vol_sprite_usage;
-    pic_param->vol_fields.bits.sprite_warping_accuracy  = s->sprite_warping_accuracy;
-    pic_param->vol_fields.bits.quant_type               = s->mpeg_quant;
-    pic_param->vol_fields.bits.quarter_sample           = s->quarter_sample;
-    pic_param->vol_fields.bits.data_partitioned         = s->data_partitioning;
-    pic_param->vol_fields.bits.reversible_vlc           = s->rvlc;
-    pic_param->vol_fields.bits.resync_marker_disable    = !s->resync_marker;
-    pic_param->no_of_sprite_warping_points              = s->num_sprite_warping_points;
+    pic_param->vop_width                                               = s->width;
+    pic_param->vop_height                                              = s->height;
+    pic_param->forward_reference_picture                               = VA_INVALID_ID;
+    pic_param->backward_reference_picture                              = VA_INVALID_ID;
+    pic_param->BFV(vol_fields,value)                                   = 0; /* reset all bits */
+    pic_param->BFM(vol_fields,bits,short_video_header)                 = avctx->codec->id == CODEC_ID_H263;
+    pic_param->BFM(vol_fields,bits,chroma_format)                      = CHROMA_420;
+    pic_param->BFM(vol_fields,bits,interlaced)                         = !s->progressive_sequence;
+    pic_param->BFM(vol_fields,bits,obmc_disable)                       = 1;
+    pic_param->BFM(vol_fields,bits,sprite_enable)                      = s->vol_sprite_usage;
+    pic_param->BFM(vol_fields,bits,sprite_warping_accuracy)            = s->sprite_warping_accuracy;
+    pic_param->BFM(vol_fields,bits,quant_type)                         = s->mpeg_quant;
+    pic_param->BFM(vol_fields,bits,quarter_sample)                     = s->quarter_sample;
+    pic_param->BFM(vol_fields,bits,data_partitioned)                   = s->data_partitioning;
+    pic_param->BFM(vol_fields,bits,reversible_vlc)                     = s->rvlc;
+    NEW(pic_param->BFM(vol_fields,bits,resync_marker_disable)          = !s->resync_marker);
+    pic_param->no_of_sprite_warping_points                             = s->num_sprite_warping_points;
     for (i = 0; i < s->num_sprite_warping_points && i < 3; i++) {
-        pic_param->sprite_trajectory_du[i]              = s->sprite_traj[i][0];
-        pic_param->sprite_trajectory_dv[i]              = s->sprite_traj[i][1];
+        pic_param->sprite_trajectory_du[i]                             = s->sprite_traj[i][0];
+        pic_param->sprite_trajectory_dv[i]                             = s->sprite_traj[i][1];
     }
-    pic_param->quant_precision                          = s->quant_precision;
-    pic_param->vop_fields.value                         = 0; /* reset all bits */
-    pic_param->vop_fields.bits.vop_coding_type          = s->pict_type - FF_I_TYPE;
-    pic_param->vop_fields.bits.backward_reference_vop_coding_type = s->pict_type == FF_B_TYPE ? s->next_picture.pict_type - FF_I_TYPE : 0;
-    pic_param->vop_fields.bits.vop_rounding_type        = s->no_rounding;
-    pic_param->vop_fields.bits.intra_dc_vlc_thr         = mpeg4_get_intra_dc_vlc_thr(s);
-    pic_param->vop_fields.bits.top_field_first          = s->top_field_first;
-    pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan;
-    pic_param->vop_fcode_forward                        = s->f_code;
-    pic_param->vop_fcode_backward                       = s->b_code;
-    pic_param->vop_time_increment_resolution            = avctx->time_base.den;
-    pic_param->num_macroblocks_in_gob                   = s->mb_width * ff_h263_get_gob_height(s);
-    pic_param->num_gobs_in_vop                          = (s->mb_width * s->mb_height) / pic_param->num_macroblocks_in_gob;
-    pic_param->TRB                                      = s->pb_time;
-    pic_param->TRD                                      = s->pp_time;
+    pic_param->quant_precision                                         = s->quant_precision;
+    pic_param->BFV(vop_fields,value)                                   = 0; /* reset all bits */
+    pic_param->BFM(vop_fields,bits,vop_coding_type)                    = s->pict_type - FF_I_TYPE;
+    pic_param->BFM(vop_fields,bits,backward_reference_vop_coding_type) = s->pict_type == FF_B_TYPE ? s->next_picture.pict_type - FF_I_TYPE : 0;
+    pic_param->BFM(vop_fields,bits,vop_rounding_type)                  = s->no_rounding;
+    pic_param->BFM(vop_fields,bits,intra_dc_vlc_thr)                   = mpeg4_get_intra_dc_vlc_thr(s);
+    pic_param->BFM(vop_fields,bits,top_field_first)                    = s->top_field_first;
+    pic_param->BFM(vop_fields,bits,alternate_vertical_scan_flag)       = s->alternate_scan;
+    pic_param->vop_fcode_forward                                       = s->f_code;
+    pic_param->vop_fcode_backward                                      = s->b_code;
+    NEW(pic_param->vop_time_increment_resolution                       = avctx->time_base.den);
+    pic_param->num_macroblocks_in_gob                                  = s->mb_width * ff_h263_get_gob_height(s);
+    pic_param->num_gobs_in_vop                                         = (s->mb_width * s->mb_height) / pic_param->num_macroblocks_in_gob;
+    pic_param->TRB                                                     = s->pb_time;
+    pic_param->TRD                                                     = s->pp_time;
 
     if (s->pict_type == FF_B_TYPE)
         pic_param->backward_reference_picture = ff_vaapi_get_surface_id(&s->next_picture);
@@ -98,7 +98,7 @@ static int vaapi_mpeg4_start_frame(AVCod
 
     /* Fill in VAIQMatrixBufferMPEG4 */
     /* Only the first inverse quantisation method uses the weighthing matrices */
-    if (pic_param->vol_fields.bits.quant_type) {
+    if (pic_param->BFM(vol_fields,bits,quant_type)) {
         iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG4));
         if (!iq_matrix)
             return -1;
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/vaapi_vc1.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/vaapi_vc1.c
@@ -146,100 +146,100 @@ static int vaapi_vc1_start_frame(AVCodec
     pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferVC1));
     if (!pic_param)
         return -1;
-    pic_param->forward_reference_picture                            = VA_INVALID_ID;
-    pic_param->backward_reference_picture                           = VA_INVALID_ID;
-    pic_param->inloop_decoded_picture                               = VA_INVALID_ID;
-    pic_param->sequence_fields.value                                = 0; /* reset all bits */
-    pic_param->sequence_fields.bits.pulldown                        = v->broadcast;
-    pic_param->sequence_fields.bits.interlace                       = v->interlace;
-    pic_param->sequence_fields.bits.tfcntrflag                      = v->tfcntrflag;
-    pic_param->sequence_fields.bits.finterpflag                     = v->finterpflag;
-    pic_param->sequence_fields.bits.psf                             = v->psf;
-    pic_param->sequence_fields.bits.multires                        = v->multires;
-    pic_param->sequence_fields.bits.overlap                         = v->overlap;
-    pic_param->sequence_fields.bits.syncmarker                      = s->resync_marker;
-    pic_param->sequence_fields.bits.rangered                        = v->rangered;
-    pic_param->sequence_fields.bits.max_b_frames                    = s->avctx->max_b_frames;
-    pic_param->coded_width                                          = s->avctx->coded_width;
-    pic_param->coded_height                                         = s->avctx->coded_height;
-    pic_param->entrypoint_fields.value                              = 0; /* reset all bits */
-    pic_param->entrypoint_fields.bits.broken_link                   = v->broken_link;
-    pic_param->entrypoint_fields.bits.closed_entry                  = v->closed_entry;
-    pic_param->entrypoint_fields.bits.panscan_flag                  = v->panscanflag;
-    pic_param->entrypoint_fields.bits.loopfilter                    = s->loop_filter;
-    pic_param->conditional_overlap_flag                             = v->condover;
-    pic_param->fast_uvmc_flag                                       = v->fastuvmc;
-    pic_param->range_mapping_fields.value                           = 0; /* reset all bits */
-    pic_param->range_mapping_fields.bits.luma_flag                  = v->range_mapy_flag;
-    pic_param->range_mapping_fields.bits.luma                       = v->range_mapy;
-    pic_param->range_mapping_fields.bits.chroma_flag                = v->range_mapuv_flag;
-    pic_param->range_mapping_fields.bits.chroma                     = v->range_mapuv;
-    pic_param->b_picture_fraction                                   = v->bfraction_lut_index;
-    pic_param->cbp_table                                            = v->cbpcy_vlc ? v->cbpcy_vlc - ff_vc1_cbpcy_p_vlc : 0;
-    pic_param->mb_mode_table                                        = 0; /* XXX: interlaced frame */
-    pic_param->range_reduction_frame                                = v->rangeredfrm;
-    pic_param->rounding_control                                     = v->rnd;
-    pic_param->post_processing                                      = v->postproc;
-    pic_param->picture_resolution_index                             = v->respic;
-    pic_param->luma_scale                                           = v->lumscale;
-    pic_param->luma_shift                                           = v->lumshift;
-    pic_param->picture_fields.value                                 = 0; /* reset all bits */
-    pic_param->picture_fields.bits.picture_type                     = vc1_get_PTYPE(v);
-    pic_param->picture_fields.bits.frame_coding_mode                = v->fcm;
-    pic_param->picture_fields.bits.top_field_first                  = v->tff;
-    pic_param->picture_fields.bits.is_first_field                   = v->fcm == 0; /* XXX: interlaced frame */
-    pic_param->picture_fields.bits.intensity_compensation           = v->mv_mode == MV_PMODE_INTENSITY_COMP;
-    pic_param->raw_coding.value                                     = 0; /* reset all bits */
-    pic_param->raw_coding.flags.mv_type_mb                          = v->mv_type_is_raw;
-    pic_param->raw_coding.flags.direct_mb                           = v->dmb_is_raw;
-    pic_param->raw_coding.flags.skip_mb                             = v->skip_is_raw;
-    pic_param->raw_coding.flags.field_tx                            = 0; /* XXX: interlaced frame */
-    pic_param->raw_coding.flags.forward_mb                          = 0; /* XXX: interlaced frame */
-    pic_param->raw_coding.flags.ac_pred                             = v->acpred_is_raw;
-    pic_param->raw_coding.flags.overflags                           = v->overflg_is_raw;
-    pic_param->bitplane_present.value                               = 0; /* reset all bits */
-    pic_param->bitplane_present.flags.bp_mv_type_mb                 = vc1_has_MVTYPEMB_bitplane(v);
-    pic_param->bitplane_present.flags.bp_direct_mb                  = vc1_has_DIRECTMB_bitplane(v);
-    pic_param->bitplane_present.flags.bp_skip_mb                    = vc1_has_SKIPMB_bitplane(v);
-    pic_param->bitplane_present.flags.bp_field_tx                   = 0; /* XXX: interlaced frame */
-    pic_param->bitplane_present.flags.bp_forward_mb                 = 0; /* XXX: interlaced frame */
-    pic_param->bitplane_present.flags.bp_ac_pred                    = vc1_has_ACPRED_bitplane(v);
-    pic_param->bitplane_present.flags.bp_overflags                  = vc1_has_OVERFLAGS_bitplane(v);
-    pic_param->reference_fields.value                               = 0; /* reset all bits */
-    pic_param->reference_fields.bits.reference_distance_flag        = v->refdist_flag;
-    pic_param->reference_fields.bits.reference_distance             = 0; /* XXX: interlaced frame */
-    pic_param->reference_fields.bits.num_reference_pictures         = 0; /* XXX: interlaced frame */
-    pic_param->reference_fields.bits.reference_field_pic_indicator  = 0; /* XXX: interlaced frame */
-    pic_param->mv_fields.value                                      = 0; /* reset all bits */
-    pic_param->mv_fields.bits.mv_mode                               = vc1_get_MVMODE(v);
-    pic_param->mv_fields.bits.mv_mode2                              = vc1_get_MVMODE2(v);
-    pic_param->mv_fields.bits.mv_table                              = s->mv_table_index;
-    pic_param->mv_fields.bits.two_mv_block_pattern_table            = 0; /* XXX: interlaced frame */
-    pic_param->mv_fields.bits.four_mv_switch                        = 0; /* XXX: interlaced frame */
-    pic_param->mv_fields.bits.four_mv_block_pattern_table           = 0; /* XXX: interlaced frame */
-    pic_param->mv_fields.bits.extended_mv_flag                      = v->extended_mv;
-    pic_param->mv_fields.bits.extended_mv_range                     = v->mvrange;
-    pic_param->mv_fields.bits.extended_dmv_flag                     = v->extended_dmv;
-    pic_param->mv_fields.bits.extended_dmv_range                    = 0; /* XXX: interlaced frame */
-    pic_param->pic_quantizer_fields.value                           = 0; /* reset all bits */
-    pic_param->pic_quantizer_fields.bits.dquant                     = v->dquant;
-    pic_param->pic_quantizer_fields.bits.quantizer                  = v->quantizer_mode;
-    pic_param->pic_quantizer_fields.bits.half_qp                    = v->halfpq;
-    pic_param->pic_quantizer_fields.bits.pic_quantizer_scale        = v->pq;
-    pic_param->pic_quantizer_fields.bits.pic_quantizer_type         = v->pquantizer;
-    pic_param->pic_quantizer_fields.bits.dq_frame                   = v->dquantfrm;
-    pic_param->pic_quantizer_fields.bits.dq_profile                 = v->dqprofile;
-    pic_param->pic_quantizer_fields.bits.dq_sb_edge                 = v->dqprofile == DQPROFILE_SINGLE_EDGE  ? v->dqsbedge : 0;
-    pic_param->pic_quantizer_fields.bits.dq_db_edge                 = v->dqprofile == DQPROFILE_DOUBLE_EDGES ? v->dqsbedge : 0;
-    pic_param->pic_quantizer_fields.bits.dq_binary_level            = v->dqbilevel;
-    pic_param->pic_quantizer_fields.bits.alt_pic_quantizer          = v->altpq;
-    pic_param->transform_fields.value                               = 0; /* reset all bits */
-    pic_param->transform_fields.bits.variable_sized_transform_flag  = v->vstransform;
-    pic_param->transform_fields.bits.mb_level_transform_type_flag   = v->ttmbf;
-    pic_param->transform_fields.bits.frame_level_transform_type     = v->ttfrm;
-    pic_param->transform_fields.bits.transform_ac_codingset_idx1    = v->c_ac_table_index;
-    pic_param->transform_fields.bits.transform_ac_codingset_idx2    = v->y_ac_table_index;
-    pic_param->transform_fields.bits.intra_transform_dc_table       = v->s.dc_table_index;
+    pic_param->forward_reference_picture                                 = VA_INVALID_ID;
+    pic_param->backward_reference_picture                                = VA_INVALID_ID;
+    pic_param->inloop_decoded_picture                                    = VA_INVALID_ID;
+    pic_param->BFV(sequence_fields,value)                                = 0; /* reset all bits */
+    NEW(pic_param->BFM(sequence_fields,bits,pulldown)                    = v->broadcast);
+    pic_param->BFM(sequence_fields,bits,interlace)                       = v->interlace;
+    NEW(pic_param->BFM(sequence_fields,bits,tfcntrflag)                  = v->tfcntrflag);
+    NEW(pic_param->BFM(sequence_fields,bits,finterpflag)                 = v->finterpflag);
+    NEW(pic_param->BFM(sequence_fields,bits,psf)                         = v->psf);
+    NEW(pic_param->BFM(sequence_fields,bits,multires)                    = v->multires);
+    pic_param->BFM(sequence_fields,bits,overlap)                         = v->overlap;
+    pic_param->BFM(sequence_fields,bits,syncmarker)                      = s->resync_marker;
+    NEW(pic_param->BFM(sequence_fields,bits,rangered)                    = v->rangered);
+    NEW(pic_param->BFM(sequence_fields,bits,max_b_frames)                = s->avctx->max_b_frames);
+    pic_param->coded_width                                               = s->avctx->coded_width;
+    pic_param->coded_height                                              = s->avctx->coded_height;
+    NEW(pic_param->BFV(entrypoint_fields,value)                          = 0); /* reset all bits */
+    pic_param->BFM(entrypoint_fields,bits,broken_link)                   = v->broken_link;
+    pic_param->BFM(entrypoint_fields,bits,closed_entry)                  = v->closed_entry;
+    NEW(pic_param->BFM(entrypoint_fields,bits,panscan_flag)              = v->panscanflag);
+    pic_param->BFM(entrypoint_fields,bits,loopfilter)                    = s->loop_filter;
+    pic_param->conditional_overlap_flag                                  = v->condover;
+    pic_param->fast_uvmc_flag                                            = v->fastuvmc;
+    pic_param->BFV(range_mapping_fields,value)                           = 0; /* reset all bits */
+    pic_param->BFMP(range_mapping,range_mapping_fields,bits,luma_flag)   = v->range_mapy_flag;
+    pic_param->BFMP(range_mapping,range_mapping_fields,bits,luma)        = v->range_mapy;
+    pic_param->BFMP(range_mapping,range_mapping_fields,bits,chroma_flag) = v->range_mapuv_flag;
+    pic_param->BFMP(range_mapping,range_mapping_fields,bits,chroma)      = v->range_mapuv;
+    pic_param->b_picture_fraction                                        = v->bfraction_lut_index;
+    pic_param->cbp_table                                                 = v->cbpcy_vlc ? v->cbpcy_vlc - ff_vc1_cbpcy_p_vlc : 0;
+    pic_param->mb_mode_table                                             = 0; /* XXX: interlaced frame */
+    pic_param->range_reduction_frame                                     = v->rangeredfrm;
+    pic_param->rounding_control                                          = v->rnd;
+    pic_param->post_processing                                           = v->postproc;
+    pic_param->picture_resolution_index                                  = v->respic;
+    pic_param->luma_scale                                                = v->lumscale;
+    pic_param->luma_shift                                                = v->lumshift;
+    pic_param->BFV(picture_fields,value)                                 = 0; /* reset all bits */
+    pic_param->BFM(picture_fields,bits,picture_type)                     = vc1_get_PTYPE(v);
+    pic_param->BFM(picture_fields,bits,frame_coding_mode)                = v->fcm;
+    pic_param->BFM(picture_fields,bits,top_field_first)                  = v->tff;
+    pic_param->BFM(picture_fields,bits,is_first_field)                   = v->fcm == 0; /* XXX: interlaced frame */
+    pic_param->BFM(picture_fields,bits,intensity_compensation)           = v->mv_mode == MV_PMODE_INTENSITY_COMP;
+    pic_param->BFV(V_raw_coding,value)                                   = 0; /* reset all bits */
+    pic_param->BFM(M_raw_coding,flags,mv_type_mb)                        = v->mv_type_is_raw;
+    pic_param->BFM(M_raw_coding,flags,direct_mb)                         = v->dmb_is_raw;
+    pic_param->BFM(M_raw_coding,flags,skip_mb)                           = v->skip_is_raw;
+    pic_param->BFM(M_raw_coding,flags,field_tx)                          = 0; /* XXX: interlaced frame */
+    pic_param->BFM(M_raw_coding,flags,forward_mb)                        = 0; /* XXX: interlaced frame */
+    pic_param->BFM(M_raw_coding,flags,ac_pred)                           = v->acpred_is_raw;
+    pic_param->BFM(M_raw_coding,flags,overflags)                         = v->overflg_is_raw;
+    pic_param->BFV(V_bitplane_present,value)                             = 0; /* reset all bits */
+    pic_param->BFM(M_bitplane_present,flags,bp_mv_type_mb)               = vc1_has_MVTYPEMB_bitplane(v);
+    pic_param->BFM(M_bitplane_present,flags,bp_direct_mb)                = vc1_has_DIRECTMB_bitplane(v);
+    pic_param->BFM(M_bitplane_present,flags,bp_skip_mb)                  = vc1_has_SKIPMB_bitplane(v);
+    pic_param->BFM(M_bitplane_present,flags,bp_field_tx)                 = 0; /* XXX: interlaced frame */
+    pic_param->BFM(M_bitplane_present,flags,bp_forward_mb)               = 0; /* XXX: interlaced frame */
+    pic_param->BFM(M_bitplane_present,flags,bp_ac_pred)                  = vc1_has_ACPRED_bitplane(v);
+    pic_param->BFM(M_bitplane_present,flags,bp_overflags)                = vc1_has_OVERFLAGS_bitplane(v);
+    pic_param->BFV(reference_fields,value)                               = 0; /* reset all bits */
+    pic_param->BFM(reference_fields,bits,reference_distance_flag)        = v->refdist_flag;
+    pic_param->BFM(reference_fields,bits,reference_distance)             = 0; /* XXX: interlaced frame */
+    pic_param->BFM(reference_fields,bits,num_reference_pictures)         = 0; /* XXX: interlaced frame */
+    pic_param->BFM(reference_fields,bits,reference_field_pic_indicator)  = 0; /* XXX: interlaced frame */
+    pic_param->BFV(mv_fields,value)                                      = 0; /* reset all bits */
+    pic_param->BFM(mv_fields,bits,mv_mode)                               = vc1_get_MVMODE(v);
+    pic_param->BFM(mv_fields,bits,mv_mode2)                              = vc1_get_MVMODE2(v);
+    pic_param->BFM(mv_fields,bits,mv_table)                              = s->mv_table_index;
+    pic_param->BFM(mv_fields,bits,two_mv_block_pattern_table)            = 0; /* XXX: interlaced frame */
+    pic_param->BFM(mv_fields,bits,four_mv_switch)                        = 0; /* XXX: interlaced frame */
+    pic_param->BFM(mv_fields,bits,four_mv_block_pattern_table)           = 0; /* XXX: interlaced frame */
+    pic_param->BFM(mv_fields,bits,extended_mv_flag)                      = v->extended_mv;
+    pic_param->BFM(mv_fields,bits,extended_mv_range)                     = v->mvrange;
+    pic_param->BFM(mv_fields,bits,extended_dmv_flag)                     = v->extended_dmv;
+    pic_param->BFM(mv_fields,bits,extended_dmv_range)                    = 0; /* XXX: interlaced frame */
+    pic_param->BFV(pic_quantizer_fields,value)                           = 0; /* reset all bits */
+    pic_param->BFM(pic_quantizer_fields,bits,dquant)                     = v->dquant;
+    pic_param->BFM(pic_quantizer_fields,bits,quantizer)                  = v->quantizer_mode;
+    pic_param->BFM(pic_quantizer_fields,bits,half_qp)                    = v->halfpq;
+    pic_param->BFM(pic_quantizer_fields,bits,pic_quantizer_scale)        = v->pq;
+    pic_param->BFM(pic_quantizer_fields,bits,pic_quantizer_type)         = v->pquantizer;
+    pic_param->BFM(pic_quantizer_fields,bits,dq_frame)                   = v->dquantfrm;
+    pic_param->BFM(pic_quantizer_fields,bits,dq_profile)                 = v->dqprofile;
+    pic_param->BFM(pic_quantizer_fields,bits,dq_sb_edge)                 = v->dqprofile == DQPROFILE_SINGLE_EDGE  ? v->dqsbedge : 0;
+    pic_param->BFM(pic_quantizer_fields,bits,dq_db_edge)                 = v->dqprofile == DQPROFILE_DOUBLE_EDGES ? v->dqsbedge : 0;
+    pic_param->BFM(pic_quantizer_fields,bits,dq_binary_level)            = v->dqbilevel;
+    pic_param->BFM(pic_quantizer_fields,bits,alt_pic_quantizer)          = v->altpq;
+    pic_param->BFV(transform_fields,value)                               = 0; /* reset all bits */
+    pic_param->BFM(transform_fields,bits,variable_sized_transform_flag)  = v->vstransform;
+    pic_param->BFM(transform_fields,bits,mb_level_transform_type_flag)   = v->ttmbf;
+    pic_param->BFM(transform_fields,bits,frame_level_transform_type)     = v->ttfrm;
+    pic_param->BFM(transform_fields,bits,transform_ac_codingset_idx1)    = v->c_ac_table_index;
+    pic_param->BFM(transform_fields,bits,transform_ac_codingset_idx2)    = v->y_ac_table_index;
+    pic_param->BFM(transform_fields,bits,intra_transform_dc_table)       = v->s.dc_table_index;
 
     switch (s->pict_type) {
     case FF_B_TYPE:
@@ -250,29 +250,29 @@ static int vaapi_vc1_start_frame(AVCodec
         break;
     }
 
-    if (pic_param->bitplane_present.value) {
+    if (pic_param->BFV(V_bitplane_present,value)) {
         uint8_t *bitplane;
         const uint8_t *ff_bp[3];
         int x, y, n;
 
         switch (s->pict_type) {
         case FF_P_TYPE:
-            ff_bp[0] = pic_param->bitplane_present.flags.bp_direct_mb  ? v->direct_mb_plane    : NULL;
-            ff_bp[1] = pic_param->bitplane_present.flags.bp_skip_mb    ? s->mbskip_table       : NULL;
-            ff_bp[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? v->mv_type_mb_plane   : NULL;
+            ff_bp[0] = pic_param->BFM(M_bitplane_present,flags,bp_direct_mb)  ? v->direct_mb_plane    : NULL;
+            ff_bp[1] = pic_param->BFM(M_bitplane_present,flags,bp_skip_mb)    ? s->mbskip_table       : NULL;
+            ff_bp[2] = pic_param->BFM(M_bitplane_present,flags,bp_mv_type_mb) ? v->mv_type_mb_plane   : NULL;
             break;
         case FF_B_TYPE:
             if (!v->bi_type) {
-                ff_bp[0] = pic_param->bitplane_present.flags.bp_direct_mb ? v->direct_mb_plane : NULL;
-                ff_bp[1] = pic_param->bitplane_present.flags.bp_skip_mb   ? s->mbskip_table    : NULL;
+                ff_bp[0] = pic_param->BFM(M_bitplane_present,flags,bp_direct_mb) ? v->direct_mb_plane : NULL;
+                ff_bp[1] = pic_param->BFM(M_bitplane_present,flags,bp_skip_mb)   ? s->mbskip_table    : NULL;
                 ff_bp[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */
                 break;
             }
             /* fall-through (BI-type) */
         case FF_I_TYPE:
             ff_bp[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */
-            ff_bp[1] = pic_param->bitplane_present.flags.bp_ac_pred    ? v->acpred_plane       : NULL;
-            ff_bp[2] = pic_param->bitplane_present.flags.bp_overflags  ? v->over_flags_plane   : NULL;
+            ff_bp[1] = pic_param->BFM(M_bitplane_present,flags,bp_ac_pred)    ? v->acpred_plane       : NULL;
+            ff_bp[2] = pic_param->BFM(M_bitplane_present,flags,bp_overflags)  ? v->over_flags_plane   : NULL;
             break;
         default:
             ff_bp[0] = NULL;
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/vaapi_h264.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/vaapi_h264.c
@@ -28,6 +28,60 @@
  *  structures for H.264 decoding.
  */
 
+/** Parses ENV environment variable expecting "yes" | "no" values. */
+static int getenv_yesno(const char *env, int *pval)
+{
+    int val;
+    const char *env_str;
+
+    env_str = getenv(env);
+    if (!env_str)
+        return -1;
+
+    if (strcmp(env_str, "1") == 0 || strcmp(env_str, "yes") == 0)
+        val = 1;
+    else if (strcmp(env_str, "0") == 0 || strcmp(env_str, "no") == 0)
+        val = 0;
+    else
+        return -1;
+
+    if (pval)
+        *pval = val;
+    return 0;
+}
+
+/**
+ * Use old GMA500 workaround for DPB. It requires other pictures than
+ * those marked as "used for reference".
+ */
+static int get_use_gma500_workaround(struct vaapi_context *vactx)
+{
+    int gma500_workaround_env;
+    const char *vendor_string;
+
+    if (getenv_yesno("GMA500_WORKAROUND", &gma500_workaround_env) < 0)
+        return 0;
+    if (!gma500_workaround_env)
+        return 0;
+
+    vendor_string = vaQueryVendorString(vactx->display);
+    if (vendor_string && strstr(vendor_string, "Intel")) {
+        if (strstr(vendor_string, "GMA500"))
+            return 1;
+        if (strstr(vendor_string, "Embedded Graphics Driver"))
+            return 1;
+    }
+    return 0;
+}
+
+static inline int use_gma500_workaround(struct vaapi_context *vactx)
+{
+    static int gma500_workaround = -1;
+    if (gma500_workaround < 0)
+        gma500_workaround = get_use_gma500_workaround(vactx);
+    return gma500_workaround;
+}
+
 /**
  * Initializes an empty VA API picture.
  *
@@ -56,8 +110,8 @@ static void fill_vaapi_pic(VAPictureH264
     if (pic_structure == 0)
         pic_structure = pic->reference;
 
-    va_pic->picture_id = ff_vaapi_get_surface_id(pic);
-    va_pic->frame_idx  = pic->long_ref ? pic->pic_id : pic->frame_num;
+    va_pic->picture_id    = ff_vaapi_get_surface_id(pic);
+    NEW(va_pic->frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num);
 
     va_pic->flags      = 0;
     if (pic_structure != PICT_FRAME)
@@ -123,6 +177,7 @@ static int fill_vaapi_ReferenceFrames(VA
 {
     DPB dpb;
     int i;
+    unsigned int list;
 
     dpb.size     = 0;
     dpb.max_size = FF_ARRAY_ELEMS(pic_param->ReferenceFrames);
@@ -130,6 +185,17 @@ static int fill_vaapi_ReferenceFrames(VA
     for (i = 0; i < dpb.max_size; i++)
         init_vaapi_pic(&dpb.va_pics[i]);
 
+    if (use_gma500_workaround(h->s.avctx->hwaccel_context)) {
+        /* XXX: this is really wrong */
+        for (list = 0; list < h->list_count; list++)
+            for (i = 0; i < (int)h->ref_count[list]; i++) {
+                Picture * const pic = &h->ref_list[list][i];
+                if (pic->reference && dpb_add(&dpb, pic) < 0)
+                    return -1;
+            }
+        return 0;
+    }
+
     for (i = 0; i < h->short_ref_count; i++) {
         Picture * const pic = h->short_ref[i];
         if (pic && pic->reference && dpb_add(&dpb, pic) < 0)
@@ -238,42 +304,42 @@ static int start_frame(AVCodecContext
     fill_vaapi_pic(&pic_param->CurrPic, s->current_picture_ptr, s->picture_structure);
     if (fill_vaapi_ReferenceFrames(pic_param, h) < 0)
         return -1;
-    pic_param->picture_width_in_mbs_minus1                      = s->mb_width - 1;
-    pic_param->picture_height_in_mbs_minus1                     = s->mb_height - 1;
-    pic_param->bit_depth_luma_minus8                            = h->sps.bit_depth_luma - 8;
-    pic_param->bit_depth_chroma_minus8                          = h->sps.bit_depth_chroma - 8;
-    pic_param->num_ref_frames                                   = h->sps.ref_frame_count;
-    pic_param->seq_fields.value                                 = 0; /* reset all bits */
-    pic_param->seq_fields.bits.chroma_format_idc                = h->sps.chroma_format_idc;
-    pic_param->seq_fields.bits.residual_colour_transform_flag   = h->sps.residual_color_transform_flag; /* XXX: only for 4:4:4 high profile? */
-    pic_param->seq_fields.bits.gaps_in_frame_num_value_allowed_flag = h->sps.gaps_in_frame_num_allowed_flag;
-    pic_param->seq_fields.bits.frame_mbs_only_flag              = h->sps.frame_mbs_only_flag;
-    pic_param->seq_fields.bits.mb_adaptive_frame_field_flag     = h->sps.mb_aff;
-    pic_param->seq_fields.bits.direct_8x8_inference_flag        = h->sps.direct_8x8_inference_flag;
-    pic_param->seq_fields.bits.MinLumaBiPredSize8x8             = h->sps.level_idc >= 31; /* A.3.3.2 */
-    pic_param->seq_fields.bits.log2_max_frame_num_minus4        = h->sps.log2_max_frame_num - 4;
-    pic_param->seq_fields.bits.pic_order_cnt_type               = h->sps.poc_type;
-    pic_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4;
-    pic_param->seq_fields.bits.delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag;
-    pic_param->num_slice_groups_minus1                          = h->pps.slice_group_count - 1;
-    pic_param->slice_group_map_type                             = h->pps.mb_slice_group_map_type;
-    pic_param->slice_group_change_rate_minus1                   = 0; /* XXX: unimplemented in FFmpeg */
-    pic_param->pic_init_qp_minus26                              = h->pps.init_qp - 26;
-    pic_param->pic_init_qs_minus26                              = h->pps.init_qs - 26;
-    pic_param->chroma_qp_index_offset                           = h->pps.chroma_qp_index_offset[0];
-    pic_param->second_chroma_qp_index_offset                    = h->pps.chroma_qp_index_offset[1];
-    pic_param->pic_fields.value                                 = 0; /* reset all bits */
-    pic_param->pic_fields.bits.entropy_coding_mode_flag         = h->pps.cabac;
-    pic_param->pic_fields.bits.weighted_pred_flag               = h->pps.weighted_pred;
-    pic_param->pic_fields.bits.weighted_bipred_idc              = h->pps.weighted_bipred_idc;
-    pic_param->pic_fields.bits.transform_8x8_mode_flag          = h->pps.transform_8x8_mode;
-    pic_param->pic_fields.bits.field_pic_flag                   = s->picture_structure != PICT_FRAME;
-    pic_param->pic_fields.bits.constrained_intra_pred_flag      = h->pps.constrained_intra_pred;
-    pic_param->pic_fields.bits.pic_order_present_flag           = h->pps.pic_order_present;
-    pic_param->pic_fields.bits.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
-    pic_param->pic_fields.bits.redundant_pic_cnt_present_flag   = h->pps.redundant_pic_cnt_present;
-    pic_param->pic_fields.bits.reference_pic_flag               = h->nal_ref_idc != 0;
-    pic_param->frame_num                                        = h->frame_num;
+    pic_param->picture_width_in_mbs_minus1                              = s->mb_width - 1;
+    pic_param->picture_height_in_mbs_minus1                             = s->mb_height - 1;
+    pic_param->bit_depth_luma_minus8                                    = h->sps.bit_depth_luma - 8;
+    pic_param->bit_depth_chroma_minus8                                  = h->sps.bit_depth_chroma - 8;
+    pic_param->num_ref_frames                                           = h->sps.ref_frame_count;
+    pic_param->BFV(seq_fields,value)                                    = 0; /* reset all bits */
+    pic_param->BFM(seq_fields,bits,chroma_format_idc)                   = h->sps.chroma_format_idc;
+    pic_param->BFM(seq_fields,bits,residual_colour_transform_flag)      = h->sps.residual_color_transform_flag; /* XXX: only for 4:4:4 high profile? */
+    NEW(pic_param->BFM(seq_fields,bits,gaps_in_frame_num_value_allowed_flag) = h->sps.gaps_in_frame_num_allowed_flag);
+    pic_param->BFM(seq_fields,bits,frame_mbs_only_flag)                 = h->sps.frame_mbs_only_flag;
+    pic_param->BFM(seq_fields,bits,mb_adaptive_frame_field_flag)        = h->sps.mb_aff;
+    pic_param->BFM(seq_fields,bits,direct_8x8_inference_flag)           = h->sps.direct_8x8_inference_flag;
+    pic_param->BFM(seq_fields,bits,MinLumaBiPredSize8x8)                = h->sps.level_idc >= 31; /* A.3.3.2 */
+    NEW(pic_param->BFM(seq_fields,bits,log2_max_frame_num_minus4)       = h->sps.log2_max_frame_num - 4);
+    NEW(pic_param->BFM(seq_fields,bits,pic_order_cnt_type)              = h->sps.poc_type);
+    NEW(pic_param->BFM(seq_fields,bits,log2_max_pic_order_cnt_lsb_minus4) = h->sps.log2_max_poc_lsb - 4);
+    NEW(pic_param->BFM(seq_fields,bits,delta_pic_order_always_zero_flag)  = h->sps.delta_pic_order_always_zero_flag);
+    pic_param->num_slice_groups_minus1                                  = h->pps.slice_group_count - 1;
+    pic_param->slice_group_map_type                                     = h->pps.mb_slice_group_map_type;
+    NEW(pic_param->slice_group_change_rate_minus1                       = 0); /* XXX: unimplemented in FFmpeg */
+    pic_param->pic_init_qp_minus26                                      = h->pps.init_qp - 26;
+    NEW(pic_param->pic_init_qs_minus26                                  = h->pps.init_qs - 26);
+    pic_param->chroma_qp_index_offset                                   = h->pps.chroma_qp_index_offset[0];
+    pic_param->second_chroma_qp_index_offset                            = h->pps.chroma_qp_index_offset[1];
+    pic_param->BFV(pic_fields,value)                                    = 0; /* reset all bits */
+    pic_param->BFM(pic_fields,bits,entropy_coding_mode_flag)            = h->pps.cabac;
+    pic_param->BFM(pic_fields,bits,weighted_pred_flag)                  = h->pps.weighted_pred;
+    pic_param->BFM(pic_fields,bits,weighted_bipred_idc)                 = h->pps.weighted_bipred_idc;
+    pic_param->BFM(pic_fields,bits,transform_8x8_mode_flag)             = h->pps.transform_8x8_mode;
+    pic_param->BFM(pic_fields,bits,field_pic_flag)                      = s->picture_structure != PICT_FRAME;
+    pic_param->BFM(pic_fields,bits,constrained_intra_pred_flag)         = h->pps.constrained_intra_pred;
+    NEW(pic_param->BFM(pic_fields,bits,pic_order_present_flag)          = h->pps.pic_order_present);
+    NEW(pic_param->BFM(pic_fields,bits,deblocking_filter_control_present_flag) = h->pps.deblocking_filter_parameters_present);
+    NEW(pic_param->BFM(pic_fields,bits,redundant_pic_cnt_present_flag)  = h->pps.redundant_pic_cnt_present);
+    NEW(pic_param->BFM(pic_fields,bits,reference_pic_flag)              = h->nal_ref_idc != 0);
+    pic_param->frame_num                                                = h->frame_num;
 
     /* Fill in VAIQMatrixBufferH264. */
     iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferH264));
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/vdpau.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/vdpau.c
@@ -30,7 +30,6 @@
 #include <assert.h>
 
 #include "vdpau.h"
-#include "vdpau_internal.h"
 
 /**
  * \addtogroup VDPAU_Decoding
@@ -38,15 +37,57 @@
  * @{
  */
 
-void ff_vdpau_h264_set_reference_frames(MpegEncContext *s)
+static void vdpau_h264_fill_field_order_cnt(int32_t field_order_cnt[2], Picture *pic, int pic_structure)
 {
-    H264Context *h = s->avctx->priv_data;
+    int i;
+    for (i = 0; i < 2; i++) {
+        const int poc = pic->field_poc[i];
+        field_order_cnt[i] = poc != INT_MAX ? poc : 0;
+    }
+}
+
+static void vdpau_h264_init_picture(VdpReferenceFrameH264 *rf)
+{
+    rf->surface             = VDP_INVALID_HANDLE;
+    rf->is_long_term        = 0;
+    rf->top_is_reference    = 0;
+    rf->bottom_is_reference = 0;
+    rf->field_order_cnt[0]  = 0;
+    rf->field_order_cnt[1]  = 0;
+    rf->frame_idx           = 0;
+}
+
+static void vdpau_h264_fill_picture(VdpReferenceFrameH264 *rf, Picture *pic, int pic_structure)
+{
+    struct vdpau_render_state *render;
+
+    assert(rf);
+    assert(pic);
+
+    if (pic_structure == 0)
+        pic_structure = pic->reference;
+
+    render = (struct vdpau_render_state *)pic->data[3];
+    assert(render);
+
+    rf->surface             = render->surface;
+    rf->is_long_term        = pic->reference && pic->long_ref;
+    rf->top_is_reference    = (pic_structure & PICT_TOP_FIELD) != 0;
+    rf->bottom_is_reference = (pic_structure & PICT_BOTTOM_FIELD) != 0;
+    rf->frame_idx           = pic->long_ref ? pic->pic_id : pic->frame_num;
+
+    vdpau_h264_fill_field_order_cnt(rf->field_order_cnt, pic, pic_structure);
+}
+
+static void vdpau_h264_set_reference_frames(H264Context *h)
+{
+    MpegEncContext * const s = &h->s;
     struct vdpau_render_state *render, *render_ref;
     VdpReferenceFrameH264 *rf, *rf2;
     Picture *pic;
     int i, list, pic_frame_idx;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
     assert(render);
 
     rf = &render->info.h264.referenceFrames[0];
@@ -62,7 +103,7 @@ void ff_vdpau_h264_set_reference_frames(
                 continue;
             pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
 
-            render_ref = (struct vdpau_render_state *)pic->data[0];
+            render_ref = (struct vdpau_render_state *)pic->data[3];
             assert(render_ref);
 
             rf2 = &render->info.h264.referenceFrames[0];
@@ -84,81 +125,93 @@ void ff_vdpau_h264_set_reference_frames(
             if (rf >= &render->info.h264.referenceFrames[H264_RF_COUNT])
                 continue;
 
-            rf->surface             = render_ref->surface;
-            rf->is_long_term        = pic->long_ref;
-            rf->top_is_reference    = (pic->reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
-            rf->bottom_is_reference = (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
-            rf->field_order_cnt[0]  = pic->field_poc[0];
-            rf->field_order_cnt[1]  = pic->field_poc[1];
-            rf->frame_idx           = pic_frame_idx;
+            vdpau_h264_fill_picture(rf, pic, pic->reference);
 
             ++rf;
         }
     }
 
-    for (; rf < &render->info.h264.referenceFrames[H264_RF_COUNT]; ++rf) {
-        rf->surface             = VDP_INVALID_HANDLE;
-        rf->is_long_term        = 0;
-        rf->top_is_reference    = 0;
-        rf->bottom_is_reference = 0;
-        rf->field_order_cnt[0]  = 0;
-        rf->field_order_cnt[1]  = 0;
-        rf->frame_idx           = 0;
-    }
+    for (; rf < &render->info.h264.referenceFrames[H264_RF_COUNT]; ++rf)
+        vdpau_h264_init_picture(rf);
 }
 
-void ff_vdpau_add_data_chunk(MpegEncContext *s,
-                             const uint8_t *buf, int buf_size)
+static int vdpau_ensure_bitstream_buffers(struct vdpau_render_state *render)
 {
-    struct vdpau_render_state *render;
-
-    render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
-    assert(render);
-
     render->bitstream_buffers= av_fast_realloc(
         render->bitstream_buffers,
         &render->bitstream_buffers_allocated,
         sizeof(*render->bitstream_buffers)*(render->bitstream_buffers_used + 1)
     );
 
-    render->bitstream_buffers[render->bitstream_buffers_used].struct_version  = VDP_BITSTREAM_BUFFER_VERSION;
-    render->bitstream_buffers[render->bitstream_buffers_used].bitstream       = buf;
-    render->bitstream_buffers[render->bitstream_buffers_used].bitstream_bytes = buf_size;
-    render->bitstream_buffers_used++;
+    if (!render->bitstream_buffers)
+        return -1;
+
+    return 0;
 }
 
-void ff_vdpau_h264_picture_start(MpegEncContext *s)
+static int vdpau_common_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
 {
-    H264Context *h = s->avctx->priv_data;
+    MpegEncContext * const s = avctx->priv_data;
     struct vdpau_render_state *render;
-    int i;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
+    assert(render);
+
+    render->bitstream_buffers_used = 0;
+    return 0;
+}
+
+static int vdpau_common_end_frame(AVCodecContext *avctx)
+{
+    MpegEncContext * const s = avctx->priv_data;
+    struct vdpau_render_state *render;
+
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
     assert(render);
 
-    for (i = 0; i < 2; ++i) {
-        int foc = s->current_picture_ptr->field_poc[i];
-        if (foc == INT_MAX)
-            foc = 0;
-        render->info.h264.field_order_cnt[i] = foc;
+    if (render->bitstream_buffers_used) {
+        ff_draw_horiz_band(s, 0, s->avctx->height);
+        render->bitstream_buffers_used = 0;
     }
+    return 0;
+}
+
+static int vdpau_common_decode_slice(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size)
+{
+    MpegEncContext * const s = avctx->priv_data;
+    struct vdpau_render_state *render;
+
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
+    assert(render);
+
+    if (vdpau_ensure_bitstream_buffers(render) < 0)
+        return -1;
 
-    render->info.h264.frame_num = h->frame_num;
+    render->bitstream_buffers[render->bitstream_buffers_used].struct_version  = VDP_BITSTREAM_BUFFER_VERSION;
+    render->bitstream_buffers[render->bitstream_buffers_used].bitstream       = buf;
+    render->bitstream_buffers[render->bitstream_buffers_used].bitstream_bytes = buf_size;
+    render->bitstream_buffers_used++;
+    return 0;
 }
 
-void ff_vdpau_h264_picture_complete(MpegEncContext *s)
+static int vdpau_h264_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
-    H264Context *h = s->avctx->priv_data;
+    H264Context * const h = avctx->priv_data;
+    MpegEncContext * const s = &h->s;
     struct vdpau_render_state *render;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
     assert(render);
 
-    render->info.h264.slice_count = h->slice_num;
-    if (render->info.h264.slice_count < 1)
-        return;
+    vdpau_h264_set_reference_frames(h);
 
-    render->info.h264.is_reference                           = (s->current_picture_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE;
+    vdpau_h264_fill_field_order_cnt(render->info.h264.field_order_cnt,
+                                    s->current_picture_ptr,
+                                    s->picture_structure);
+
+    /* fill VdpPictureInfoH264 struct */
+    render->info.h264.is_reference                           = h->nal_ref_idc != 0;
+    render->info.h264.frame_num                              = h->frame_num;
     render->info.h264.field_pic_flag                         = s->picture_structure != PICT_FRAME;
     render->info.h264.bottom_field_flag                      = s->picture_structure == PICT_BOTTOM_FIELD;
     render->info.h264.num_ref_frames                         = h->sps.ref_frame_count;
@@ -185,19 +238,44 @@ void ff_vdpau_h264_picture_complete(Mpeg
     memcpy(render->info.h264.scaling_lists_4x4, h->pps.scaling_matrix4, sizeof(render->info.h264.scaling_lists_4x4));
     memcpy(render->info.h264.scaling_lists_8x8, h->pps.scaling_matrix8, sizeof(render->info.h264.scaling_lists_8x8));
 
-    ff_draw_horiz_band(s, 0, s->avctx->height);
-    render->bitstream_buffers_used = 0;
+    render->info.h264.slice_count                = 0;
+
+    return vdpau_common_start_frame(avctx, buffer, size);
 }
 
-void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf,
-                                    int buf_size, int slice_count)
+static int vdpau_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
+    MpegEncContext * const s = avctx->priv_data;
+    struct vdpau_render_state *render;
+    static const uint8_t start_code_prefix_one_3byte[3] = { 0x00, 0x00, 0x01 };
+
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
+    assert(render);
+
+    if (vdpau_ensure_bitstream_buffers(render) < 0)
+        return -1;
+
+    render->bitstream_buffers[render->bitstream_buffers_used].struct_version  = VDP_BITSTREAM_BUFFER_VERSION;
+    render->bitstream_buffers[render->bitstream_buffers_used].bitstream       = start_code_prefix_one_3byte;
+    render->bitstream_buffers[render->bitstream_buffers_used].bitstream_bytes = sizeof(start_code_prefix_one_3byte);
+    render->bitstream_buffers_used++;
+
+    if (vdpau_common_decode_slice(avctx, buffer, size) < 0)
+        return -1;
+
+    ++render->info.h264.slice_count;
+    return 0;
+}
+
+static int vdpau_mpeg2_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
+{
+    MpegEncContext * const s = avctx->priv_data;
     struct vdpau_render_state *render, *last, *next;
     int i;
 
-    if (!s->current_picture_ptr) return;
+    if (!s->current_picture_ptr) return 0;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
     assert(render);
 
     /* fill VdpPictureInfoMPEG1Or2 struct */
@@ -226,36 +304,47 @@ void ff_vdpau_mpeg_picture_complete(Mpeg
 
     switch(s->pict_type){
     case  FF_B_TYPE:
-        next = (struct vdpau_render_state *)s->next_picture.data[0];
+        next = (struct vdpau_render_state *)s->next_picture.data[3];
         assert(next);
         render->info.mpeg.backward_reference     = next->surface;
         // no return here, going to set forward prediction
     case  FF_P_TYPE:
-        last = (struct vdpau_render_state *)s->last_picture.data[0];
+        last = (struct vdpau_render_state *)s->last_picture.data[3];
         if (!last) // FIXME: Does this test make sense?
             last = render; // predict second field from the first
         render->info.mpeg.forward_reference      = last->surface;
     }
 
-    ff_vdpau_add_data_chunk(s, buf, buf_size);
+    render->info.mpeg.slice_count                = 0;
 
-    render->info.mpeg.slice_count                = slice_count;
+    return vdpau_common_start_frame(avctx, buffer, size);
+}
 
-    if (slice_count)
-        ff_draw_horiz_band(s, 0, s->avctx->height);
-    render->bitstream_buffers_used               = 0;
+static int vdpau_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
+{
+    MpegEncContext * const s = avctx->priv_data;
+    struct vdpau_render_state *render;
+
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
+    assert(render);
+
+    if (vdpau_common_decode_slice(avctx, buffer, size) < 0)
+        return -1;
+
+    ++render->info.mpeg.slice_count;
+    return 0;
 }
 
-void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf,
-                                 int buf_size)
+static int vdpau_vc1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
-    VC1Context *v = s->avctx->priv_data;
+    VC1Context * const v = avctx->priv_data;
+    MpegEncContext * const s = &v->s;
     struct vdpau_render_state *render, *last, *next;
 
-    render = (struct vdpau_render_state *)s->current_picture.data[0];
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
     assert(render);
 
-    /*  fill LvPictureInfoVC1 struct */
+    /* fill VdpPictureInfoVC1 struct */
     render->info.vc1.frame_coding_mode  = v->fcm;
     render->info.vc1.postprocflag       = v->postprocflag;
     render->info.vc1.pulldown           = v->broadcast;
@@ -296,34 +385,47 @@ void ff_vdpau_vc1_decode_picture(MpegEnc
 
     switch(s->pict_type){
     case  FF_B_TYPE:
-        next = (struct vdpau_render_state *)s->next_picture.data[0];
+        next = (struct vdpau_render_state *)s->next_picture.data[3];
         assert(next);
         render->info.vc1.backward_reference = next->surface;
         // no break here, going to set forward prediction
     case  FF_P_TYPE:
-        last = (struct vdpau_render_state *)s->last_picture.data[0];
+        last = (struct vdpau_render_state *)s->last_picture.data[3];
         if (!last) // FIXME: Does this test make sense?
             last = render; // predict second field from the first
         render->info.vc1.forward_reference = last->surface;
     }
 
-    ff_vdpau_add_data_chunk(s, buf, buf_size);
+    render->info.vc1.slice_count                 = 0;
 
-    render->info.vc1.slice_count          = 1;
+    return vdpau_common_start_frame(avctx, buffer, size);
+}
 
-    ff_draw_horiz_band(s, 0, s->avctx->height);
-    render->bitstream_buffers_used        = 0;
+static int vdpau_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
+{
+    VC1Context * const v = avctx->priv_data;
+    MpegEncContext * const s = &v->s;
+    struct vdpau_render_state *render;
+
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
+    assert(render);
+
+    if (vdpau_common_decode_slice(avctx, buffer, size) < 0)
+        return -1;
+
+    ++render->info.vc1.slice_count;
+    return 0;
 }
 
-void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf,
-                                   int buf_size)
+static int vdpau_mpeg4_decode_picture(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
+    MpegEncContext * const s = avctx->priv_data;
     struct vdpau_render_state *render, *last, *next;
     int i;
 
-    if (!s->current_picture_ptr) return;
+    if (!s->current_picture_ptr) return 0;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+    render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
     assert(render);
 
     /* fill VdpPictureInfoMPEG4Part2 struct */
@@ -352,21 +454,122 @@ void ff_vdpau_mpeg4_decode_picture(MpegE
 
     switch (s->pict_type) {
     case FF_B_TYPE:
-        next = (struct vdpau_render_state *)s->next_picture.data[0];
+        next = (struct vdpau_render_state *)s->next_picture.data[3];
         assert(next);
         render->info.mpeg4.backward_reference     = next->surface;
         render->info.mpeg4.vop_coding_type        = 2;
         // no break here, going to set forward prediction
     case FF_P_TYPE:
-        last = (struct vdpau_render_state *)s->last_picture.data[0];
+        last = (struct vdpau_render_state *)s->last_picture.data[3];
         assert(last);
         render->info.mpeg4.forward_reference      = last->surface;
     }
 
-    ff_vdpau_add_data_chunk(s, buf, buf_size);
+    if (vdpau_common_start_frame(avctx, buffer, size) < 0)
+        return -1;
 
-    ff_draw_horiz_band(s, 0, s->avctx->height);
-    render->bitstream_buffers_used = 0;
+    if (vdpau_common_decode_slice(avctx, buffer, size) < 0)
+        return -1;
+
+    return vdpau_common_end_frame(avctx);
+}
+
+static int vdpau_mpeg4_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
+{
+    /* The `buffer' can be modified beyond this point so we pass the
+     * whole picture now to the decoder and let user-applications catch
+     * up immediately */
+    return vdpau_mpeg4_decode_picture(avctx, buffer, size);
 }
 
+static int vdpau_mpeg4_decode_slice(av_unused AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
+{
+    /* SKIP: everything is done in vdpau_mpeg4_start_frame() */
+    return 0;
+}
+
+static int vdpau_mpeg4_end_frame(av_unused AVCodecContext *avctx)
+{
+    /* SKIP: everything is done in vdpau_mpeg4_start_frame() */
+    return 0;
+}
+
+#if CONFIG_MPEG1_VDPAU_HWACCEL
+AVHWAccel mpeg1_vdpau_hwaccel = {
+    .name           = "mpeg1_vdpau",
+    .type           = CODEC_TYPE_VIDEO,
+    .id             = CODEC_ID_MPEG1VIDEO,
+    .pix_fmt        = PIX_FMT_VDPAU,
+    .capabilities   = 0,
+    .start_frame    = vdpau_mpeg2_start_frame,
+    .end_frame      = vdpau_common_end_frame,
+    .decode_slice   = vdpau_mpeg2_decode_slice,
+};
+#endif
+
+#if CONFIG_MPEG2_VDPAU_HWACCEL
+AVHWAccel mpeg2_vdpau_hwaccel = {
+    .name           = "mpeg2_vdpau",
+    .type           = CODEC_TYPE_VIDEO,
+    .id             = CODEC_ID_MPEG2VIDEO,
+    .pix_fmt        = PIX_FMT_VDPAU,
+    .capabilities   = 0,
+    .start_frame    = vdpau_mpeg2_start_frame,
+    .end_frame      = vdpau_common_end_frame,
+    .decode_slice   = vdpau_mpeg2_decode_slice,
+};
+#endif
+
+#if CONFIG_H264_VDPAU_HWACCEL
+AVHWAccel h264_vdpau_hwaccel = {
+    .name           = "h264_vdpau",
+    .type           = CODEC_TYPE_VIDEO,
+    .id             = CODEC_ID_H264,
+    .pix_fmt        = PIX_FMT_VDPAU,
+    .capabilities   = 0,
+    .start_frame    = vdpau_h264_start_frame,
+    .end_frame      = vdpau_common_end_frame,
+    .decode_slice   = vdpau_h264_decode_slice,
+};
+#endif
+
+#if CONFIG_WMV3_VDPAU_HWACCEL
+AVHWAccel wmv3_vdpau_hwaccel = {
+    .name           = "wmv3_vdpau",
+    .type           = CODEC_TYPE_VIDEO,
+    .id             = CODEC_ID_WMV3,
+    .pix_fmt        = PIX_FMT_VDPAU,
+    .capabilities   = 0,
+    .start_frame    = vdpau_vc1_start_frame,
+    .end_frame      = vdpau_common_end_frame,
+    .decode_slice   = vdpau_vc1_decode_slice,
+};
+#endif
+
+#if CONFIG_VC1_VDPAU_HWACCEL
+AVHWAccel vc1_vdpau_hwaccel = {
+    .name           = "vc1_vdpau",
+    .type           = CODEC_TYPE_VIDEO,
+    .id             = CODEC_ID_VC1,
+    .pix_fmt        = PIX_FMT_VDPAU,
+    .capabilities   = 0,
+    .start_frame    = vdpau_vc1_start_frame,
+    .end_frame      = vdpau_common_end_frame,
+    .decode_slice   = vdpau_vc1_decode_slice,
+};
+#endif
+
+#if CONFIG_MPEG4_VDPAU_HWACCEL
+AVHWAccel mpeg4_vdpau_hwaccel = {
+    .name           = "mpeg4_vdpau",
+    .type           = CODEC_TYPE_VIDEO,
+    .id             = CODEC_ID_MPEG4,
+    .pix_fmt        = PIX_FMT_VDPAU,
+    .capabilities   = 0,
+    .start_frame    = vdpau_mpeg4_start_frame,
+    .end_frame      = vdpau_mpeg4_end_frame,
+    .decode_slice   = vdpau_mpeg4_decode_slice,
+};
+#endif
+
 /* @}*/
--- /dev/null
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/vaapi_compat.h
@@ -0,0 +1,92 @@
+/*
+ * Video Acceleration API (video decoding)
+ * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
+ *
+ * Copyright (C) 2008-2009 Splitted-Desktop Systems
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VAAPI_COMPAT_H
+#define AVCODEC_VAAPI_COMPAT_H
+
+/* Compatibility glue with original VA-API 0.29 */
+#if CONFIG_VAAPI_OLD
+typedef struct _VASliceParameterBufferBase {
+    unsigned int slice_data_size;
+    unsigned int slice_data_offset;
+    unsigned int slice_data_flag;
+} VASliceParameterBufferBase;
+#endif
+
+#ifndef VA_CHECK_VERSION
+#define VA_MAJOR_VERSION 0
+#define VA_MINOR_VERSION 29
+#define VA_CHECK_VERSION(major,minor,micro) \
+        (VA_MAJOR_VERSION > (major) || \
+         (VA_MAJOR_VERSION == (major) && VA_MINOR_VERSION > (minor)) || \
+         (VA_MAJOR_VERSION == (major) && VA_MINOR_VERSION == (minor) && VA_MICRO_VERSION >= (micro)))
+#endif
+
+#ifndef VA_FOURCC
+#define VA_FOURCC(ch0, ch1, ch2, ch3)           \
+    ((uint32_t)(uint8_t)(ch0) |                 \
+     ((uint32_t)(uint8_t)(ch1) << 8) |          \
+     ((uint32_t)(uint8_t)(ch2) << 16) |         \
+     ((uint32_t)(uint8_t)(ch3) << 24 ))
+#endif
+
+#ifndef VA_INVALID_ID
+#define VA_INVALID_ID           0xffffffff
+#endif
+#ifndef VA_INVALID_SURFACE
+#define VA_INVALID_SURFACE      VA_INVALID_ID
+#endif
+
+/* Compatibility glue with VA-API >= 0.31 */
+#if VA_CHECK_VERSION(0,31,0)
+#define vaSyncSurface(dpy, context, surface) (vaSyncSurface)((dpy), (surface))
+#define vaPutImage2             vaPutImage
+#define vaAssociateSubpicture2  vaAssociateSubpicture
+#endif
+
+/* Used in codec implementation to set up the right bit-fields */
+#if CONFIG_VAAPI_OLD
+# define BFV(a, b)              a
+# define BFM(a, b, c)           c
+# define BFMP(p, a, b, c)       p##_##c
+# define NEW(x)                 /* nothing */
+#else
+# define BFV(a, b)              a.b
+# define BFM(a, b, c)           a.b.c
+# define BFMP(p, a, b, c)       a.b.c
+# define NEW(x)                 x
+#endif
+
+#if CONFIG_VAAPI_OLD
+# define V_raw_coding           raw_coding_flag
+# define M_raw_coding           raw_coding
+# define V_bitplane_present     bitplane_present_flag
+# define M_bitplane_present     bitplane_present
+#else
+# define V_raw_coding           raw_coding
+# define M_raw_coding           raw_coding
+# define V_bitplane_present     bitplane_present
+# define M_bitplane_present     bitplane_present
+#endif
+
+#endif /* AVCODEC_VAAPI_COMPAT_H */
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/vaapi_internal.h
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/vaapi_internal.h
@@ -24,8 +24,14 @@
 #ifndef AVCODEC_VAAPI_INTERNAL_H
 #define AVCODEC_VAAPI_INTERNAL_H
 
+#include "config.h"
+#if CONFIG_VAAPI_OLD
+#include <va.h>
+#else
 #include <va/va.h>
+#endif
 #include "vaapi.h"
+#include "vaapi_compat.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/vaapi_mpeg2.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/vaapi_mpeg2.c
@@ -52,24 +52,24 @@ static int vaapi_mpeg2_start_frame(AVCod
     pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG2));
     if (!pic_param)
         return -1;
-    pic_param->horizontal_size                                  = s->width;
-    pic_param->vertical_size                                    = s->height;
-    pic_param->forward_reference_picture                        = VA_INVALID_ID;
-    pic_param->backward_reference_picture                       = VA_INVALID_ID;
-    pic_param->picture_coding_type                              = s->pict_type;
-    pic_param->f_code                                           = mpeg2_get_f_code(s);
-    pic_param->picture_coding_extension.value                   = 0; /* reset all bits */
-    pic_param->picture_coding_extension.bits.intra_dc_precision = s->intra_dc_precision;
-    pic_param->picture_coding_extension.bits.picture_structure  = s->picture_structure;
-    pic_param->picture_coding_extension.bits.top_field_first    = s->top_field_first;
-    pic_param->picture_coding_extension.bits.frame_pred_frame_dct = s->frame_pred_frame_dct;
-    pic_param->picture_coding_extension.bits.concealment_motion_vectors = s->concealment_motion_vectors;
-    pic_param->picture_coding_extension.bits.q_scale_type       = s->q_scale_type;
-    pic_param->picture_coding_extension.bits.intra_vlc_format   = s->intra_vlc_format;
-    pic_param->picture_coding_extension.bits.alternate_scan     = s->alternate_scan;
-    pic_param->picture_coding_extension.bits.repeat_first_field = s->repeat_first_field;
-    pic_param->picture_coding_extension.bits.progressive_frame  = s->progressive_frame;
-    pic_param->picture_coding_extension.bits.is_first_field     = mpeg2_get_is_frame_start(s);
+    pic_param->horizontal_size                                               = s->width;
+    pic_param->vertical_size                                                 = s->height;
+    pic_param->forward_reference_picture                                     = VA_INVALID_ID;
+    pic_param->backward_reference_picture                                    = VA_INVALID_ID;
+    pic_param->picture_coding_type                                           = s->pict_type;
+    pic_param->f_code                                                        = mpeg2_get_f_code(s);
+    pic_param->BFV(picture_coding_extension,value)                           = 0; /* reset all bits */
+    pic_param->BFM(picture_coding_extension,bits,intra_dc_precision)         = s->intra_dc_precision;
+    pic_param->BFM(picture_coding_extension,bits,picture_structure)          = s->picture_structure;
+    pic_param->BFM(picture_coding_extension,bits,top_field_first)            = s->top_field_first;
+    pic_param->BFM(picture_coding_extension,bits,frame_pred_frame_dct)       = s->frame_pred_frame_dct;
+    pic_param->BFM(picture_coding_extension,bits,concealment_motion_vectors) = s->concealment_motion_vectors;
+    pic_param->BFM(picture_coding_extension,bits,q_scale_type)               = s->q_scale_type;
+    pic_param->BFM(picture_coding_extension,bits,intra_vlc_format)           = s->intra_vlc_format;
+    pic_param->BFM(picture_coding_extension,bits,alternate_scan)             = s->alternate_scan;
+    pic_param->BFM(picture_coding_extension,bits,repeat_first_field)         = s->repeat_first_field;
+    pic_param->BFM(picture_coding_extension,bits,progressive_frame)          = s->progressive_frame;
+    pic_param->BFM(picture_coding_extension,bits,is_first_field)             = mpeg2_get_is_frame_start(s);
 
     switch (s->pict_type) {
     case FF_B_TYPE:
@@ -131,7 +131,7 @@ static int vaapi_mpeg2_decode_slice(AVCo
     if (!slice_param)
         return -1;
     slice_param->macroblock_offset              = macroblock_offset;
-    slice_param->slice_horizontal_position      = s->mb_x;
+    NEW(slice_param->slice_horizontal_position  = s->mb_x);
     slice_param->slice_vertical_position        = s->mb_y;
     slice_param->quantiser_scale_code           = quantiser_scale_code;
     slice_param->intra_slice_flag               = intra_slice_flag;
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavcodec/vc1dec.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavcodec/vc1dec.c
@@ -37,7 +37,6 @@
 #include "unary.h"
 #include "simple_idct.h"
 #include "mathops.h"
-#include "vdpau_internal.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -3139,13 +3138,6 @@ static int vc1_decode_frame(AVCodecConte
         s->current_picture_ptr= &s->picture[i];
     }
 
-    if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){
-        if (v->profile < PROFILE_ADVANCED)
-            avctx->pix_fmt = PIX_FMT_VDPAU_WMV3;
-        else
-            avctx->pix_fmt = PIX_FMT_VDPAU_VC1;
-    }
-
     //for advanced profile we may need to parse and unescape data
     if (avctx->codec_id == CODEC_ID_VC1) {
         int buf_size2 = 0;
@@ -3162,8 +3154,7 @@ static int vc1_decode_frame(AVCodecConte
                 if(size <= 0) continue;
                 switch(AV_RB32(start)){
                 case VC1_CODE_FRAME:
-                    if (avctx->hwaccel ||
-                        s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+                    if (avctx->hwaccel)
                         buf_start = start;
                     buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
                     break;
@@ -3255,10 +3246,7 @@ static int vc1_decode_frame(AVCodecConte
     s->me.qpel_put= s->dsp.put_qpel_pixels_tab;
     s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
 
-    if ((CONFIG_VC1_VDPAU_DECODER)
-        &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start);
-    else if (avctx->hwaccel) {
+    if (avctx->hwaccel) {
         if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)
             return -1;
         if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0)
@@ -3348,37 +3336,3 @@ AVCodec wmv3_decoder = {
     .pix_fmts = ff_hwaccel_pixfmt_list_420
 };
 #endif
-
-#if CONFIG_WMV3_VDPAU_DECODER
-AVCodec wmv3_vdpau_decoder = {
-    "wmv3_vdpau",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_WMV3,
-    sizeof(VC1Context),
-    vc1_decode_init,
-    NULL,
-    vc1_decode_end,
-    vc1_decode_frame,
-    CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
-    NULL,
-    .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"),
-    .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_WMV3, PIX_FMT_NONE}
-};
-#endif
-
-#if CONFIG_VC1_VDPAU_DECODER
-AVCodec vc1_vdpau_decoder = {
-    "vc1_vdpau",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_VC1,
-    sizeof(VC1Context),
-    vc1_decode_init,
-    NULL,
-    vc1_decode_end,
-    vc1_decode_frame,
-    CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
-    NULL,
-    .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"),
-    .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_VC1, PIX_FMT_NONE}
-};
-#endif
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavutil/pixfmt.h
+++ mplayer-1.0~rc4~try1.dsfg1/libavutil/pixfmt.h
@@ -133,6 +133,7 @@ enum PixelFormat {
     PIX_FMT_BGR444BE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1
     PIX_FMT_BGR444LE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1
     PIX_FMT_Y400A,     ///< 8bit gray, 8bit alpha
+    PIX_FMT_VDPAU,     ///< HW decoding with VDPAU, Picture.data[3] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
 };
 
--- mplayer-1.0~rc4~try1.dsfg1.orig/libavutil/pixdesc.c
+++ mplayer-1.0~rc4~try1.dsfg1/libavutil/pixdesc.c
@@ -785,7 +785,13 @@ const AVPixFmtDescriptor av_pix_fmt_desc
         .comp = {
             {0,1,1,0,7},        /* Y */
             {0,1,2,0,7},        /* A */
-        },
+        }
+    },
+    [PIX_FMT_VDPAU] = {
+        .name = "vdpau",
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .flags = PIX_FMT_HWACCEL,
     },
 };
 
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/dec_video.c
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/dec_video.c
@@ -56,9 +56,47 @@ extern double vout_time_usage;
 int field_dominance = -1;
 
 int divx_quality = 0;
+char *video_hwaccel_name=NULL;
 
 const vd_functions_t *mpvdec = NULL;
 
+int get_video_hwaccel(void)
+{
+    static int video_hwaccel = -1;
+    if (video_hwaccel < 0) {
+        video_hwaccel = HWACCEL_NONE;
+        if (video_hwaccel_name) {
+            if (!strcmp(video_hwaccel_name,"xvmc"))
+                video_hwaccel = HWACCEL_XVMC;
+            else if (!strcmp(video_hwaccel_name,"vaapi"))
+                video_hwaccel = HWACCEL_VAAPI;
+            else if (!strcmp(video_hwaccel_name,"vdpau"))
+                video_hwaccel = HWACCEL_VDPAU;
+        }
+    }
+    return video_hwaccel;
+}
+
+const char *get_video_hwaccel_name(int hwaccel)
+{
+    switch (hwaccel) {
+    case HWACCEL_XVMC:  return "XvMC";
+    case HWACCEL_VAAPI: return "VA API";
+    case HWACCEL_VDPAU: return "VDPAU";
+    }
+    return NULL;
+}
+
+const char *get_video_hwaccel_short_name(int hwaccel)
+{
+    switch (hwaccel) {
+    case HWACCEL_XVMC:  return "xvmc";
+    case HWACCEL_VAAPI: return "vaapi";
+    case HWACCEL_VDPAU: return "vdpau";
+    }
+    return NULL;
+}
+
 int get_video_quality_max(sh_video_t *sh_video)
 {
     vf_instance_t *vf = sh_video->vfilter;
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/dec_video.h
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/dec_video.h
@@ -21,6 +21,14 @@
 
 #include "libmpdemux/stheader.h"
 
+enum {
+  HWACCEL_NONE = 0,
+  HWACCEL_XVMC,
+  HWACCEL_VAAPI,
+  HWACCEL_VDPAU,
+  HWACCEL_COUNT
+};
+
 extern int field_dominance;
 
 // dec_video.c:
@@ -41,6 +49,11 @@ int set_rectangle(sh_video_t *sh_video,
 void resync_video_stream(sh_video_t *sh_video);
 int get_current_video_decoder_lag(sh_video_t *sh_video);
 
+int get_video_hwaccel(void);
+const char *get_video_hwaccel_name(int hwaccel);
+const char *get_video_hwaccel_short_name(int hwaccel);
+
 extern int divx_quality;
+extern char *video_hwaccel_name;
 
 #endif /* MPLAYER_DEC_VIDEO_H */
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/img_format.c
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/img_format.c
@@ -96,6 +96,14 @@ const char *vo_format_name(int format)
 	case IMGFMT_ZRMJPEGIB: return "Zoran MJPEG bottom field first";
 	case IMGFMT_XVMC_MOCO_MPEG2: return "MPEG1/2 Motion Compensation";
 	case IMGFMT_XVMC_IDCT_MPEG2: return "MPEG1/2 Motion Compensation and IDCT";
+	case IMGFMT_VAAPI_MPEG2: return "MPEG-2 VA-API Acceleration";
+	case IMGFMT_VAAPI_MPEG2_IDCT: return "MPEG-2 VA-API Acceleration (Motion Compensation and IDCT)";
+	case IMGFMT_VAAPI_MPEG2_MOCO: return "MPEG-2 VA-API Acceleration (Motion Compensation)";
+	case IMGFMT_VAAPI_MPEG4: return "MPEG-4 VA-API Acceleration";
+	case IMGFMT_VAAPI_H263:  return "H.263 VA-API Acceleration";
+	case IMGFMT_VAAPI_H264:  return "H.264 VA-API Acceleration";
+	case IMGFMT_VAAPI_WMV3:  return "WMV3 VA-API Acceleration";
+	case IMGFMT_VAAPI_VC1:   return "VC-1 VA-API Acceleration";
 	case IMGFMT_VDPAU_MPEG1: return "MPEG1 VDPAU acceleration";
 	case IMGFMT_VDPAU_MPEG2: return "MPEG2 VDPAU acceleration";
 	case IMGFMT_VDPAU_H264: return "H.264 VDPAU acceleration";
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/img_format.h
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/img_format.h
@@ -182,6 +182,26 @@
 #define IMGFMT_XVMC_MOCO_MPEG2 (IMGFMT_XVMC|0x02)
 #define IMGFMT_XVMC_IDCT_MPEG2 (IMGFMT_XVMC|0x82)
 
+/* VA-API Formats */
+
+#define IMGFMT_VAAPI               0x56410000 /* 'VA'00 */
+#define IMGFMT_VAAPI_MASK          0xFFFF0000
+#define IMGFMT_IS_VAAPI(fmt)       (((fmt) & IMGFMT_VAAPI_MASK) == IMGFMT_VAAPI)
+#define IMGFMT_VAAPI_CODEC_MASK    0x000000F0
+#define IMGFMT_VAAPI_CODEC(fmt)    ((fmt) & IMGFMT_VAAPI_CODEC_MASK)
+#define IMGFMT_VAAPI_CODEC_MPEG2   (0x10)
+#define IMGFMT_VAAPI_CODEC_MPEG4   (0x20)
+#define IMGFMT_VAAPI_CODEC_H264    (0x30)
+#define IMGFMT_VAAPI_CODEC_VC1     (0x40)
+#define IMGFMT_VAAPI_MPEG2         (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG2)
+#define IMGFMT_VAAPI_MPEG2_IDCT    (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG2|1)
+#define IMGFMT_VAAPI_MPEG2_MOCO    (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG2|2)
+#define IMGFMT_VAAPI_MPEG4         (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG4)
+#define IMGFMT_VAAPI_H263          (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG4|1)
+#define IMGFMT_VAAPI_H264          (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_H264)
+#define IMGFMT_VAAPI_VC1           (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_VC1)
+#define IMGFMT_VAAPI_WMV3          (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_VC1|1)
+
 // VDPAU specific format.
 #define IMGFMT_VDPAU               0x1DC80000
 #define IMGFMT_VDPAU_MASK          0xFFFF0000
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/mp_image.c
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/mp_image.c
@@ -101,6 +101,7 @@ void mp_image_setfmt(mp_image_t* mpi,uns
     // compressed formats
     if(out_fmt == IMGFMT_MPEGPES ||
        out_fmt == IMGFMT_ZRMJPEGNI || out_fmt == IMGFMT_ZRMJPEGIT || out_fmt == IMGFMT_ZRMJPEGIB ||
+       IMGFMT_IS_VAAPI(out_fmt) ||
        IMGFMT_IS_VDPAU(out_fmt) || IMGFMT_IS_XVMC(out_fmt)){
 	mpi->bpp=0;
 	return;
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/vd.c
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/vd.c
@@ -403,3 +403,12 @@ void mpcodecs_draw_slice(sh_video_t *sh,
     if (vf->draw_slice)
         vf->draw_slice(vf, src, stride, w, h, x, y);
 }
+
+void *mpcodecs_get_hwaccel_context(sh_video_t *sh)
+{
+    void *ctx = NULL;
+    struct vf_instance *vf = sh->vfilter;
+    if (vf->control(vf, VFCTRL_GET_HWACCEL_CONTEXT, &ctx) == CONTROL_TRUE)
+        return ctx;
+    return NULL;
+}
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/vd.h
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/vd.h
@@ -64,6 +64,7 @@ extern const m_option_t xvid_dec_opts[];
 int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int preferred_outfmt);
 mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
 void mpcodecs_draw_slice(sh_video_t *sh, unsigned char** src, int* stride, int w,int h, int x, int y);
+void *mpcodecs_get_hwaccel_context(sh_video_t *sh);
 
 #define VDFLAGS_DROPFRAME 3
 
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/vd_ffmpeg.c
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/vd_ffmpeg.c
@@ -32,6 +32,7 @@
 #include "fmt-conversion.h"
 
 #include "vd_internal.h"
+#include "dec_video.h"
 
 static const vd_info_t info = {
     "FFmpeg's libavcodec codec family",
@@ -228,8 +229,8 @@ static void set_format_params(struct AVC
     int imgfmt;
     if (fmt == PIX_FMT_NONE)
         return;
-    imgfmt = pixfmt2imgfmt(fmt);
-    if (IMGFMT_IS_XVMC(imgfmt) || IMGFMT_IS_VDPAU(imgfmt)) {
+    imgfmt = pixfmt2imgfmt(fmt, avctx->codec_id);
+    if (IMGFMT_IS_XVMC(imgfmt) || IMGFMT_IS_VDPAU(imgfmt) || IMGFMT_IS_VAAPI(imgfmt)) {
         sh_video_t *sh     = avctx->opaque;
         vd_ffmpeg_ctx *ctx = sh->context;
         ctx->do_dr1    = 1;
@@ -286,8 +287,14 @@ static int init(sh_video_t *sh){
     avctx->codec_type = CODEC_TYPE_VIDEO;
     avctx->codec_id = lavc_codec->id;
 
+#if CONFIG_VAAPI
+    if(get_video_hwaccel() == HWACCEL_VAAPI){
+        mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_VAAPIAcceleratedCodec);
+        avctx->get_format = get_format;
+    }
+#endif /* CONFIG_VAAPI */
 #if CONFIG_VDPAU
-    if(lavc_codec->capabilities & CODEC_CAP_HWACCEL_VDPAU){
+    if(get_video_hwaccel() == HWACCEL_VDPAU){
         avctx->get_format = get_format;
     }
 #endif /* CONFIG_VDPAU */
@@ -479,7 +486,7 @@ static void draw_slice(struct AVCodecCon
                         const AVFrame *src, int offset[4],
                         int y, int type, int height){
     sh_video_t *sh = s->opaque;
-    uint8_t *source[MP_MAX_PLANES]= {src->data[0] + offset[0], src->data[1] + offset[1], src->data[2] + offset[2]};
+    uint8_t *source[MP_MAX_PLANES]= {src->data[0] + offset[0], src->data[1] + offset[1], src->data[2] + offset[2], src->data[3] + offset[3]};
     int strides[MP_MAX_PLANES] = {src->linesize[0], src->linesize[1], src->linesize[2]};
 #if 0
     int start=0, i;
@@ -558,9 +565,10 @@ static int init_vo(sh_video_t *sh, enum
         sh->disp_w = width;
         sh->disp_h = height;
         ctx->pix_fmt = pix_fmt;
-        ctx->best_csp = pixfmt2imgfmt(pix_fmt);
+        ctx->best_csp = pixfmt2imgfmt(pix_fmt, avctx->codec_id);
         if (!mpcodecs_config_vo(sh, sh->disp_w, sh->disp_h, ctx->best_csp))
             return -1;
+        avctx->hwaccel_context = mpcodecs_get_hwaccel_context(sh);
         ctx->vo_initialized = 1;
     }
     return 0;
@@ -611,7 +619,9 @@ static int get_buffer(AVCodecContext *av
         return avctx->get_buffer(avctx, pic);
     }
 
-    if (IMGFMT_IS_XVMC(ctx->best_csp) || IMGFMT_IS_VDPAU(ctx->best_csp)) {
+    if (IMGFMT_IS_XVMC(ctx->best_csp) ||
+        IMGFMT_IS_VAAPI(ctx->best_csp) ||
+        IMGFMT_IS_VDPAU(ctx->best_csp)) {
         type =  MP_IMGTYPE_NUMBERED | (0xffff << 16);
     } else
     if (!pic->buffer_hints) {
@@ -643,6 +653,11 @@ static int get_buffer(AVCodecContext *av
         avctx->draw_horiz_band= draw_slice;
     } else
         avctx->draw_horiz_band= NULL;
+#if CONFIG_VAAPI
+    if(IMGFMT_IS_VAAPI(mpi->imgfmt)) {
+        avctx->draw_horiz_band= draw_slice;
+    }
+#endif
     if(IMGFMT_IS_VDPAU(mpi->imgfmt)) {
         avctx->draw_horiz_band= draw_slice;
     }
@@ -955,24 +970,62 @@ static mp_image_t *decode(sh_video_t *sh
     return mpi;
 }
 
-#if CONFIG_XVMC || CONFIG_VDPAU
+#if CONFIG_XVMC || CONFIG_VAAPI || CONFIG_VDPAU
+static inline int is_hwaccel_format(int imgfmt)
+{
+    switch (get_video_hwaccel()) {
+    case HWACCEL_VAAPI: return IMGFMT_IS_VAAPI(imgfmt) != 0;
+    case HWACCEL_VDPAU: return IMGFMT_IS_VDPAU(imgfmt) != 0;
+    case HWACCEL_XVMC:  return IMGFMT_IS_XVMC(imgfmt)  != 0;
+    }
+    return 0;
+}
+
+static int query_format(sh_video_t *sh, int fmt)
+{
+    vd_ffmpeg_ctx * const ctx = sh->context;
+    AVCodecContext * const avctx = ctx->avctx;
+    int r, width, height;
+    /* XXX: some codecs have not initialized width and height yet at
+       this point, so we are faking the dimensions so that init_vo()
+       doesn't fail because of 0x0 size */
+    if ((width = avctx->width) == 0)
+        avctx->width = 64;
+    if ((height = avctx->height) == 0)
+        avctx->height = 64;
+    r = init_vo(sh, fmt);
+    avctx->width = width;
+    avctx->height = height;
+    return r;
+}
+
 static enum PixelFormat get_format(struct AVCodecContext *avctx,
-                                    const enum PixelFormat *fmt){
-    enum PixelFormat selected_format;
+                                   const enum PixelFormat *fmt){
+    enum PixelFormat selected_format = PIX_FMT_NONE;
     int imgfmt;
     sh_video_t *sh = avctx->opaque;
-    int i;
+    int i, try_hwaccel;
 
-    for(i=0;fmt[i]!=PIX_FMT_NONE;i++){
-        imgfmt = pixfmt2imgfmt(fmt[i]);
-        if(!IMGFMT_IS_XVMC(imgfmt) && !IMGFMT_IS_VDPAU(imgfmt)) continue;
-        mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_TryingPixfmt, i);
-        if(init_vo(sh, fmt[i]) >= 0) {
-            break;
+    for (try_hwaccel = 1; try_hwaccel >= 0; --try_hwaccel) {
+        for (i = 0; fmt[i] != PIX_FMT_NONE; i++){
+            imgfmt = pixfmt2imgfmt(fmt[i], avctx->codec_id);
+            if ((try_hwaccel ^ is_hwaccel_format(imgfmt)) != 0)
+                continue;
+            mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_TryingPixfmt, i);
+            if (query_format(sh, fmt[i]) >= 0) {
+                if (try_hwaccel) {
+                    /* don't allow format conversion for HW acceleration */
+                    if (sh->codec->outfmt[sh->outfmtidx] != imgfmt)
+                        continue;
+                }
+                selected_format = fmt[i];
+                break;
+            }
         }
+        if (selected_format != PIX_FMT_NONE)
+            break;
     }
-    selected_format = fmt[i];
     set_format_params(avctx, selected_format);
     return selected_format;
 }
-#endif /* CONFIG_XVMC || CONFIG_VDPAU */
+#endif /* CONFIG_XVMC || CONFIG_VAAPI || CONFIG_VDPAU */
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/vf.h
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/vf.h
@@ -111,6 +111,7 @@ typedef struct vf_seteq_s
 #define VFCTRL_GET_PTS         17 /* Return last pts value that reached vf_vo*/
 #define VFCTRL_SET_DEINTERLACE 18 /* Set deinterlacing status */
 #define VFCTRL_GET_DEINTERLACE 19 /* Get deinterlacing status */
+#define VFCTRL_GET_HWACCEL_CONTEXT 20 /* Get HW accelerator context */
 
 #include "vfcap.h"
 
--- mplayer-1.0~rc4~try1.dsfg1.orig/libmpcodecs/vf_vo.c
+++ mplayer-1.0~rc4~try1.dsfg1/libmpcodecs/vf_vo.c
@@ -170,6 +170,12 @@ static int control(struct vf_instance *v
 	*(double *)data = vf->priv->pts;
 	return CONTROL_TRUE;
     }
+    case VFCTRL_GET_HWACCEL_CONTEXT:
+    {
+        if(!video_out) return CONTROL_FALSE; // vo not configured?
+        return(video_out->control(VOCTRL_GET_HWACCEL_CONTEXT, data)
+               == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
+    }
     }
     // return video_out->control(request,data);
     return CONTROL_UNKNOWN;
@@ -189,6 +195,7 @@ static void get_image(struct vf_instance
     if(!vo_config_count) return;
     // GET_IMAGE is required for hardware-accelerated formats
     if(vo_directrendering ||
+       IMGFMT_IS_VAAPI(mpi->imgfmt) ||
        IMGFMT_IS_XVMC(mpi->imgfmt) || IMGFMT_IS_VDPAU(mpi->imgfmt))
 	video_out->control(VOCTRL_GET_IMAGE,mpi);
 }
--- mplayer-1.0~rc4~try1.dsfg1.orig/libvo/gl_common.c
+++ mplayer-1.0~rc4~try1.dsfg1/libvo/gl_common.c
@@ -140,6 +140,11 @@ void* (GLAPIENTRY *mpglAllocateMemoryMES
 void (GLAPIENTRY *mpglFreeMemoryMESA)(void *, int, void *);
 /** \} */ // end of glextfunctions group
 
+void (GLAPIENTRY *mpglXBindTexImage)(Display *, GLXDrawable, int, const int *);
+void (GLAPIENTRY *mpglXReleaseTexImage)(Display *, GLXDrawable, int);
+GLXPixmap (GLAPIENTRY *mpglXCreatePixmap)(Display *, GLXFBConfig, Pixmap, const int *);
+void (GLAPIENTRY *mpglXDestroyPixmap)(Display *, GLXPixmap);
+
 //! \defgroup glgeneral OpenGL general helper functions
 
 //! \defgroup glcontext OpenGL context management helper functions
@@ -469,6 +474,10 @@ static const extfunc_desc_t extfuncs[] =
   {&mpglTexImage3D, NULL, {"glTexImage3D", NULL}},
   {&mpglAllocateMemoryMESA, "GLX_MESA_allocate_memory", {"glXAllocateMemoryMESA", NULL}},
   {&mpglFreeMemoryMESA, "GLX_MESA_allocate_memory", {"glXFreeMemoryMESA", NULL}},
+  {&mpglXBindTexImage, "GLX_EXT_texture_from_pixmap", {"glXBindTexImageEXT", NULL}},
+  {&mpglXReleaseTexImage, "GLX_EXT_texture_from_pixmap", {"glXReleaseTexImageEXT", NULL}},
+  {&mpglXCreatePixmap, "GLX_EXT_texture_from_pixmap", {"glXCreatePixmap", NULL}},
+  {&mpglXDestroyPixmap, "GLX_EXT_texture_from_pixmap", {"glXDestroyPixmap", NULL}},
   {NULL}
 };
 
--- mplayer-1.0~rc4~try1.dsfg1.orig/libvo/gl_common.h
+++ mplayer-1.0~rc4~try1.dsfg1/libvo/gl_common.h
@@ -507,4 +507,9 @@ extern void (GLAPIENTRY *mpglTexImage3D)
 extern void* (GLAPIENTRY *mpglAllocateMemoryMESA)(void *, int, size_t, float, float, float);
 extern void (GLAPIENTRY *mpglFreeMemoryMESA)(void *, int, void *);
 
+extern void (GLAPIENTRY *mpglXBindTexImage)(Display *, GLXDrawable, int, const int *);
+extern void (GLAPIENTRY *mpglXReleaseTexImage)(Display *, GLXDrawable, int);
+extern GLXPixmap (GLAPIENTRY *mpglXCreatePixmap)(Display *, GLXFBConfig, Pixmap, const int *);
+extern void (GLAPIENTRY *mpglXDestroyPixmap)(Display *, GLXPixmap);
+
 #endif /* MPLAYER_GL_COMMON_H */
--- mplayer-1.0~rc4~try1.dsfg1.orig/libvo/video_out.c
+++ mplayer-1.0~rc4~try1.dsfg1/libvo/video_out.c
@@ -95,6 +95,7 @@ extern const vo_functions_t video_out_xm
 extern const vo_functions_t video_out_x11;
 extern vo_functions_t video_out_xover;
 extern const vo_functions_t video_out_xvmc;
+extern const vo_functions_t video_out_vaapi;
 extern const vo_functions_t video_out_vdpau;
 extern const vo_functions_t video_out_xv;
 extern const vo_functions_t video_out_gl_nosw;
@@ -290,6 +291,9 @@ const vo_functions_t* const video_out_dr
 #ifdef CONFIG_MD5SUM
         &video_out_md5sum,
 #endif
+#if CONFIG_VAAPI
+        &video_out_vaapi,
+#endif
         NULL
 };
 
--- mplayer-1.0~rc4~try1.dsfg1.orig/libvo/video_out.h
+++ mplayer-1.0~rc4~try1.dsfg1/libvo/video_out.h
@@ -99,6 +99,10 @@ typedef struct {
   int w,h;
 } mp_win_t;
 
+// Return current HW acceleration context
+// void *get_hwaccel_context(void);
+#define VOCTRL_GET_HWACCEL_CONTEXT 33
+
 #define VO_TRUE		1
 #define VO_FALSE	0
 #define VO_ERROR	-1
--- mplayer-1.0~rc4~try1.dsfg1.orig/libvo/vo_vdpau.c
+++ mplayer-1.0~rc4~try1.dsfg1/libvo/vo_vdpau.c
@@ -971,7 +971,7 @@ static int draw_slice(uint8_t *image[],
                       int x, int y)
 {
     VdpStatus vdp_st;
-    struct vdpau_render_state *rndr = (struct vdpau_render_state *)image[0];
+    struct vdpau_render_state *rndr = (struct vdpau_render_state *)image[3];
     int max_refs = image_format == IMGFMT_VDPAU_H264 ? rndr->info.h264.num_ref_frames : 2;
 
     if (handle_preemption() < 0)
@@ -1074,10 +1074,10 @@ static uint32_t get_image(mp_image_t *mp
         return VO_FALSE;
     }
     mpi->flags |= MP_IMGFLAG_DIRECT;
-    mpi->stride[0] = mpi->stride[1] = mpi->stride[2] = 0;
-    mpi->planes[0] = mpi->planes[1] = mpi->planes[2] = NULL;
+    mpi->stride[0] = mpi->stride[1] = mpi->stride[2] = mpi->stride[3] = 0;
+    mpi->planes[0] = mpi->planes[1] = mpi->planes[2] = mpi->planes[3] = NULL;
     // hack to get around a check and to avoid a special-case in vd_ffmpeg.c
-    mpi->planes[0] = (void *)rndr;
+    mpi->planes[0] = mpi->planes[3] = (void *)rndr;
     mpi->num_planes = 1;
     mpi->priv = rndr;
     return VO_TRUE;
--- /dev/null
+++ mplayer-1.0~rc4~try1.dsfg1/libvo/stats.c
@@ -0,0 +1,217 @@
+#include "config.h"
+#include "stats.h"
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <locale.h>
+#include <inttypes.h>
+
+#if CONFIG_LIBGTOP
+#include <glibtop/cpu.h>
+#include <glibtop/proctime.h>
+#include <glibtop/procstate.h>
+#endif
+
+// Process statistics
+struct proc_stats {
+    uint64_t utime;
+    uint64_t stime;
+    uint64_t cutime;
+    uint64_t cstime;
+    uint64_t frequency;
+    uint64_t cpu_time;
+    uint64_t start_time;
+    uint64_t current_time;
+};
+
+// Get current process stats
+static int get_proc_stats(struct proc_stats *pstats);
+
+void stats_init(void)
+{
+#if CONFIG_LIBGTOP
+    glibtop_init();
+#endif
+}
+
+void stats_exit(void)
+{
+#if CONFIG_LIBGTOP
+    glibtop_close();
+#endif
+}
+
+// Get CPU frequency
+unsigned int get_cpu_frequency(void)
+{
+    unsigned int freq = 0;
+#if defined __linux__
+    {
+        FILE *proc_file = fopen("/proc/cpuinfo", "r");
+        if (proc_file) {
+            char line[256];
+            char *old_locale = setlocale(LC_NUMERIC, NULL);
+            setlocale(LC_NUMERIC, "C");
+            while(fgets(line, sizeof(line), proc_file)) {
+                float f;
+                int len = strlen(line);
+                if (len == 0)
+                    continue;
+                line[len - 1] = 0;
+                if (sscanf(line, "cpu MHz : %f", &f) == 1)
+                    freq = (unsigned int)f;
+            }
+            setlocale(LC_NUMERIC, old_locale);
+            fclose(proc_file);
+        }
+    }
+#endif
+    return freq;
+}
+
+// Get CPU usage in percent
+static float get_cpu_usage_1(void)
+{
+    static struct proc_stats prev_stats;
+    struct proc_stats curr_stats;
+    uint64_t prev_proc_time = 0, curr_proc_time = 0;
+    float pcpu = 0.0f;
+
+    if (get_proc_stats(&curr_stats) == 0) {
+        prev_proc_time += prev_stats.utime;
+        prev_proc_time += prev_stats.stime;
+        prev_proc_time += prev_stats.cutime;
+        prev_proc_time += prev_stats.cstime;
+        curr_proc_time += curr_stats.utime;
+        curr_proc_time += curr_stats.stime;
+        curr_proc_time += curr_stats.cutime;
+        curr_proc_time += curr_stats.cstime;
+        if (prev_stats.start_time > 0)
+            pcpu = 100.0 * ((float)(curr_proc_time - prev_proc_time) /
+                            (float)(curr_stats.cpu_time - prev_stats.cpu_time));
+        prev_stats = curr_stats;
+    }
+    return pcpu;
+}
+
+float get_cpu_usage(enum CpuUsageType type)
+{
+    static float pcpu_total = 0.0;
+    static unsigned int n_samples;
+    float pcpu;
+
+    pcpu        = get_cpu_usage_1();
+    pcpu_total += pcpu / 100.0;
+    ++n_samples;
+
+    if (type == CPU_USAGE_AVERAGE)
+        pcpu = 100.0 * (pcpu_total / n_samples);
+    return pcpu;
+}
+
+// For ELF executable, notes are pushed before environment and args
+static int find_elf_note(unsigned long match, unsigned long *pval)
+{
+    unsigned long *ep = (unsigned long *)__environ;
+    while (*ep++);
+    for (; *ep != 0; ep += 2) {
+        if (ep[0] == match) {
+            *pval = ep[1];
+            return 0;
+        }
+    }
+    return -1;
+}
+
+#ifndef AT_CLKTCK
+#define AT_CLKTCK 17
+#endif
+
+// Get current process stats
+int get_proc_stats(struct proc_stats *pstats)
+{
+    int error = -1;
+    char line[256], *str, *end;
+    char vc;
+    int vi;
+    unsigned long vul;
+    unsigned long long vull;
+    float vf;
+#if defined __linux__
+    {
+        FILE *proc_file = fopen("/proc/self/stat", "r");
+        if (proc_file) {
+            if (fgets(line, sizeof(line), proc_file)) {
+                unsigned long utime, stime, cutime, cstime, start_time;
+                str = strrchr(line, ')');
+                if (str && sscanf(str + 2,
+                                  "%c "
+                                  "%d %d %d %d %d "
+                                  "%lu %lu %lu %lu %lu %lu %lu "
+                                  "%ld %ld %ld %ld %ld %ld "
+                                  "%lu %lu ",
+                                  &vc,
+                                  &vi, &vi, &vi, &vi, &vi, 
+                                  &vul, &vul, &vul, &vul, &vul, &utime, &stime,
+                                  &cutime, &cstime, &vul, &vul, &vul, &vul,
+                                  &start_time, &vul) == 21) {
+                    pstats->utime      = utime;
+                    pstats->stime      = stime;
+                    pstats->cutime     = cutime;
+                    pstats->cstime     = cstime;
+                    pstats->start_time = start_time;
+                    error = 0;
+                }
+            }
+            fclose(proc_file);
+        }
+        if (error)
+            return error;
+        error = -1;
+
+        if (find_elf_note(AT_CLKTCK, &vul) == 0) {
+            pstats->frequency = vul;
+            error = 0;
+        }
+        if (error)
+            return error;
+        error = -1;
+
+        proc_file = fopen("/proc/uptime", "r");
+        if (proc_file) {
+            if (fgets(line, sizeof(line), proc_file)) {
+                char *old_locale = setlocale(LC_NUMERIC, NULL);
+                setlocale(LC_NUMERIC, "C");
+                if (sscanf(line, "%f", &vf) == 1) {
+                    pstats->cpu_time = (uint64_t)(vf * (float)pstats->frequency);
+                    error = 0;
+                }
+                setlocale(LC_NUMERIC, old_locale);
+            }
+            fclose(proc_file);
+        }
+    }
+#elif CONFIG_LIBGTOP
+    {
+        glibtop_cpu cpu;
+        glibtop_proc_time proc_time;
+        glibtop_proc_state proc_state;
+
+        glibtop_get_cpu(&cpu);
+        glibtop_get_proc_state(&proc_state, getpid());
+        pstats->cpu_time   = cpu.xcpu_total[proc_state.processor];
+
+        glibtop_get_proc_time(&proc_time, getpid());
+        pstats->utime      = proc_time.utime;
+        pstats->stime      = proc_time.stime;
+        pstats->cutime     = proc_time.cutime;
+        pstats->cstime     = proc_time.cstime;
+        pstats->start_time = proc_time.start_time;
+        pstats->frequency  = proc_time.frequency;
+
+        error = 0;
+    }
+#endif
+    return error;
+}
--- /dev/null
+++ mplayer-1.0~rc4~try1.dsfg1/libvo/stats.h
@@ -0,0 +1,21 @@
+#ifndef MPLAYER_STATS_H
+#define MPLAYER_STATS_H
+
+#include <stdint.h>
+
+void stats_init(void);
+void stats_exit(void);
+
+/// CPU usage model
+enum CpuUsageType {
+    CPU_USAGE_QUANTUM = 1, ///< CPU usage since the last call to cpu_get_usage()
+    CPU_USAGE_AVERAGE      ///< CPU usage average'd since program start
+};
+
+/// Get CPU frequency
+unsigned int get_cpu_frequency(void);
+
+/// Get CPU usage in percent
+float get_cpu_usage(enum CpuUsageType type);
+
+#endif /* MPLAYER_STATS_H */
--- /dev/null
+++ mplayer-1.0~rc4~try1.dsfg1/libvo/vo_vaapi.c
@@ -0,0 +1,2671 @@
+/*
+ * VA API output module
+ *
+ * Copyright (C) 2008-2009 Splitted-Desktop Systems
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+#include "subopt-helper.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+#include "fastmemcpy.h"
+#include "sub.h"
+#include "x11_common.h"
+#include "libavutil/common.h"
+#include "libavcodec/vaapi.h"
+#include "gui/interface.h"
+#include "stats.h"
+#include "libass/ass_mp.h"
+#include <stdarg.h>
+
+#if CONFIG_GL
+#include "gl_common.h"
+#include <GL/glu.h>
+#include <GL/glx.h>
+#endif
+
+#include <assert.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#if CONFIG_VAAPI_OLD
+#include <va_x11.h>
+#else
+#include <va/va_x11.h>
+#endif
+#if CONFIG_VAAPI_GLX
+#include <va/va_glx.h>
+#endif
+
+#if CONFIG_XRENDER
+#include <X11/extensions/Xrender.h>
+#endif
+
+/* Compatibility glue with VA-API >= 0.30 */
+#ifndef VA_INVALID_ID
+#define VA_INVALID_ID           0xffffffff
+#endif
+#ifndef VA_FOURCC
+#define VA_FOURCC(ch0, ch1, ch2, ch3)           \
+    ((uint32_t)(uint8_t)(ch0) |                 \
+     ((uint32_t)(uint8_t)(ch1) << 8) |          \
+     ((uint32_t)(uint8_t)(ch2) << 16) |         \
+     ((uint32_t)(uint8_t)(ch3) << 24 ))
+#endif
+#if defined VA_SRC_BT601 && defined VA_SRC_BT709
+#define USE_VAAPI_COLORSPACE 1
+#else
+#define USE_VAAPI_COLORSPACE 0
+#endif
+
+/* Defined to 1 if IA44/AI44 subpicture formats are allowed */
+/* XXX: they are not visually attractive... */
+#define USE_VAAPI_IA44_FORMATS 0
+
+/* Defined to 1 if VA/GLX 'bind' API is available */
+#define USE_VAAPI_GLX_BIND                                \
+    (VA_MAJOR_VERSION == 0 &&                             \
+     ((VA_MINOR_VERSION == 30 &&                          \
+       VA_MICRO_VERSION == 4 && VA_SDS_VERSION >= 5) ||   \
+      (VA_MINOR_VERSION == 31 &&                          \
+       VA_MICRO_VERSION == 0 && VA_SDS_VERSION < 5)))
+
+/* Compatibility glue with VA-API >= 0.31 */
+#if defined VA_CHECK_VERSION
+#if VA_CHECK_VERSION(0,31,0)
+#define vaPutImage2             vaPutImage
+#define vaAssociateSubpicture2  vaAssociateSubpicture
+#endif
+#endif
+
+static vo_info_t info = {
+    "VA API with X11",
+    "vaapi",
+    "Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>",
+    ""
+};
+
+const LIBVO_EXTERN(vaapi)
+
+/* Numbers of video surfaces */
+#define MAX_OUTPUT_SURFACES       2 /* Maintain synchronisation points in flip_page() */
+#define MAX_VIDEO_SURFACES       21 /* Maintain free surfaces in a queue (use least-recently-used) */
+#define NUM_VIDEO_SURFACES_MPEG2  3 /* 1 decode frame, up to  2 references */
+#define NUM_VIDEO_SURFACES_MPEG4  3 /* 1 decode frame, up to  2 references */
+#define NUM_VIDEO_SURFACES_H264  21 /* 1 decode frame, up to 20 references */
+#define NUM_VIDEO_SURFACES_VC1    3 /* 1 decode frame, up to  2 references */
+
+static void ensure_osd(void);
+static int reset_xrender_specific(void);
+
+typedef void (*draw_alpha_func)(int x0, int y0, int w, int h,
+                                unsigned char *src, unsigned char *srca,
+                                int stride);
+
+typedef void (*eosd_draw_alpha_func)(unsigned char *src,
+                                     int src_w, int src_h, int src_stride,
+                                     int dst_x, int dst_y,
+                                     uint32_t color);
+
+struct vaapi_surface {
+    VASurfaceID id;
+    VAImage     image;
+    int         is_bound; /* Flag: image bound to the surface? */
+};
+
+struct vaapi_equalizer {
+    VADisplayAttribute brightness;
+    VADisplayAttribute contrast;
+    VADisplayAttribute hue;
+    VADisplayAttribute saturation;
+};
+
+static int                      g_is_visible;
+static int                      g_is_paused;
+static uint32_t                 g_image_width;
+static uint32_t                 g_image_height;
+static uint32_t                 g_image_format;
+static uint32_t                 g_image_fields;
+static Pixmap                   g_image_pixmap;
+static struct vo_rect           g_output_rect;
+static struct vaapi_surface    *g_output_surfaces[MAX_OUTPUT_SURFACES];
+static unsigned int             g_output_surface;
+static int                      g_deint;
+static int                      g_deint_type;
+static int                      g_colorspace;
+
+static int                      gl_enabled;
+static int                      gl_use_tfp;
+#if CONFIG_GL
+static MPGLContext              gl_context;
+static int                      gl_binding;
+static int                      gl_reflect;
+static int                      gl_finish;
+static GLuint                   gl_texture;
+static GLuint                   gl_font_base;
+static Pixmap                   gl_pixmap;
+static int                      gl_visual_attr[] = {
+    GLX_RGBA,
+    GLX_RED_SIZE, 1,
+    GLX_GREEN_SIZE, 1,
+    GLX_BLUE_SIZE, 1,
+    GLX_DOUBLEBUFFER,
+    GL_NONE
+};
+#endif
+
+#if CONFIG_VAAPI_GLX
+static void                    *gl_surface;
+#endif
+
+static int                      xr_enabled;
+#if CONFIG_XRENDER
+static Pixmap                   g_image_pixmap;
+static Picture                  xr_video_picture;
+static Picture                  xr_window_picture;
+#endif
+
+static struct vaapi_context    *va_context;
+static VAProfile               *va_profiles;
+static int                      va_num_profiles;
+static VAEntrypoint            *va_entrypoints;
+static int                      va_num_entrypoints;
+static VASurfaceID             *va_surface_ids;
+static int                      va_num_surfaces;
+static struct vaapi_surface   **va_free_surfaces;
+static int                      va_free_surfaces_head_index;
+static int                      va_free_surfaces_tail_index;
+static VAImageFormat           *va_image_formats;
+static int                      va_num_image_formats;
+static VAImageFormat           *va_subpic_formats;
+static unsigned int            *va_subpic_flags;
+static int                      va_num_subpic_formats;
+static VAImage                  va_osd_image;
+static uint8_t                 *va_osd_image_data;
+static VASubpictureID           va_osd_subpicture;
+static int                      va_osd_associated;
+static draw_alpha_func          va_osd_draw_alpha;
+static uint8_t                 *va_osd_palette;
+static struct vaapi_equalizer   va_equalizer;
+static VAImage                  va_eosd_image;
+static uint8_t                 *va_eosd_image_data;
+static VASubpictureID           va_eosd_subpicture;
+static int                      va_eosd_associated;
+static eosd_draw_alpha_func     va_eosd_draw_alpha;
+
+///< Flag: direct surface mapping: use mpi->number to select free VA surface?
+static int                      va_dm;
+
+///< Flag: gather run-time statistics (CPU usage, frequency)
+static int                      cpu_stats;
+static unsigned int             cpu_frequency;
+static float                    cpu_usage;
+
+// X error trap
+static int x11_error_code = 0;
+static int (*old_error_handler)(Display *, XErrorEvent *);
+
+static int error_handler(Display *dpy, XErrorEvent *error)
+{
+    x11_error_code = error->error_code;
+    return 0;
+}
+
+static void x11_trap_errors(void)
+{
+    x11_error_code    = 0;
+    old_error_handler = XSetErrorHandler(error_handler);
+}
+
+static int x11_untrap_errors(void)
+{
+    XSetErrorHandler(old_error_handler);
+    return x11_error_code;
+}
+
+static int check_status(VAStatus status, const char *msg)
+{
+    if (status != VA_STATUS_SUCCESS) {
+        mp_msg(MSGT_VO, MSGL_ERR, "[vo_vaapi] %s: %s\n", msg, vaErrorStr(status));
+        return 0;
+    }
+    return 1;
+}
+
+static const char *string_of_VAImageFormat(VAImageFormat *imgfmt)
+{
+    static char str[5];
+    str[0] = imgfmt->fourcc;
+    str[1] = imgfmt->fourcc >> 8;
+    str[2] = imgfmt->fourcc >> 16;
+    str[3] = imgfmt->fourcc >> 24;
+    str[4] = '\0';
+    return str;
+}
+
+static const char *string_of_VAProfile(VAProfile profile)
+{
+    switch (profile) {
+#define PROFILE(profile) \
+        case VAProfile##profile: return "VAProfile" #profile
+        PROFILE(MPEG2Simple);
+        PROFILE(MPEG2Main);
+        PROFILE(MPEG4Simple);
+        PROFILE(MPEG4AdvancedSimple);
+        PROFILE(MPEG4Main);
+        PROFILE(H264Baseline);
+        PROFILE(H264Main);
+        PROFILE(H264High);
+        PROFILE(VC1Simple);
+        PROFILE(VC1Main);
+        PROFILE(VC1Advanced);
+#undef PROFILE
+    }
+    return "<unknown>";
+}
+
+static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint)
+{
+    switch (entrypoint) {
+#define ENTRYPOINT(entrypoint) \
+        case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint
+        ENTRYPOINT(VLD);
+        ENTRYPOINT(IZZ);
+        ENTRYPOINT(IDCT);
+        ENTRYPOINT(MoComp);
+        ENTRYPOINT(Deblocking);
+#undef ENTRYPOINT
+    }
+    return "<unknown>";
+}
+
+static int has_profile(VAProfile profile)
+{
+    if (va_profiles && va_num_profiles > 0) {
+        int i;
+        for (i = 0; i < va_num_profiles; i++) {
+            if (va_profiles[i] == profile)
+                return 1;
+        }
+    }
+    return 0;
+}
+
+static int VAProfile_from_imgfmt(uint32_t format)
+{
+    static const int mpeg2_profiles[] =
+        { VAProfileMPEG2Main, VAProfileMPEG2Simple, -1 };
+    static const int mpeg4_profiles[] =
+        { VAProfileMPEG4Main, VAProfileMPEG4AdvancedSimple, VAProfileMPEG4Simple, -1 };
+    static const int h264_profiles[] =
+        { VAProfileH264High, VAProfileH264Main, VAProfileH264Baseline, -1 };
+    static const int wmv3_profiles[] =
+        { VAProfileVC1Main, VAProfileVC1Simple, -1 };
+    static const int vc1_profiles[] =
+        { VAProfileVC1Advanced, -1 };
+
+    const int *profiles = NULL;
+    switch (IMGFMT_VAAPI_CODEC(format)) {
+    case IMGFMT_VAAPI_CODEC_MPEG2:
+        profiles = mpeg2_profiles;
+        break;
+    case IMGFMT_VAAPI_CODEC_MPEG4:
+        profiles = mpeg4_profiles;
+        break;
+    case IMGFMT_VAAPI_CODEC_H264:
+        profiles = h264_profiles;
+        break;
+    case IMGFMT_VAAPI_CODEC_VC1:
+        switch (format) {
+        case IMGFMT_VAAPI_WMV3:
+            profiles = wmv3_profiles;
+            break;
+        case IMGFMT_VAAPI_VC1:
+            profiles = vc1_profiles;
+            break;
+        }
+        break;
+    }
+
+    if (profiles) {
+        for (int i = 0; profiles[i] != -1; i++) {
+            if (has_profile(profiles[i]))
+                return profiles[i];
+        }
+    }
+    return -1;
+}
+
+static int has_entrypoint(VAEntrypoint entrypoint)
+{
+    if (va_entrypoints && va_num_entrypoints > 0) {
+        int i;
+        for (i = 0; i < va_num_entrypoints; i++) {
+            if (va_entrypoints[i] == entrypoint)
+                return 1;
+        }
+    }
+    return 0;
+}
+
+static int VAEntrypoint_from_imgfmt(uint32_t format)
+{
+    int entrypoint = 0;
+    switch (format) {
+    case IMGFMT_VAAPI_MPEG2:
+    case IMGFMT_VAAPI_MPEG4:
+    case IMGFMT_VAAPI_H263:
+    case IMGFMT_VAAPI_H264:
+    case IMGFMT_VAAPI_WMV3:
+    case IMGFMT_VAAPI_VC1:
+        entrypoint = VAEntrypointVLD;
+        break;
+    case IMGFMT_VAAPI_MPEG2_IDCT:
+        entrypoint = VAEntrypointIDCT;
+        break;
+    case IMGFMT_VAAPI_MPEG2_MOCO:
+        entrypoint = VAEntrypointMoComp;
+        break;
+    }
+
+    if (entrypoint)
+        return has_entrypoint(entrypoint);
+
+    return -1;
+}
+
+static VAImageFormat *find_image_format(uint32_t fourcc)
+{
+    if (va_image_formats && va_num_image_formats > 0) {
+        int i;
+        for (i = 0; i < va_num_image_formats; i++) {
+            if (va_image_formats[i].fourcc == fourcc)
+                return &va_image_formats[i];
+        }
+    }
+    return NULL;
+}
+
+static VAImageFormat *VAImageFormat_from_imgfmt(uint32_t format)
+{
+    uint32_t fourcc = 0;
+
+    switch (format) {
+    case IMGFMT_NV12: fourcc = VA_FOURCC('N','V','1','2'); break;
+    case IMGFMT_YV12: fourcc = VA_FOURCC('Y','V','1','2'); break;
+    case IMGFMT_I420: fourcc = VA_FOURCC('I','4','2','0'); break;
+    case IMGFMT_IYUV: fourcc = VA_FOURCC('I','Y','U','V'); break;
+    }
+
+    if (fourcc)
+        return find_image_format(fourcc);
+
+    return NULL;
+}
+
+static struct vaapi_surface *alloc_vaapi_surface(unsigned int width,
+                                                 unsigned int height,
+                                                 unsigned int format)
+{
+    struct vaapi_surface *surface = NULL;
+    struct vaapi_surface **surfaces;
+    VASurfaceID *surface_ids;
+    VAStatus status;
+
+    surface = calloc(1, sizeof(*surface));
+    if (!surface)
+        goto error;
+
+    surfaces = realloc(va_free_surfaces,
+                       (1 + va_num_surfaces) * sizeof(surfaces[0]));
+    if (!surfaces)
+        goto error;
+
+    surface_ids = realloc(va_surface_ids,
+                          (1 + va_num_surfaces) * sizeof(surface_ids[0]));
+    if (!surface_ids)
+        goto error;
+
+    status = vaCreateSurfaces(va_context->display, width, height, format,
+                              1, &surface->id);
+    if (!check_status(status, "vaCreateSurfaces()"))
+        goto error;
+
+    va_surface_ids                    = surface_ids;
+    va_surface_ids[va_num_surfaces]   = surface->id;
+    va_free_surfaces                  = surfaces;
+    va_free_surfaces[va_num_surfaces] = surface;
+    surface->image.image_id           = VA_INVALID_ID;
+    surface->image.buf                = VA_INVALID_ID;
+    ++va_num_surfaces;
+    return surface;
+error:
+    free(surface);
+    return NULL;
+}
+
+static void resize(void)
+{
+    struct vo_rect src;
+
+    calc_src_dst_rects(g_image_width, g_image_height,
+                       &src, &g_output_rect, NULL, NULL);
+
+    ensure_osd();
+
+    vo_x11_clearwindow(mDisplay, vo_window);
+
+#if CONFIG_GL
+#define FOVY     60.0f
+#define ASPECT   1.0f
+#define Z_NEAR   0.1f
+#define Z_FAR    100.0f
+#define Z_CAMERA 0.869f
+
+    if (gl_enabled) {
+        glViewport(0, 0, vo_dwidth, vo_dheight);
+        glMatrixMode(GL_PROJECTION);
+        glLoadIdentity();
+        gluPerspective(FOVY, ASPECT, Z_NEAR, Z_FAR);
+        glMatrixMode(GL_MODELVIEW);
+        glLoadIdentity();
+
+        glTranslatef(-0.5f, -0.5f, -Z_CAMERA);
+        glScalef(1.0f / (GLfloat)vo_dwidth,
+                 -1.0f / (GLfloat)vo_dheight,
+                 1.0f / (GLfloat)vo_dwidth);
+        glTranslatef(0.0f, -1.0f * (GLfloat)vo_dheight, 0.0f);
+    }
+#endif
+
+#if CONFIG_XRENDER
+    if (xr_enabled)
+        reset_xrender_specific();
+#endif
+
+    if (g_is_visible)
+        flip_page();
+}
+
+#if CONFIG_GL
+static int gl_build_font(void)
+{
+    XFontStruct *fi;
+
+    gl_font_base = glGenLists(96);
+
+    fi = XLoadQueryFont(mDisplay, "-adobe-helvetica-medium-r-normal--16-*-*-*-p-*-iso8859-1" );
+    if (!fi) {
+        fi = XLoadQueryFont(mDisplay, "fixed");
+        if (!fi)
+            return -1;
+    }
+
+    glXUseXFont(fi->fid, 32, 96, gl_font_base);
+    XFreeFont(mDisplay, fi);
+    return 0;
+}
+
+static void gl_printf(const char *format, ...)
+{
+    va_list args;
+    char *text;
+    int textlen;
+
+    va_start(args, format);
+    textlen = vsnprintf(NULL, 0, format, args);
+    va_end(args);
+
+    text = malloc(textlen + 1);
+    if (!text)
+        return;
+
+    va_start(args, format);
+    vsprintf(text, format, args);
+    va_end(args);
+
+    glPushAttrib(GL_LIST_BIT);
+    glListBase(gl_font_base - 32);
+    glCallLists(textlen, GL_UNSIGNED_BYTE, text);
+    glPopAttrib();
+    free(text);
+}
+
+static void gl_draw_rectangle(int x, int y, int w, int h, unsigned int rgba)
+{
+    glColor4f((GLfloat)((rgba >> 24) & 0xff) / 255.0,
+              (GLfloat)((rgba >> 16) & 0xff) / 255.0,
+              (GLfloat)((rgba >> 8) & 0xff) / 255.0,
+              (GLfloat)(rgba & 0xff) / 255.0);
+
+    glTranslatef((GLfloat)x, (GLfloat)y, 0.0f);
+    glBegin(GL_QUADS);
+    {
+        glVertex2i(0, 0);
+        glVertex2i(w, 0);
+        glVertex2i(w, h);
+        glVertex2i(0, h);
+    }
+    glEnd();
+}
+#endif
+
+#if CONFIG_XRENDER
+static int init_xrender(void)
+{
+    int dummy;
+
+    return XRenderQueryExtension(mDisplay, &dummy, &dummy);
+}
+
+static void uninit_xrender(void)
+{
+}
+#endif
+
+static inline unsigned char *get_osd_image_data(int x0, int y0)
+{
+    return (va_osd_image_data +
+            va_osd_image.offsets[0] +
+            va_osd_image.pitches[0] * y0 +
+            x0 * ((va_osd_image.format.bits_per_pixel + 7) / 8));
+}
+
+static void draw_alpha_rgb32(int x0, int y0, int w, int h,
+                             unsigned char *src, unsigned char *srca,
+                             int stride)
+{
+    int x, y;
+    const unsigned int dststride = va_osd_image.pitches[0];
+    unsigned char *dst = get_osd_image_data(x0, y0);
+
+    for (y = 0; y < h; y++, dst += dststride, src += stride, srca += stride)
+        for (x = 0; x < w; x++) {
+            const unsigned char c = src[x];
+            dst[4*x + 0] = c;
+            dst[4*x + 1] = c;
+            dst[4*x + 2] = c;
+            dst[4*x + 3] = -srca[x];
+        }
+}
+
+#if USE_VAAPI_IA44_FORMATS
+static void draw_alpha_IA44(int x0, int y0, int w, int h,
+                            unsigned char *src, unsigned char *srca,
+                            int stride)
+{
+    int x, y;
+    const unsigned int dststride = va_osd_image.pitches[0];
+    unsigned char *dst = get_osd_image_data(x0, y0);
+
+    for (y = 0; y < h; y++, dst += dststride)
+        for (x = 0; x < w; x++)
+            dst[x] = (src[y*stride + x] & 0xf0) | (-srca[y*stride + x] >> 4);
+}
+
+static void draw_alpha_AI44(int x0, int y0, int w, int h,
+                            unsigned char *src, unsigned char *srca,
+                            int stride)
+{
+    int x, y;
+    const unsigned int dststride = va_osd_image.pitches[0];
+    unsigned char *dst = get_osd_image_data(x0, y0);
+
+    for (y = 0; y < h; y++, dst += dststride)
+        for (x = 0; x < w; x++)
+            dst[x] = (src[y*stride + x] >> 4) | (-srca[y*stride + x] & 0xf0);
+}
+#endif
+
+static void draw_alpha_IA88(int x0, int y0, int w, int h,
+                            unsigned char *src, unsigned char *srca,
+                            int stride)
+{
+    int x, y;
+    const unsigned int dststride = va_osd_image.pitches[0];
+    unsigned char *dst = get_osd_image_data(x0, y0);
+
+    for (y = 0; y < h; y++, dst += dststride)
+        for (x = 0; x < w; x++) {
+            dst[2*x + 0] =  src [y*stride + x];
+            dst[2*x + 1] = -srca[y*stride + x];
+        }
+}
+
+static void draw_alpha_AI88(int x0, int y0, int w, int h,
+                            unsigned char *src, unsigned char *srca,
+                            int stride)
+{
+    int x, y;
+    const unsigned int dststride = va_osd_image.pitches[0];
+    unsigned char *dst = get_osd_image_data(x0, y0);
+
+    for (y = 0; y < h; y++, dst += dststride)
+        for (x = 0; x < w; x++) {
+            dst[2*x + 0] = -srca[y*stride + x];
+            dst[2*x + 1] =  src [y*stride + x];
+        }
+}
+
+///< List of subpicture formats in preferred order
+static const struct {
+    uint32_t format;
+    draw_alpha_func draw_alpha;
+}
+va_osd_info[] = {
+#if USE_VAAPI_IA44_FORMATS
+    { VA_FOURCC('I','A','4','4'), draw_alpha_IA44  },
+    { VA_FOURCC('A','I','4','4'), draw_alpha_AI44  },
+#endif
+    { VA_FOURCC('I','A','8','8'), draw_alpha_IA88  },
+    { VA_FOURCC('A','I','8','8'), draw_alpha_AI88  },
+    { VA_FOURCC('B','G','R','A'), draw_alpha_rgb32 },
+    { VA_FOURCC('R','G','B','A'), draw_alpha_rgb32 },
+    { 0, NULL }
+};
+
+static uint8_t *gen_osd_palette(const VAImage *image)
+{
+    uint8_t *palette;
+    int i, is_rgb;
+    int r_idx = -1, g_idx = -1, b_idx = -1;
+    int y_idx = -1, u_idx = -1, v_idx = -1;
+    int i_idx = -1, a_idx = -1;
+
+    if (image->num_palette_entries < 1)
+        return NULL;
+
+    palette = malloc(image->num_palette_entries * image->entry_bytes);
+    if (!palette)
+        return NULL;
+
+    for (i = 0; i < image->entry_bytes; i++) {
+        switch (image->component_order[i]) {
+        case 'R': r_idx = i; is_rgb = 1; break;
+        case 'G': g_idx = i; is_rgb = 1; break;
+        case 'B': b_idx = i; is_rgb = 1; break;
+        case 'Y': y_idx = i; is_rgb = 0; break;
+        case 'U': u_idx = i; is_rgb = 0; break;
+        case 'V': v_idx = i; is_rgb = 0; break;
+        case 'I': i_idx = i; break;
+        case 'A': a_idx = i; break;
+        }
+    }
+
+    if (r_idx != -1 && g_idx != -1 && b_idx != -1) {      /* RGB format */
+        for (i = 0; i < image->num_palette_entries; i++) {
+            const int n = i * image->entry_bytes;
+            palette[n + r_idx] = i * 0xff / (image->num_palette_entries - 1);
+            palette[n + g_idx] = i * 0xff / (image->num_palette_entries - 1);
+            palette[n + b_idx] = i * 0xff / (image->num_palette_entries - 1);
+        }
+    }
+    else if (y_idx != -1 && u_idx != -1 && v_idx != -1) { /* YUV format */
+        for (i = 0; i < image->num_palette_entries; i++) {
+            const int n = i * image->entry_bytes;
+            palette[n + y_idx] = i * 0xff / (image->num_palette_entries - 1);
+            palette[n + u_idx] = 0x80;
+            palette[n + v_idx] = 0x80;
+        }
+    }
+    else if (i_idx != -1 && a_idx != -1) {/* AYUV format (GMA500 "psb" bug) */
+        for (i = 0; i < image->num_palette_entries; i++) {
+            const int n = i * image->entry_bytes;
+            palette[n + 0] = 0x80;
+            palette[n + 1] = 0x80;
+            palette[n + 2] = 16 + i * 220 / (image->num_palette_entries - 1);
+            palette[n + 3] = 0;
+        }
+    }
+    else {
+        mp_msg(MSGT_VO, MSGL_ERR, "[vo_vaapi] Could not set up subpicture palette\n");
+        free(palette);
+        palette = NULL;
+    }
+    return palette;
+}
+
+static void disable_osd(void)
+{
+    if (!va_osd_associated)
+        return;
+
+    vaDeassociateSubpicture(va_context->display,
+                            va_osd_subpicture,
+                            va_surface_ids, va_num_surfaces);
+
+    va_osd_associated = 0;
+}
+
+static int enable_osd(void)
+{
+    VAStatus status;
+
+    disable_osd();
+
+    status = vaAssociateSubpicture2(va_context->display,
+                                    va_osd_subpicture,
+                                    va_surface_ids, va_num_surfaces,
+                                    0, 0,
+                                    va_osd_image.width, va_osd_image.height,
+                                    0, 0,
+                                    g_image_width, g_image_height,
+                                    0);
+    if (!check_status(status, "vaAssociateSubpicture()"))
+        return -1;
+
+    va_osd_associated = 1;
+    return 0;
+}
+
+static void destroy_osd(void)
+{
+    disable_osd();
+
+    if (va_osd_subpicture != VA_INVALID_ID) {
+        vaDestroySubpicture(va_context->display, va_osd_subpicture);
+        va_osd_subpicture = VA_INVALID_ID;
+    }
+
+    if (va_osd_image.image_id != VA_INVALID_ID) {
+        vaDestroyImage(va_context->display, va_osd_image.image_id);
+        va_osd_image.image_id = VA_INVALID_ID;
+        va_osd_image.width    = 0;
+        va_osd_image.height   = 0;
+    }
+}
+
+static void create_osd(void)
+{
+    VAStatus status;
+    int i, j;
+
+    for (i = 0; va_osd_info[i].format; i++) {
+        for (j = 0; j < va_num_subpic_formats; j++)
+            if (va_subpic_formats[j].fourcc == va_osd_info[i].format)
+                break;
+        if (j < va_num_subpic_formats &&
+            vaCreateImage(va_context->display, &va_subpic_formats[j],
+                          g_output_rect.width, g_output_rect.height,
+                          &va_osd_image) == VA_STATUS_SUCCESS) {
+            va_osd_palette = gen_osd_palette(&va_osd_image);
+            if (((!va_osd_image.num_palette_entries) ^ (!va_osd_palette)) == 0)
+                break;
+            vaDestroyImage(va_context->display, va_osd_image.image_id);
+            va_osd_image.image_id = VA_INVALID_ID;
+        }
+    }
+
+    if (va_osd_info[i].format &&
+        vaCreateSubpicture(va_context->display, va_osd_image.image_id,
+                           &va_osd_subpicture) == VA_STATUS_SUCCESS) {
+        va_osd_draw_alpha = va_osd_info[i].draw_alpha;
+        if (va_osd_palette) {
+            status = vaSetImagePalette(va_context->display,
+                                       va_osd_image.image_id, va_osd_palette);
+            check_status(status, "vaSetImagePalette()");
+        }
+        mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] Using %s surface for OSD\n",
+               string_of_VAImageFormat(&va_osd_image.format));
+    }
+}
+
+static void ensure_osd(void)
+{
+    if (g_output_rect.width  == va_osd_image.width &&
+        g_output_rect.height == va_osd_image.height)
+        return;
+
+    destroy_osd();
+    create_osd();
+}
+
+static inline unsigned char *get_eosd_image_data(int x0, int y0)
+{
+    return (va_eosd_image_data +
+            va_eosd_image.offsets[0] +
+            va_eosd_image.pitches[0] * y0 +
+            x0 * ((va_eosd_image.format.bits_per_pixel + 7) / 8));
+}
+
+static void eosd_draw_alpha_bgra(unsigned char *src,
+                                 int src_w, int src_h, int src_stride,
+                                 int dst_x, int dst_y,
+                                 uint32_t color)
+{
+    int x, y;
+    const unsigned int dst_stride = va_eosd_image.pitches[0];
+    unsigned char *dst = get_eosd_image_data(dst_x, dst_y);
+    const unsigned int r = (color >> 24) & 0xff;
+    const unsigned int g = (color >> 16) & 0xff;
+    const unsigned int b = (color >>  8) & 0xff;
+    const unsigned int a = 0xff - (color & 0xff);
+
+    for (y = 0; y < src_h; y++, dst += dst_stride, src += src_stride)
+        for (x = 0; x < src_w; x++) {
+            const unsigned int v = src[x];
+            dst[4*x + 0] = (b * v + dst[4*x + 0] * (0xff - v)) / 255;
+            dst[4*x + 1] = (g * v + dst[4*x + 1] * (0xff - v)) / 255;
+            dst[4*x + 2] = (r * v + dst[4*x + 2] * (0xff - v)) / 255;
+            dst[4*x + 3] = (a * v + dst[4*x + 3] * (0xff - v)) / 255;
+        }
+}
+
+static void eosd_draw_alpha_rgba(unsigned char *src,
+                                 int src_w, int src_h, int src_stride,
+                                 int dst_x, int dst_y,
+                                 uint32_t color)
+{
+    int x, y;
+    const unsigned int dst_stride = va_eosd_image.pitches[0];
+    unsigned char *dst = get_eosd_image_data(dst_x, dst_y);
+    const unsigned int r = (color >> 24) & 0xff;
+    const unsigned int g = (color >> 16) & 0xff;
+    const unsigned int b = (color >>  8) & 0xff;
+    const unsigned int a = 0xff - (color & 0xff);
+
+    for (y = 0; y < src_h; y++, dst += dst_stride, src += src_stride)
+        for (x = 0; x < src_w; x++) {
+            const unsigned int v = src[x];
+            dst[4*x + 0] = (r * v + dst[4*x + 0] * (0xff - v)) / 255;
+            dst[4*x + 1] = (g * v + dst[4*x + 1] * (0xff - v)) / 255;
+            dst[4*x + 2] = (b * v + dst[4*x + 2] * (0xff - v)) / 255;
+            dst[4*x + 3] = (a * v + dst[4*x + 3] * (0xff - v)) / 255;
+        }
+}
+
+static void disable_eosd(void)
+{
+    if (!va_eosd_associated)
+        return;
+
+    vaDeassociateSubpicture(va_context->display,
+                            va_eosd_subpicture,
+                            va_surface_ids, va_num_surfaces);
+
+    va_eosd_associated = 0;
+}
+
+static int enable_eosd(void)
+{
+    VAStatus status;
+
+    if (va_eosd_associated)
+        return 0;
+
+    status = vaAssociateSubpicture2(va_context->display,
+                                    va_eosd_subpicture,
+                                    va_surface_ids, va_num_surfaces,
+                                    0, 0, g_image_width, g_image_height,
+                                    0, 0, g_image_width, g_image_height,
+                                    0);
+    if (!check_status(status, "vaAssociateSubpicture()"))
+        return -1;
+
+    va_eosd_associated = 1;
+    return 0;
+}
+
+///< List of subpicture formats in preferred order
+static const struct {
+    uint32_t format;
+    eosd_draw_alpha_func draw_alpha;
+}
+va_eosd_info[] = {
+    { VA_FOURCC('B','G','R','A'), eosd_draw_alpha_bgra },
+    { VA_FOURCC('R','G','B','A'), eosd_draw_alpha_rgba },
+    { 0, NULL }
+};
+
+static int is_direct_mapping_init(void)
+{
+    VADisplayAttribute attr;
+    VAStatus status;
+
+    if (va_dm < 2)
+        return va_dm;
+
+    /* If the driver doesn't make a copy of the VA surface for
+       display, then we have to retain it until it's no longer the
+       visible surface. In other words, if the driver is using
+       DirectSurface mode, we don't want to decode the new surface
+       into the previous one that was used for display. */
+    attr.type  = VADisplayAttribDirectSurface;
+    attr.flags = VA_DISPLAY_ATTRIB_GETTABLE;
+
+    status = vaGetDisplayAttributes(va_context->display, &attr, 1);
+    if (status == VA_STATUS_SUCCESS)
+        return !attr.value;
+    return 0;
+}
+
+static inline int is_direct_mapping(void)
+{
+    static int dm = -1;
+    if (dm < 0) {
+        dm = is_direct_mapping_init();
+        if (dm)
+            mp_msg(MSGT_VO, MSGL_INFO,
+                   "[vo_vaapi] Using 1:1 VA surface mapping\n");
+    }
+    return dm;
+}
+
+static int int_012(int *n)
+{
+    return *n >= 0 && *n <= 2;
+}
+
+static const opt_t subopts[] = {
+    { "dm",          OPT_ARG_INT,  &va_dm,        (opt_test_f)int_012 },
+    { "stats",       OPT_ARG_BOOL, &cpu_stats,    NULL },
+    { "deint",       OPT_ARG_INT,  &g_deint,      (opt_test_f)int_012 },
+#if USE_VAAPI_COLORSPACE
+    { "colorspace",  OPT_ARG_INT,  &g_colorspace, (opt_test_f)int_012 },
+#endif
+#if CONFIG_GL
+    { "gl",          OPT_ARG_BOOL, &gl_enabled,   NULL },
+    { "glfinish",    OPT_ARG_BOOL, &gl_finish,    NULL },
+#if USE_VAAPI_GLX_BIND
+    { "bind",        OPT_ARG_BOOL, &gl_binding,   NULL },
+#endif
+    { "reflect",     OPT_ARG_BOOL, &gl_reflect,   NULL },
+    { "tfp",         OPT_ARG_BOOL, &gl_use_tfp,   NULL },
+#endif
+#if CONFIG_XRENDER
+    { "xrender",     OPT_ARG_BOOL, &xr_enabled,   NULL },
+#endif
+    { NULL, }
+};
+
+static int preinit(const char *arg)
+{
+    VADisplayAttribute *display_attrs;
+    VAStatus status;
+    int va_major_version, va_minor_version;
+    int i, max_image_formats, max_subpic_formats, max_profiles;
+    int num_display_attrs, max_display_attrs;
+
+    va_dm = 2;
+    g_deint = 0;
+    g_deint_type = 2;
+    g_colorspace = 1;
+    if (subopt_parse(arg, subopts) != 0) {
+        mp_msg(MSGT_VO, MSGL_FATAL,
+               "\n-vo vaapi command line help:\n"
+               "Example: mplayer -vo vaapi:gl\n"
+               "\nOptions:\n"
+               "  dm\n"
+               "    0: use least-recently-used VA surface\n"
+               "    1: identify VA surface with MPI index\n"
+               "    2: auto-detect use of direct surface mapping (default)\n"
+               "  deint (all modes > 0 respect -field-dominance)\n"
+               "    0: no deinterlacing (default)\n"
+               "    1: only show first field\n"
+               "    2: bob deinterlacing\n"
+               "  colorspace\n"
+               "    0: guess based on video resolution\n"
+               "    1: ITU-R BT.601 (default)\n"
+               "    2: ITU-R BT.709\n"
+#if CONFIG_GL
+               "  gl\n"
+               "    Enable OpenGL rendering\n"
+               "  glfinish\n"
+               "    Call glFinish() before swapping buffers\n"
+               "  tfp\n"
+               "    Use GLX texture-from-pixmap instead of VA/GLX extensions\n"
+#if USE_VAAPI_GLX_BIND
+               "  bind\n"
+               "    Use VA surface binding instead of copy\n"
+#endif
+               "  reflect\n"
+               "    Enable OpenGL reflection effects\n"
+#endif
+#if CONFIG_XRENDER
+               "  xrender\n"
+               "    Enable Xrender rendering, thus vaPutSurface() to a Pixmap\n"
+#endif
+               "\n" );
+        return -1;
+    }
+    if (gl_enabled && xr_enabled) {
+        mp_msg(MSGT_VO, MSGL_ERR, "[vo_vaapi] User requested both Xrender and OpenGL rendering\n");
+        return -1;
+    }
+    if (g_deint)
+        g_deint_type = g_deint;
+#if CONFIG_GL
+    if (gl_enabled)
+        mp_msg(MSGT_VO, MSGL_INFO, "[vo_vaapi] Using OpenGL rendering%s\n",
+               gl_reflect ? ", with reflection effects" : "");
+#endif
+#if CONFIG_XRENDER
+    if (xr_enabled)
+        mp_msg(MSGT_VO, MSGL_INFO, "[vo_vaapi] Using Xrender rendering\n");
+#endif
+
+    stats_init();
+
+#if CONFIG_GL
+    if (gl_enabled && !init_mpglcontext(&gl_context, GLTYPE_X11))
+        return -1;
+    else
+#endif
+    if (!vo_init())
+        return -1;
+#if CONFIG_XRENDER
+    if (xr_enabled && !init_xrender())
+        return -1;
+#endif
+
+    va_context = calloc(1, sizeof(*va_context));
+    if (!va_context)
+        return -1;
+
+#if CONFIG_VAAPI_GLX
+    if (gl_enabled)
+        va_context->display = vaGetDisplayGLX(mDisplay);
+    else
+#endif
+        va_context->display = vaGetDisplay(mDisplay);
+    if (!va_context->display)
+        return -1;
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] preinit(): VA display %p\n", va_context->display);
+
+    status = vaInitialize(va_context->display, &va_major_version, &va_minor_version);
+    if (!check_status(status, "vaInitialize()"))
+        return -1;
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] preinit(): VA API version %d.%d\n",
+           va_major_version, va_minor_version);
+
+    max_image_formats = vaMaxNumImageFormats(va_context->display);
+    va_image_formats = calloc(max_image_formats, sizeof(*va_image_formats));
+    if (!va_image_formats)
+        return -1;
+    status = vaQueryImageFormats(va_context->display, va_image_formats, &va_num_image_formats);
+    if (!check_status(status, "vaQueryImageFormats()"))
+        return -1;
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] preinit(): %d image formats available\n",
+           va_num_image_formats);
+    for (i = 0; i < va_num_image_formats; i++)
+        mp_msg(MSGT_VO, MSGL_DBG2, "  %s\n", string_of_VAImageFormat(&va_image_formats[i]));
+
+    max_subpic_formats = vaMaxNumSubpictureFormats(va_context->display);
+    va_subpic_formats = calloc(max_subpic_formats, sizeof(*va_subpic_formats));
+    if (!va_subpic_formats)
+        return -1;
+    va_subpic_flags = calloc(max_subpic_formats, sizeof(*va_subpic_flags));
+    if (!va_subpic_flags)
+        return -1;
+    status = vaQuerySubpictureFormats(va_context->display, va_subpic_formats, va_subpic_flags, &va_num_subpic_formats);
+    if (!check_status(status, "vaQuerySubpictureFormats()"))
+        va_num_subpic_formats = 0; /* XXX: don't error out for IEGD */
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] preinit(): %d subpicture formats available\n",
+           va_num_subpic_formats);
+    for (i = 0; i < va_num_subpic_formats; i++)
+        mp_msg(MSGT_VO, MSGL_DBG2, "  %s, flags 0x%x\n", string_of_VAImageFormat(&va_subpic_formats[i]), va_subpic_flags[i]);
+
+    max_profiles = vaMaxNumProfiles(va_context->display);
+    va_profiles = calloc(max_profiles, sizeof(*va_profiles));
+    if (!va_profiles)
+        return -1;
+    status = vaQueryConfigProfiles(va_context->display, va_profiles, &va_num_profiles);
+    if (!check_status(status, "vaQueryConfigProfiles()"))
+        return -1;
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] preinit(): %d profiles available\n",
+           va_num_profiles);
+    for (i = 0; i < va_num_profiles; i++)
+        mp_msg(MSGT_VO, MSGL_DBG2, "  %s\n", string_of_VAProfile(va_profiles[i]));
+
+    va_osd_subpicture      = VA_INVALID_ID;
+    va_osd_image.image_id  = VA_INVALID_ID;
+    va_eosd_subpicture     = VA_INVALID_ID;
+    va_eosd_image.image_id = VA_INVALID_ID;
+
+    max_display_attrs = vaMaxNumDisplayAttributes(va_context->display);
+    display_attrs = calloc(max_display_attrs, sizeof(*display_attrs));
+    if (display_attrs) {
+        num_display_attrs = 0;
+        status = vaQueryDisplayAttributes(va_context->display,
+                                          display_attrs, &num_display_attrs);
+        if (check_status(status, "vaQueryDisplayAttributes()")) {
+            for (i = 0; i < num_display_attrs; i++) {
+                VADisplayAttribute *attr;
+                switch (display_attrs[i].type) {
+                case VADisplayAttribBrightness:
+                    attr = &va_equalizer.brightness;
+                    break;
+                case VADisplayAttribContrast:
+                    attr = &va_equalizer.contrast;
+                    break;
+                case VADisplayAttribHue:
+                    attr = &va_equalizer.hue;
+                    break;
+                case VADisplayAttribSaturation:
+                    attr = &va_equalizer.saturation;
+                    break;
+                default:
+                    attr = NULL;
+                    break;
+                }
+                if (attr)
+                    *attr = display_attrs[i];
+            }
+        }
+        free(display_attrs);
+    }
+    return 0;
+}
+
+static void free_video_specific(void)
+{
+    int i;
+
+#if CONFIG_VAAPI_GLX
+    if (gl_surface) {
+        VAStatus status;
+        status = vaDestroySurfaceGLX(va_context->display, gl_surface);
+        check_status(status, "vaDestroySurfaceGLX()");
+        gl_surface = NULL;
+    }
+#endif
+
+    if (va_context && va_context->context_id) {
+        vaDestroyContext(va_context->display, va_context->context_id);
+        va_context->context_id = 0;
+    }
+
+    if (va_free_surfaces) {
+        for (i = 0; i < va_num_surfaces; i++) {
+            if (!va_free_surfaces[i])
+                continue;
+            if (va_free_surfaces[i]->image.image_id != VA_INVALID_ID) {
+                vaDestroyImage(va_context->display,
+                               va_free_surfaces[i]->image.image_id);
+                va_free_surfaces[i]->image.image_id = VA_INVALID_ID;
+            }
+            free(va_free_surfaces[i]);
+            va_free_surfaces[i] = NULL;
+        }
+        free(va_free_surfaces);
+        va_free_surfaces = NULL;
+        va_free_surfaces_head_index = 0;
+        va_free_surfaces_tail_index = 0;
+    }
+
+    g_output_surface = 0;
+    memset(g_output_surfaces, 0, sizeof(g_output_surfaces));
+
+    if (va_osd_palette) {
+        free(va_osd_palette);
+        va_osd_palette = NULL;
+    }
+
+    disable_eosd();
+    disable_osd();
+
+    if (va_eosd_subpicture != VA_INVALID_ID) {
+        vaDestroySubpicture(va_context->display, va_eosd_subpicture);
+        va_eosd_subpicture = VA_INVALID_ID;
+    }
+
+    if (va_eosd_image.image_id != VA_INVALID_ID) {
+        vaDestroyImage(va_context->display, va_eosd_image.image_id);
+        va_eosd_image.image_id = VA_INVALID_ID;
+    }
+
+    destroy_osd();
+
+    if (va_surface_ids) {
+        vaDestroySurfaces(va_context->display, va_surface_ids, va_num_surfaces);
+        free(va_surface_ids);
+        va_surface_ids = NULL;
+        va_num_surfaces = 0;
+    }
+
+    if (va_context && va_context->config_id) {
+        vaDestroyConfig(va_context->display, va_context->config_id);
+        va_context->config_id = 0;
+    }
+
+    if (va_entrypoints) {
+        free(va_entrypoints);
+        va_entrypoints = NULL;
+    }
+
+#if CONFIG_GL
+    if (gl_pixmap) {
+        x11_trap_errors();
+        mpglXDestroyPixmap(mDisplay, gl_pixmap);
+        XSync(mDisplay, False);
+        x11_untrap_errors();
+        gl_pixmap = None;
+    }
+
+    if (g_image_pixmap) {
+        XFreePixmap(mDisplay, g_image_pixmap);
+        g_image_pixmap = None;
+    }
+
+    if (gl_texture) {
+        glDeleteTextures(1, &gl_texture);
+        gl_texture = GL_NONE;
+    }
+#endif
+
+#if CONFIG_XRENDER
+    if (xr_window_picture) {
+        XRenderFreePicture(mDisplay, xr_window_picture);
+        xr_window_picture = None;
+    }
+#endif
+
+    g_is_visible = 0;
+}
+
+static void uninit(void)
+{
+    if (!vo_config_count)
+        return;
+
+    free_video_specific();
+
+    if (va_profiles) {
+        free(va_profiles);
+        va_profiles = NULL;
+    }
+
+    if (va_subpic_flags) {
+        free(va_subpic_flags);
+        va_subpic_flags = NULL;
+    }
+
+    if (va_subpic_formats) {
+        free(va_subpic_formats);
+        va_subpic_formats = NULL;
+    }
+
+    if (va_image_formats) {
+        free(va_image_formats);
+        va_image_formats = NULL;
+    }
+
+    if (va_context && va_context->display) {
+        vaTerminate(va_context->display);
+        va_context->display = NULL;
+    }
+
+    if (va_context) {
+        free(va_context);
+        va_context = NULL;
+    }
+
+#ifdef CONFIG_XF86VM
+    vo_vm_close();
+#endif
+#if CONFIG_XRENDER
+    if (xr_enabled)
+        uninit_xrender();
+#endif
+#if CONFIG_GL
+    if (gl_enabled)
+        uninit_mpglcontext(&gl_context);
+    else
+#endif
+    vo_x11_uninit();
+
+    stats_exit();
+}
+
+static int config_x11(uint32_t width, uint32_t height,
+                      uint32_t display_width, uint32_t display_height,
+                      uint32_t flags, char *title)
+{
+    Colormap cmap;
+    XVisualInfo visualInfo;
+    XVisualInfo *vi;
+    XSetWindowAttributes xswa;
+    unsigned long xswa_mask;
+    XWindowAttributes wattr;
+    int depth;
+
+#ifdef CONFIG_GUI
+    if (use_gui)
+        guiGetEvent(guiSetShVideo, 0);  // the GUI will set up / resize our window
+    else
+#endif
+    {
+#ifdef CONFIG_XF86VM
+        if (flags & VOFLAG_MODESWITCHING)
+            vo_vm_switch();
+#endif
+        XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &wattr);
+        depth = wattr.depth;
+        if (depth != 15 && depth != 16 && depth != 24 && depth != 32)
+            depth = 24;
+        XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &visualInfo);
+
+#if CONFIG_GL
+        if (gl_enabled) {
+            vi = glXChooseVisual(mDisplay, mScreen, gl_visual_attr);
+            if (!vi)
+                return -1;
+            cmap = XCreateColormap(mDisplay, mRootWin, vi->visual, AllocNone);
+            if (cmap == None)
+                return -1;
+        }
+        else
+#endif
+        {
+            vi = &visualInfo;
+            XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, vi);
+            cmap = CopyFromParent;
+        }
+
+        vo_x11_create_vo_window(vi,
+                                vo_dx, vo_dy, display_width, display_height,
+                                flags, cmap, "vaapi", title);
+
+        if (vi != &visualInfo)
+            XFree(vi);
+
+        xswa_mask             = CWBorderPixel | CWBackPixel;
+        xswa.border_pixel     = 0;
+        xswa.background_pixel = 0;
+        XChangeWindowAttributes(mDisplay, vo_window, xswa_mask, &xswa);
+
+#ifdef CONFIG_XF86VM
+        if (flags & VOFLAG_MODESWITCHING) {
+            /* Grab the mouse pointer in our window */
+            if (vo_grabpointer)
+                XGrabPointer(mDisplay, vo_window, True, 0,
+                             GrabModeAsync, GrabModeAsync,
+                             vo_window, None, CurrentTime);
+            XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime);
+        }
+#endif
+    }
+    return 0;
+}
+
+#if CONFIG_GL
+static GLXFBConfig *get_fbconfig_for_depth(int depth)
+{
+    GLXFBConfig *fbconfigs, *ret = NULL;
+    int          n_elements, i, found;
+    int          db, stencil, alpha, mipmap, rgba, value;
+
+    static GLXFBConfig *cached_config = NULL;
+    static int          have_cached_config = 0;
+
+    if (have_cached_config)
+        return cached_config;
+
+    fbconfigs = glXGetFBConfigs(mDisplay, mScreen, &n_elements);
+
+    db      = SHRT_MAX;
+    stencil = SHRT_MAX;
+    mipmap  = 0;
+    rgba    = 0;
+
+    found = n_elements;
+
+    for (i = 0; i < n_elements; i++) {
+        XVisualInfo *vi;
+        int          visual_depth;
+
+        vi = glXGetVisualFromFBConfig(mDisplay, fbconfigs[i]);
+        if (!vi)
+            continue;
+
+        visual_depth = vi->depth;
+        XFree(vi);
+
+        if (visual_depth != depth)
+            continue;
+
+        glXGetFBConfigAttrib(mDisplay, fbconfigs[i], GLX_ALPHA_SIZE, &alpha);
+        glXGetFBConfigAttrib(mDisplay, fbconfigs[i], GLX_BUFFER_SIZE, &value);
+        if (value != depth && (value - alpha) != depth)
+            continue;
+
+        value = 0;
+        if (depth == 32) {
+            glXGetFBConfigAttrib(mDisplay, fbconfigs[i],
+                                 GLX_BIND_TO_TEXTURE_RGBA_EXT, &value);
+            if (value)
+                rgba = 1;
+        }
+
+        if (!value) {
+            if (rgba)
+                continue;
+
+            glXGetFBConfigAttrib(mDisplay, fbconfigs[i],
+                                 GLX_BIND_TO_TEXTURE_RGB_EXT, &value);
+            if (!value)
+                continue;
+        }
+
+        glXGetFBConfigAttrib(mDisplay, fbconfigs[i], GLX_DOUBLEBUFFER, &value);
+        if (value > db)
+            continue;
+        db = value;
+
+        glXGetFBConfigAttrib(mDisplay, fbconfigs[i], GLX_STENCIL_SIZE, &value);
+        if (value > stencil)
+            continue;
+        stencil = value;
+
+        found = i;
+    }
+
+    if (found != n_elements) {
+        ret = malloc(sizeof(*ret));
+        *ret = fbconfigs[found];
+    }
+
+    if (n_elements)
+        XFree(fbconfigs);
+
+    have_cached_config = 1;
+    cached_config = ret;
+    return ret;
+}
+
+static int config_tfp(unsigned int width, unsigned int height)
+{
+    GLXFBConfig *fbconfig;
+    int attribs[7], i = 0;
+    const int depth = 24;
+
+    if (!mpglXBindTexImage || !mpglXReleaseTexImage) {
+        mp_msg(MSGT_VO, MSGL_ERR, "[vo_vaapi] No GLX texture-from-pixmap extension available\n");
+        return -1;
+    }
+
+    if (depth != 24 && depth != 32)
+        return -1;
+
+    g_image_pixmap = XCreatePixmap(mDisplay, vo_window, width, height, depth);
+    if (!g_image_pixmap) {
+        mp_msg(MSGT_VO, MSGL_ERR, "[vo_vaapi] Could not create X11 pixmap\n");
+        return -1;
+    }
+
+    fbconfig = get_fbconfig_for_depth(depth);
+    if (!fbconfig) {
+        mp_msg(MSGT_VO, MSGL_ERR, "[vo_vaapi] Could not find an FBConfig for 32-bit pixmap\n");
+        return -1;
+    }
+
+    attribs[i++] = GLX_TEXTURE_TARGET_EXT;
+    attribs[i++] = GLX_TEXTURE_2D_EXT;
+    attribs[i++] = GLX_TEXTURE_FORMAT_EXT;
+    if (depth == 24)
+        attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT;
+    else if (depth == 32)
+        attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT;
+    attribs[i++] = GLX_MIPMAP_TEXTURE_EXT;
+    attribs[i++] = GL_FALSE;
+    attribs[i++] = None;
+
+    x11_trap_errors();
+    gl_pixmap = mpglXCreatePixmap(mDisplay, *fbconfig, g_image_pixmap, attribs);
+    XSync(mDisplay, False);
+    if (x11_untrap_errors()) {
+        mp_msg(MSGT_VO, MSGL_ERR, "[vo_vaapi] Could not create GLX pixmap\n");
+        return -1;
+    }
+    return 0;
+}
+
+static int config_glx(unsigned int width, unsigned int height)
+{
+    if (gl_context.setGlWindow(&gl_context) == SET_WINDOW_FAILED)
+        return -1;
+
+    glDisable(GL_DEPTH_TEST);
+    glDepthMask(GL_FALSE);
+    glDisable(GL_CULL_FACE);
+    glEnable(GL_TEXTURE_2D);
+    glDrawBuffer(vo_doublebuffering ? GL_BACK : GL_FRONT);
+    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+    /* Create TFP resources */
+    if (gl_use_tfp && config_tfp(width, height) == 0)
+        mp_msg(MSGT_VO, MSGL_INFO, "[vo_vaapi] Using GLX texture-from-pixmap extension\n");
+    else
+        gl_use_tfp = 0;
+
+    /* Create OpenGL texture */
+    /* XXX: assume GL_ARB_texture_non_power_of_two is available */
+    glEnable(GL_TEXTURE_2D);
+    glGenTextures(1, &gl_texture);
+    mpglBindTexture(GL_TEXTURE_2D, gl_texture);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    if (!gl_use_tfp) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
+                     GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+    }
+    mpglBindTexture(GL_TEXTURE_2D, 0);
+    glDisable(GL_TEXTURE_2D);
+
+    glClearColor(0.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    if (gl_build_font() < 0)
+        return -1;
+    return 0;
+}
+#endif
+
+#if CONFIG_XRENDER
+static XRenderPictFormat *get_xrender_argb32_format(void)
+{
+    static XRenderPictFormat *pictformat = NULL;
+    XRenderPictFormat templ;
+
+    const unsigned long mask =
+        PictFormatType      |
+        PictFormatDepth     |
+        PictFormatRed       |
+        PictFormatRedMask   |
+        PictFormatGreen     |
+        PictFormatGreenMask |
+        PictFormatBlue      |
+        PictFormatBlueMask  |
+        PictFormatAlphaMask;
+
+    if (pictformat)
+        return pictformat;
+
+    /* First, look for a 32-bit format which ignores the alpha component */
+    templ.depth            = 32;
+    templ.type             = PictTypeDirect;
+    templ.direct.red       = 16;
+    templ.direct.green     = 8;
+    templ.direct.blue      = 0;
+    templ.direct.redMask   = 0xff;
+    templ.direct.greenMask = 0xff;
+    templ.direct.blueMask  = 0xff;
+    templ.direct.alphaMask = 0;
+
+    pictformat = XRenderFindFormat(mDisplay, mask, &templ, 0);
+
+    if (!pictformat) {
+        /* Not all X servers support xRGB32 formats. However, the
+         * XRENDER spec says that they must support an ARGB32 format,
+         * so we can always return that.
+         */
+        pictformat = XRenderFindStandardFormat(mDisplay, PictStandardARGB32);
+        if (!pictformat)
+            mp_msg(MSGT_VO, MSGL_ERR, "XRENDER ARGB32 format not supported\n");
+    }
+    return pictformat;
+}
+
+static int create_xrender_specific(void)
+{
+    XRenderPictFormat *pictformat;
+
+    if (g_output_rect.width == 0 && g_output_rect.height == 0)
+        return 0;
+
+    g_image_pixmap = XCreatePixmap(mDisplay, vo_window, g_output_rect.width,
+                                   g_output_rect.height, 32);
+    if (!g_image_pixmap) {
+        mp_msg(MSGT_VO, MSGL_ERR, "Could not create video pixmap\n");
+        return -1;
+    }
+
+    pictformat = get_xrender_argb32_format();
+    if (!pictformat)
+        return -1;
+    xr_video_picture = XRenderCreatePicture(mDisplay, g_image_pixmap,
+                                            pictformat, 0, NULL);
+    if (!xr_video_picture) {
+        mp_msg(MSGT_VO, MSGL_ERR, "Could not create XRENDER backing picture for Pixmap\n");
+        return -1;
+    }
+    return 0;
+}
+
+static void free_xrender_specific(void)
+{
+    if (xr_video_picture) {
+        XRenderFreePicture(mDisplay, xr_video_picture);
+        xr_video_picture = None;
+    }
+
+    if (g_image_pixmap) {
+        XFreePixmap(mDisplay, g_image_pixmap);
+        g_image_pixmap = None;
+    }
+}
+
+static int reset_xrender_specific(void)
+{
+    free_xrender_specific();
+    return create_xrender_specific();
+}
+
+/* XXX: create a Pixmap as large as the display rect */
+static int config_xrender(unsigned int width, unsigned int height)
+{
+    XWindowAttributes wattr;
+    XRenderPictFormat *pictformat;
+
+    XGetWindowAttributes(mDisplay, vo_window, &wattr);
+    pictformat = XRenderFindVisualFormat(mDisplay, wattr.visual);
+    if (!pictformat) {
+        mp_msg(MSGT_VO, MSGL_ERR, "XRENDER does not support Window visual\n");
+        return -1;
+    }
+
+    xr_window_picture = XRenderCreatePicture(mDisplay, vo_window, pictformat,
+                                             0, NULL);
+    if (!xr_window_picture) {
+        mp_msg(MSGT_VO, MSGL_ERR, "Could not create XRENDER backing picture for Window\n");
+        return -1;
+    }
+    return reset_xrender_specific();
+}
+#endif
+
+static int config_vaapi(uint32_t width, uint32_t height, uint32_t format)
+{
+    VAConfigAttrib attrib;
+    VAStatus status;
+    int i, j, profile, entrypoint, max_entrypoints, num_surfaces;
+
+    /* Create video surfaces */
+    if (!IMGFMT_IS_VAAPI(format))
+        num_surfaces = MAX_OUTPUT_SURFACES;
+    else {
+        switch (IMGFMT_VAAPI_CODEC(format)) {
+        case IMGFMT_VAAPI_CODEC_MPEG2:
+            num_surfaces = NUM_VIDEO_SURFACES_MPEG2;
+            break;
+        case IMGFMT_VAAPI_CODEC_MPEG4:
+            num_surfaces = NUM_VIDEO_SURFACES_MPEG4;
+            break;
+        case IMGFMT_VAAPI_CODEC_H264:
+            num_surfaces = NUM_VIDEO_SURFACES_H264;
+            break;
+        case IMGFMT_VAAPI_CODEC_VC1:
+            num_surfaces = NUM_VIDEO_SURFACES_VC1;
+            break;
+        default:
+            num_surfaces = 0;
+            break;
+        }
+        if (num_surfaces == 0)
+            return -1;
+        if (!is_direct_mapping())
+            num_surfaces = FFMIN(2 * num_surfaces, MAX_VIDEO_SURFACES);
+    }
+    for (i = 0; i < num_surfaces; i++) {
+        struct vaapi_surface *surface;
+        surface = alloc_vaapi_surface(width, height, VA_RT_FORMAT_YUV420);
+        if (!surface)
+            return -1;
+    }
+    assert(va_num_surfaces == num_surfaces);
+
+#if CONFIG_VAAPI_GLX
+    /* Create GLX surfaces */
+    if (gl_enabled && !gl_use_tfp) {
+        status = vaCreateSurfaceGLX(va_context->display,
+                                    GL_TEXTURE_2D, gl_texture,
+                                    &gl_surface);
+        if (!check_status(status, "vaCreateSurfaceGLX()"))
+            return -1;
+    }
+#endif
+
+    /* Create OSD data */
+    va_osd_draw_alpha     = NULL;
+    va_osd_image.image_id = VA_INVALID_ID;
+    va_osd_image.buf      = VA_INVALID_ID;
+    va_osd_subpicture     = VA_INVALID_ID;
+    ensure_osd();
+
+    /* Create EOSD data */
+    va_eosd_draw_alpha     = NULL;
+    va_eosd_image.image_id = VA_INVALID_ID;
+    va_eosd_image.buf      = VA_INVALID_ID;
+    va_eosd_subpicture     = VA_INVALID_ID;
+    for (i = 0; va_eosd_info[i].format; i++) {
+        for (j = 0; j < va_num_subpic_formats; j++)
+            if (va_subpic_formats[j].fourcc == va_eosd_info[i].format)
+                break;
+        if (j < va_num_subpic_formats &&
+            vaCreateImage(va_context->display, &va_subpic_formats[j],
+                          width, height, &va_eosd_image) == VA_STATUS_SUCCESS)
+            break;
+    }
+    if (va_eosd_info[i].format &&
+        vaCreateSubpicture(va_context->display, va_eosd_image.image_id,
+                           &va_eosd_subpicture) == VA_STATUS_SUCCESS) {
+        va_eosd_draw_alpha = va_eosd_info[i].draw_alpha;
+        mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] Using %s surface for EOSD\n",
+               string_of_VAImageFormat(&va_eosd_image.format));
+    }
+
+    /* Allocate VA images */
+    if (!IMGFMT_IS_VAAPI(format)) {
+        VAImageFormat *image_format = VAImageFormat_from_imgfmt(format);
+        if (!image_format)
+            return -1;
+        for (i = 0; i < va_num_surfaces; i++) {
+            struct vaapi_surface * const s = va_free_surfaces[i];
+            s->is_bound = 0;
+            status = vaDeriveImage(va_context->display, s->id, &s->image);
+            if (status == VA_STATUS_SUCCESS) {
+                /* vaDeriveImage() is supported, check format */
+                if (s->image.format.fourcc != image_format->fourcc) {
+                    vaDestroyImage(va_context->display, s->image.image_id);
+                    return -1;
+                }
+                if (s->image.width == width && s->image.height == height) {
+                    s->is_bound = 1;
+                    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] Using vaDeriveImage()\n");
+                }
+                else {
+                    vaDestroyImage(va_context->display, s->image.image_id);
+                    status = VA_STATUS_ERROR_OPERATION_FAILED;
+                }
+                
+            }
+            if (status != VA_STATUS_SUCCESS) {
+                status = vaCreateImage(va_context->display, image_format,
+                                       width, height, &s->image);
+                if (!check_status(status, "vaCreateImage()"))
+                    return -1;
+            }
+        }
+        return 0;
+    }
+
+    /* Check profile */
+    profile = VAProfile_from_imgfmt(format);
+    if (profile < 0)
+        return -1;
+
+    /* Check entry-point (only VLD for now) */
+    max_entrypoints = vaMaxNumEntrypoints(va_context->display);
+    va_entrypoints = calloc(max_entrypoints, sizeof(*va_entrypoints));
+    if (!va_entrypoints)
+        return -1;
+
+    status = vaQueryConfigEntrypoints(va_context->display, profile,
+                                      va_entrypoints, &va_num_entrypoints);
+    if (!check_status(status, "vaQueryConfigEntrypoints()"))
+        return -1;
+
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] config_vaapi(%s): %d entrypoints available\n",
+           string_of_VAProfile(profile), va_num_entrypoints);
+    for (i = 0; i < va_num_entrypoints; i++)
+        mp_msg(MSGT_VO, MSGL_DBG2, "  %s\n", string_of_VAEntrypoint(va_entrypoints[i]));
+
+    entrypoint = VAEntrypoint_from_imgfmt(format);
+    if (entrypoint != VAEntrypointVLD)
+        return -1;
+
+    /* Check chroma format (only 4:2:0 for now) */
+    attrib.type = VAConfigAttribRTFormat;
+    status = vaGetConfigAttributes(va_context->display, profile, entrypoint, &attrib, 1);
+    if (!check_status(status, "vaGetConfigAttributes()"))
+        return -1;
+    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
+        return -1;
+
+    /* Create a configuration for the decode pipeline */
+    status = vaCreateConfig(va_context->display, profile, entrypoint, &attrib, 1, &va_context->config_id);
+    if (!check_status(status, "vaCreateConfig()"))
+        return -1;
+
+    /* Create a context for the decode pipeline */
+    status = vaCreateContext(va_context->display, va_context->config_id,
+                             width, height, VA_PROGRESSIVE,
+                             va_surface_ids, va_num_surfaces,
+                             &va_context->context_id);
+    if (!check_status(status, "vaCreateContext()"))
+        return -1;
+    return 0;
+}
+
+static int config(uint32_t width, uint32_t height,
+                  uint32_t display_width, uint32_t display_height,
+                  uint32_t flags, char *title, uint32_t format)
+{
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] config(): size %dx%d, display size %dx%d, flags %x, title '%s', format %x (%s)\n",
+           width, height, display_width, display_height, flags, title, format, vo_format_name(format));
+
+    free_video_specific();
+
+    if (config_x11(width, height, display_width, display_height, flags, title) < 0)
+        return -1;
+
+#if CONFIG_GL
+    if (gl_enabled && config_glx(width, height) < 0)
+        return -1;
+#endif
+
+#if CONFIG_XRENDER
+    if (xr_enabled && config_xrender(width, height) < 0)
+        return -1;
+#endif
+
+    if (config_vaapi(width, height, format) < 0)
+        return -1;
+
+    g_is_visible   = 0;
+    g_is_paused    = 0;
+    g_image_width  = width;
+    g_image_height = height;
+    g_image_format = format;
+    resize();
+    return 0;
+}
+
+static int query_format(uint32_t format)
+{
+    const int default_caps = (VFCAP_CSP_SUPPORTED |
+                              VFCAP_CSP_SUPPORTED_BY_HW |
+                              VFCAP_HWSCALE_UP |
+                              VFCAP_HWSCALE_DOWN |
+                              VFCAP_OSD |
+                              VFCAP_EOSD);
+
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] query_format(): format %x (%s)\n",
+           format, vo_format_name(format));
+
+    switch (format) {
+    case IMGFMT_VAAPI_MPEG2:
+    case IMGFMT_VAAPI_MPEG4:
+    case IMGFMT_VAAPI_H263:
+    case IMGFMT_VAAPI_H264:
+    case IMGFMT_VAAPI_WMV3:
+    case IMGFMT_VAAPI_VC1:
+        return default_caps | VOCAP_NOSLICES;
+    case IMGFMT_NV12:
+    case IMGFMT_YV12:
+    case IMGFMT_I420:
+    case IMGFMT_IYUV:
+        if (VAImageFormat_from_imgfmt(format))
+            return default_caps;
+        break;
+    }
+    return 0;
+}
+
+static inline int get_field_flags(int i)
+{
+    return (g_deint && (g_image_fields & MP_IMGFIELD_INTERLACED) ? 
+            (((!!(g_image_fields & MP_IMGFIELD_TOP_FIRST)) ^ i) == 0 ?
+             VA_BOTTOM_FIELD : VA_TOP_FIELD) : VA_FRAME_PICTURE);
+}
+
+static inline int get_colorspace_flags(void)
+{
+    int csp = 0;
+#if USE_VAAPI_COLORSPACE
+    switch (g_colorspace) {
+    case 0:
+        csp = ((g_image_width >= 1280 || g_image_height > 576) ?
+               VA_SRC_BT709 : VA_SRC_BT601);
+        break;
+    case 1:
+        csp = VA_SRC_BT601;
+        break;
+    case 2:
+        csp = VA_SRC_BT709;
+        break;
+    default:
+        assert(0);
+        break;
+    }
+#endif
+    return csp;
+}
+
+static void put_surface_x11(struct vaapi_surface *surface)
+{
+    VAStatus status;
+    int i;
+
+    for (i = 0; i <= !!(g_deint > 1); i++) {
+        status = vaPutSurface(va_context->display,
+                              surface->id,
+                              vo_window,
+                              0, 0, g_image_width, g_image_height,
+                              g_output_rect.left,
+                              g_output_rect.top,
+                              g_output_rect.width,
+                              g_output_rect.height,
+                              NULL, 0,
+                              get_field_flags(i) | get_colorspace_flags());
+        if (!check_status(status, "vaPutSurface()"))
+            return;
+    }
+}
+
+#if CONFIG_GL
+static void put_surface_glx(struct vaapi_surface *surface)
+{
+    VAStatus status;
+    int i;
+
+    if (gl_use_tfp) {
+        for (i = 0; i <= !!(g_deint > 1); i++) {
+            status = vaPutSurface(va_context->display,
+                                  surface->id,
+                                  g_image_pixmap,
+                                  0, 0, g_image_width, g_image_height,
+                                  0, 0, g_image_width, g_image_height,
+                                  NULL, 0,
+                                  get_field_flags(i) | get_colorspace_flags());
+            if (!check_status(status, "vaPutSurface()"))
+                return;
+        }
+        g_output_surfaces[g_output_surface] = surface;
+        return;
+    }
+
+#if CONFIG_VAAPI_GLX
+    if (gl_binding) {
+#if USE_VAAPI_GLX_BIND
+        for (i = 0; i <= !!(g_deint > 1); i++) {
+            status = vaAssociateSurfaceGLX(va_context->display,
+                                           gl_surface,
+                                           surface->id,
+                                           get_field_flags(i) | get_colorspace_flags());
+            if (!check_status(status, "vaAssociateSurfaceGLX()"))
+                return;
+        }
+#else
+        mp_msg(MSGT_VO, MSGL_WARN, "vaAssociateSurfaceGLX() is not implemented\n");
+        gl_binding = 0;
+#endif
+    }
+
+    if (!gl_binding) {
+        for (i = 0; i <= !!(g_deint > 1); i++) {
+            status = vaCopySurfaceGLX(va_context->display,
+                                      gl_surface,
+                                      surface->id,
+                                      get_field_flags(i) | get_colorspace_flags());
+
+            if (status == VA_STATUS_ERROR_UNIMPLEMENTED) {
+                mp_msg(MSGT_VO, MSGL_WARN,
+                       "[vo_vaapi] vaCopySurfaceGLX() is not implemented\n");
+                gl_binding = 1;
+            }
+            else {
+                if (!check_status(status, "vaCopySurfaceGLX()"))
+                    return;
+            }
+        }
+    }
+#endif
+    g_output_surfaces[g_output_surface] = surface;
+}
+
+static int glx_bind_texture(void)
+{
+    glEnable(GL_TEXTURE_2D);
+    mpglBindTexture(GL_TEXTURE_2D, gl_texture);
+
+    if (gl_use_tfp) {
+        x11_trap_errors();
+        mpglXBindTexImage(mDisplay, gl_pixmap, GLX_FRONT_LEFT_EXT, NULL);
+        XSync(mDisplay, False);
+        if (x11_untrap_errors())
+            mp_msg(MSGT_VO, MSGL_WARN, "[vo_vaapi] Update bind_tex_image failed\n");
+    }
+
+#if USE_VAAPI_GLX_BIND
+    if (gl_binding) {
+        VAStatus status;
+        status = vaBeginRenderSurfaceGLX(va_context->display, gl_surface);
+        if (!check_status(status, "vaBeginRenderSurfaceGLX()"))
+            return -1;
+    }
+#endif
+    return 0;
+}
+
+static int glx_unbind_texture(void)
+{
+    if (gl_use_tfp) {
+        x11_trap_errors();
+        mpglXReleaseTexImage(mDisplay, gl_pixmap, GLX_FRONT_LEFT_EXT);
+        if (x11_untrap_errors())
+            mp_msg(MSGT_VO, MSGL_WARN, "[vo_vaapi] Failed to release?\n");
+    }
+
+#if USE_VAAPI_GLX_BIND
+    if (gl_binding) {
+        VAStatus status;
+        status = vaEndRenderSurfaceGLX(va_context->display, gl_surface);
+        if (!check_status(status, "vaEndRenderSurfaceGLX()"))
+            return -1;
+    }
+#endif
+
+    mpglBindTexture(GL_TEXTURE_2D, 0);
+    glDisable(GL_TEXTURE_2D);
+    return 0;
+}
+
+static void render_background(void)
+{
+    /* Original code from Mirco Muller (MacSlow):
+       <http://cgit.freedesktop.org/~macslow/gl-gst-player/> */
+    GLfloat fStartX = 0.0f;
+    GLfloat fStartY = 0.0f;
+    GLfloat fWidth  = (GLfloat)vo_dwidth;
+    GLfloat fHeight = (GLfloat)vo_dheight;
+
+    glBegin(GL_QUADS);
+    {
+        /* top third, darker grey to white */
+        glColor3f(0.85f, 0.85f, 0.85f);
+        glVertex3f(fStartX, fStartY, 0.0f);
+        glColor3f(0.85f, 0.85f, 0.85f);
+        glVertex3f(fStartX + fWidth, fStartY, 0.0f);
+        glColor3f(1.0f, 1.0f, 1.0f);
+        glVertex3f(fStartX + fWidth, fStartY + fHeight / 3.0f, 0.0f);
+        glColor3f(1.0f, 1.0f, 1.0f);
+        glVertex3f(fStartX, fStartY + fHeight / 3.0f, 0.0f);
+
+        /* middle third, just plain white */
+        glColor3f(1.0f, 1.0f, 1.0f);
+        glVertex3f(fStartX, fStartY + fHeight / 3.0f, 0.0f);
+        glVertex3f(fStartX + fWidth, fStartY + fHeight / 3.0f, 0.0f);
+        glVertex3f(fStartX + fWidth, fStartY + 2.0f * fHeight / 3.0f, 0.0f);
+        glVertex3f(fStartX, fStartY + 2.0f * fHeight / 3.0f, 0.0f);
+
+        /* bottom third, white to lighter grey */
+        glColor3f(1.0f, 1.0f, 1.0f);
+        glVertex3f(fStartX, fStartY + 2.0f * fHeight / 3.0f, 0.0f);
+        glColor3f(1.0f, 1.0f, 1.0f);
+        glVertex3f(fStartX + fWidth, fStartY + 2.0f * fHeight / 3.0f, 0.0f);
+        glColor3f(0.62f, 0.66f, 0.69f);
+        glVertex3f(fStartX + fWidth, fStartY + fHeight, 0.0f);
+        glColor3f(0.62f, 0.66f, 0.69f);
+        glVertex3f(fStartX, fStartY + fHeight, 0.0f);
+    }
+    glEnd();
+}
+
+static void render_frame(void)
+{
+    struct vo_rect * const r = &g_output_rect;
+
+    if (glx_bind_texture() < 0)
+        return;
+    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+    glBegin(GL_QUADS);
+    {
+        glTexCoord2f(0.0f, 0.0f); glVertex2i(r->left, r->top);
+        glTexCoord2f(0.0f, 1.0f); glVertex2i(r->left, r->bottom);
+        glTexCoord2f(1.0f, 1.0f); glVertex2i(r->right, r->bottom);
+        glTexCoord2f(1.0f, 0.0f); glVertex2i(r->right, r->top);
+    }
+    glEnd();
+    if (glx_unbind_texture() < 0)
+        return;
+}
+
+static void render_reflection(void)
+{
+    struct vo_rect * const r = &g_output_rect;
+    const unsigned int rh  = g_output_rect.height / 5;
+    GLfloat ry = 1.0f - (GLfloat)rh / (GLfloat)r->height;
+
+    if (glx_bind_texture() < 0)
+        return;
+    glBegin(GL_QUADS);
+    {
+        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+        glTexCoord2f(0.0f, 1.0f); glVertex2i(r->left, r->top);
+        glTexCoord2f(1.0f, 1.0f); glVertex2i(r->right, r->top);
+
+        glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
+        glTexCoord2f(1.0f, ry); glVertex2i(r->right, r->top + rh);
+        glTexCoord2f(0.0f, ry); glVertex2i(r->left, r->top + rh);
+    }
+    glEnd();
+    if (glx_unbind_texture() < 0)
+        return;
+}
+
+static void flip_page_glx(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    if (gl_reflect) {
+        render_background();
+
+        glPushMatrix();
+        glRotatef(20.0f, 0.0f, 1.0f, 0.0f);
+        glTranslatef(50.0f, 0.0f, 0.0f);
+    }
+
+    render_frame();
+
+    if (gl_reflect) {
+        glPushMatrix();
+        glTranslatef(0.0, (GLfloat)g_output_rect.height + 5.0f, 0.0f);
+        render_reflection();
+        glPopMatrix();
+        glPopMatrix();
+    }
+
+    if (cpu_stats) {
+        gl_draw_rectangle(0, 0, vo_dwidth, 32, 0x000000ff);
+        glColor3f(1.0f, 1.0f, 1.0f);
+        glRasterPos2i(16, 20);
+        gl_printf("MPlayer: %.1f%% of CPU @ %u MHz", cpu_usage, cpu_frequency);
+    }
+
+    if (gl_finish)
+        mpglFinish();
+    gl_context.swapGlBuffers(&gl_context);
+
+    if (vo_fs) /* avoid flickering borders in fullscreen mode */
+        glClear(GL_COLOR_BUFFER_BIT);
+}
+#endif
+
+#if CONFIG_XRENDER
+static void put_surface_xrender(struct vaapi_surface *surface)
+{
+    VAStatus status;
+    int i;
+
+    for (i = 0; i <= !!(g_deint > 1); i++) {
+        status = vaPutSurface(va_context->display,
+                              surface->id,
+                              g_image_pixmap,
+                              0, 0, g_image_width, g_image_height,
+                              0, 0, g_output_rect.width, g_output_rect.height,
+                              NULL, 0,
+                              get_field_flags(i) | get_colorspace_flags());
+        if (!check_status(status, "vaPutSurface()"))
+            return;
+        XRenderComposite(mDisplay,
+                         PictOpSrc, xr_video_picture, 0, xr_window_picture,
+                         0, 0,
+                         0, 0,
+                         g_output_rect.left, g_output_rect.top,
+                         g_output_rect.width, g_output_rect.height);
+    }
+}
+#endif
+
+static void put_surface(struct vaapi_surface *surface)
+{
+    if (!surface || surface->id == VA_INVALID_SURFACE)
+        return;
+
+#if CONFIG_GL
+    if (gl_enabled)
+        put_surface_glx(surface);
+    else
+#endif
+#if CONFIG_XRENDER
+    if (xr_enabled)
+        put_surface_xrender(surface);
+    else
+#endif
+        put_surface_x11(surface);
+}
+
+static int draw_slice(uint8_t * image[], int stride[],
+                      int w, int h, int x, int y)
+{
+    struct vaapi_surface * const surface = va_free_surfaces[g_output_surface];
+    VAImage * const va_image = &surface->image;
+    VAStatus status;
+    uint8_t *image_data = NULL;
+    uint8_t *dst[3] = { 0, };
+    unsigned int dst_stride[3];
+
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] draw_slice(): location (%d,%d), size %dx%d\n", x, y, w, h);
+
+    status = vaMapBuffer(va_context->display, va_image->buf,
+                         (void *)&image_data);
+    if (!check_status(status, "vaMapBuffer()"))
+        return VO_FALSE;
+
+    dst_stride[0] = va_image->pitches[0];
+    dst[0] = image_data + va_image->offsets[0] + y * dst_stride[0] + x;
+
+    memcpy_pic(dst[0], image[0], w, h, dst_stride[0], stride[0]);
+
+    x /= 2;
+    y /= 2;
+    w /= 2;
+    h /= 2;
+
+    if (g_image_format == IMGFMT_YV12) {
+        /* MPlayer's YV12 is actually I420, so swap U/V components */
+        dst_stride[1] = va_image->pitches[2];
+        dst[1] = image_data + va_image->offsets[2] + y * dst_stride[1] + x;
+        dst_stride[2] = va_image->pitches[1];
+        dst[2] = image_data + va_image->offsets[1] + y * dst_stride[2] + x;
+    }
+    else {
+        if (image[1]) {
+            dst_stride[1] = va_image->pitches[1];
+            dst[1] = image_data + va_image->offsets[1] + y * dst_stride[1] + x;
+        }
+        if (image[2]) {
+            dst_stride[2] = va_image->pitches[2];
+            dst[2] = image_data + va_image->offsets[2] + y * dst_stride[2] + x;
+        }
+    }
+
+    if (image[1]) /* RGBA only has a single plane */
+        memcpy_pic(dst[1], image[1], w, h, dst_stride[1], stride[1]);
+
+    if (image[2]) /* NV12 only has two planes */
+        memcpy_pic(dst[2], image[2], w, h, dst_stride[2], stride[2]);
+
+    status = vaUnmapBuffer(va_context->display, surface->image.buf);
+    if (!check_status(status, "vaUnmapBuffer()"))
+        return VO_FALSE;
+
+    return VO_TRUE;
+}
+
+static int draw_frame(uint8_t * src[])
+{
+    mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_X11_DrawFrameCalled);
+
+    return -1;
+}
+
+static void draw_osd(void)
+{
+    VAStatus status;
+    const int osd_width  = va_osd_image.width;
+    const int osd_height = va_osd_image.height;
+
+    ensure_osd();
+    if (va_osd_image.image_id == VA_INVALID_ID)
+        return;
+
+    if (!va_osd_draw_alpha)
+        return;
+
+    if (!vo_update_osd(osd_width, osd_height))
+        return;
+ 
+    if (!vo_osd_check_range_update(0, 0, osd_width, osd_height)) {
+        disable_osd();
+        return;
+    }
+
+    status = vaMapBuffer(va_context->display, va_osd_image.buf,
+                         (void *)&va_osd_image_data);
+    if (!check_status(status, "vaMapBuffer()"))
+        return;
+
+    memset(va_osd_image_data, 0, va_osd_image.data_size);
+
+    vo_draw_text(osd_width, osd_height, va_osd_draw_alpha);
+
+    status = vaUnmapBuffer(va_context->display, va_osd_image.buf);
+    if (!check_status(status, "vaUnmapBuffer()"))
+        return;
+    va_osd_image_data = NULL;
+
+    enable_osd();
+}
+
+static void draw_eosd(mp_eosd_images_t *imgs)
+{
+    ass_image_t *img = imgs->imgs;
+    ass_image_t *i;
+    VAStatus status;
+
+    if (!va_eosd_draw_alpha)
+        return;
+
+    // Nothing changed, no need to redraw
+    if (imgs->changed == 0)
+        return;
+
+    // There's nothing to render!
+    if (!img) {
+        disable_eosd();
+        return;
+    }
+
+    if (imgs->changed == 1)
+        goto eosd_skip_upload;
+
+    status = vaMapBuffer(va_context->display, va_eosd_image.buf,
+                         (void *)&va_eosd_image_data);
+    if (!check_status(status, "vaMapBuffer()"))
+        return;
+
+    memset(va_eosd_image_data, 0, va_eosd_image.data_size);
+
+    for (i = img; i; i = i->next)
+        va_eosd_draw_alpha(i->bitmap, i->w, i->h, i->stride,
+                           i->dst_x, i->dst_y, i->color);
+
+    status = vaUnmapBuffer(va_context->display, va_eosd_image.buf);
+    if (!check_status(status, "vaUnmapBuffer()"))
+        return;
+    va_eosd_image_data = NULL;
+
+eosd_skip_upload:
+    enable_eosd();
+}
+
+static void flip_page(void)
+{
+    struct vaapi_surface *surface;
+
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] flip_page()\n");
+
+    surface = g_output_surfaces[g_output_surface];
+    if (!surface)
+        return;
+
+    put_surface(surface);
+    g_output_surface = (g_output_surface + 1) % MAX_OUTPUT_SURFACES;
+    g_is_visible     = 1;
+
+#if CONFIG_GL
+    if (gl_enabled)
+        flip_page_glx();
+#endif
+}
+
+static struct vaapi_surface *get_surface(mp_image_t *mpi)
+{
+    struct vaapi_surface *surface;
+
+    if (mpi->type == MP_IMGTYPE_NUMBERED && is_direct_mapping()) {
+        assert(mpi->number < va_num_surfaces);
+        surface = va_free_surfaces[mpi->number];
+        return surface;
+    }
+
+    /* Push current surface to a free slot */
+    if (mpi->priv) {
+        assert(!va_free_surfaces[va_free_surfaces_tail_index]);
+        va_free_surfaces[va_free_surfaces_tail_index] = mpi->priv;
+        va_free_surfaces_tail_index = (va_free_surfaces_tail_index + 1) % va_num_surfaces;
+    }
+
+    /* Pop the least recently used free surface */
+    assert(va_free_surfaces[va_free_surfaces_head_index]);
+    surface = va_free_surfaces[va_free_surfaces_head_index];
+    va_free_surfaces[va_free_surfaces_head_index] = NULL;
+    va_free_surfaces_head_index = (va_free_surfaces_head_index + 1) % va_num_surfaces;
+    return surface;
+}
+
+static uint32_t get_image(mp_image_t *mpi)
+{
+    struct vaapi_surface *surface;
+
+    if (mpi->type != MP_IMGTYPE_NUMBERED)
+        return VO_FALSE;
+
+    if (!IMGFMT_IS_VAAPI(g_image_format))
+        return VO_FALSE;
+
+    surface = get_surface(mpi);
+    if (!surface)
+        return VO_FALSE;
+
+    mpi->flags |= MP_IMGFLAG_DIRECT;
+    mpi->stride[0] = mpi->stride[1] = mpi->stride[2] = mpi->stride[3] = 0;
+    mpi->planes[0] = mpi->planes[1] = mpi->planes[2] = mpi->planes[3] = NULL;
+    mpi->planes[0] = (char *)surface;
+    mpi->planes[3] = (char *)(uintptr_t)surface->id;
+    mpi->num_planes = 1;
+    mpi->priv = surface;
+
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] get_image(): surface 0x%08x\n", surface->id);
+
+    return VO_TRUE;
+}
+
+static int put_image(mp_image_t *mpi, struct vaapi_surface *surface)
+{
+    VAStatus status;
+ 
+    if ((mpi->flags & (MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV)) != (MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV))
+        return VO_FALSE;
+
+    if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) {
+        if (!draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0))
+            return VO_FALSE;
+    }
+
+    if (!surface->is_bound) {
+        status = vaPutImage2(va_context->display,
+                             surface->id,
+                             surface->image.image_id,
+                             mpi->x, mpi->y, mpi->w, mpi->h,
+                             mpi->x, mpi->y, mpi->w, mpi->h);
+        if (!check_status(status, "vaPutImage()"))
+            return VO_FALSE;
+    }
+
+    return VO_TRUE;
+}
+
+static uint32_t draw_image(mp_image_t *mpi)
+{
+    struct vaapi_surface *surface = (struct vaapi_surface *)mpi->priv;
+
+    g_image_fields = mpi->fields;
+
+    if (!IMGFMT_IS_VAAPI(mpi->imgfmt)) {
+        /* XXX: no direct rendering in non-accelerated mode */
+        surface = va_free_surfaces[g_output_surface];
+        if (!put_image(mpi, surface))
+            return VO_FALSE;
+    }
+
+    mp_msg(MSGT_VO, MSGL_DBG2, "[vo_vaapi] draw_image(): surface 0x%08x\n", surface->id);
+
+    g_output_surfaces[g_output_surface] = surface;
+
+    if (cpu_stats) {
+        static uint64_t ticks;
+        if ((ticks++ % 30) == 0) {
+            cpu_frequency = get_cpu_frequency();
+            cpu_usage = get_cpu_usage(CPU_USAGE_QUANTUM);
+        }
+    }
+    return VO_TRUE;
+}
+
+static void check_events(void)
+{
+    int events = vo_x11_check_events(mDisplay);
+
+    if (events & VO_EVENT_RESIZE)
+        resize();
+
+    if ((events & (VO_EVENT_EXPOSE|VO_EVENT_RESIZE)) && g_is_paused) {
+        /* Redraw the last visible buffer  */
+        if (g_is_visible) {
+            struct vaapi_surface *surface = g_output_surfaces[g_output_surface];
+            if (surface)
+                put_surface(surface);
+        }
+    }
+}
+
+static VADisplayAttribute *get_display_attribute(const char *name)
+{
+    VADisplayAttribute *attr;
+    if (!strcasecmp(name, "brightness"))
+        attr = &va_equalizer.brightness;
+    else if (!strcasecmp(name, "contrast"))
+        attr = &va_equalizer.contrast;
+    else if (!strcasecmp(name, "saturation"))
+        attr = &va_equalizer.saturation;
+    else if (!strcasecmp(name, "hue"))
+        attr = &va_equalizer.hue;
+    else
+        attr = NULL;
+    return attr;
+}
+
+static int get_equalizer(const char *name, int *value)
+{
+    VADisplayAttribute * const attr = get_display_attribute(name);
+    int r;
+
+    if (!attr || !(attr->flags & VA_DISPLAY_ATTRIB_GETTABLE))
+        return VO_NOTIMPL;
+
+    /* normalize to -100 .. 100 range */
+    r = attr->max_value - attr->min_value;
+    if (r == 0)
+        return VO_NOTIMPL;
+    *value = ((attr->value - attr->min_value) * 200) / r - 100;
+    return VO_TRUE;
+}
+
+static int set_equalizer(const char *name, int value)
+{
+    VADisplayAttribute * const attr = get_display_attribute(name);
+    VAStatus status;
+    int r;
+
+    if (!attr || !(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE))
+        return VO_NOTIMPL;
+
+    /* normalize to attribute value range */
+    r = attr->max_value - attr->min_value;
+    if (r == 0)
+        return VO_NOTIMPL;
+    attr->value = ((value + 100) * r) / 200 + attr->min_value;
+
+    status = vaSetDisplayAttributes(va_context->display, attr, 1);
+    if (!check_status(status, "vaSetDisplayAttributes()"))
+        return VO_FALSE;
+    return VO_TRUE;
+}
+
+static int control(uint32_t request, void *data, ...)
+{
+    switch (request) {
+    case VOCTRL_GET_DEINTERLACE:
+        *(int*)data = g_deint;
+        return VO_TRUE;
+    case VOCTRL_SET_DEINTERLACE:
+        g_deint = *(int*)data;
+        if (g_deint)
+            g_deint = g_deint_type;
+        return VO_TRUE;
+    case VOCTRL_PAUSE:
+        return (g_is_paused = 1);
+    case VOCTRL_RESUME:
+        return (g_is_paused = 0);
+    case VOCTRL_QUERY_FORMAT:
+        return query_format(*((uint32_t *)data));
+    case VOCTRL_GET_IMAGE:
+        return get_image(data);
+    case VOCTRL_DRAW_IMAGE:
+        return draw_image(data);
+    case VOCTRL_GUISUPPORT:
+        return VO_TRUE;
+    case VOCTRL_BORDER:
+        vo_x11_border();
+        resize();
+        return VO_TRUE;
+    case VOCTRL_FULLSCREEN:
+        vo_x11_fullscreen();
+        resize();
+        return VO_TRUE;
+    case VOCTRL_SET_EQUALIZER: {
+        va_list ap;
+        int value;
+
+        va_start(ap, data);
+        value = va_arg(ap, int);
+
+        va_end(ap);
+        return set_equalizer(data, value);
+    }
+    case VOCTRL_GET_EQUALIZER: {
+        va_list ap;
+        int *value;
+
+        va_start(ap, data);
+        value = va_arg(ap, int *);
+
+        va_end(ap);
+        return get_equalizer(data, value);
+    }
+    case VOCTRL_ONTOP:
+        vo_x11_ontop();
+        return VO_TRUE;
+    case VOCTRL_UPDATE_SCREENINFO:
+        update_xinerama_info();
+        return VO_TRUE;
+    case VOCTRL_GET_PANSCAN:
+        return VO_TRUE;
+    case VOCTRL_SET_PANSCAN:
+        resize();
+        return VO_TRUE;
+    case VOCTRL_GET_HWACCEL_CONTEXT:
+        *((void **)data) = va_context;
+        return VO_TRUE;
+    case VOCTRL_DRAW_EOSD:
+        if (!data)
+            return VO_FALSE;
+        draw_eosd(data);
+        return VO_TRUE;
+    case VOCTRL_GET_EOSD_RES: {
+        mp_eosd_res_t *r = data;
+        r->mt = r->mb = r->ml = r->mr = 0;
+        r->srcw = g_image_width;
+        r->srch = g_image_height;
+        r->w    = g_image_width;
+        r->h    = g_image_height;
+        return VO_TRUE;
+    }
+    }
+    return VO_NOTIMPL;
+}
