diff -Naur xine-lib-1.1.19.orig/src/combined/ffmpeg/ff_video_decoder.c xine-lib-1.1.19/src/combined/ffmpeg/ff_video_decoder.c
--- xine-lib-1.1.19.orig/src/combined/ffmpeg/ff_video_decoder.c	2010-03-10 20:07:15.000000000 +0100
+++ xine-lib-1.1.19/src/combined/ffmpeg/ff_video_decoder.c	2010-10-14 14:46:37.000000000 +0200
@@ -51,6 +51,21 @@
 #  include <libpostproc/postprocess.h>
 #endif
 
+#include <va/va_x11.h>
+#include <libavcodec/vaapi.h>
+//#include <X11/Xutil.h>
+
+typedef struct ff_va_surfaces_s ff_va_surfaces_t;
+
+struct ff_va_surfaces_s
+{
+  int count;
+  VASurfaceID **free;
+  VASurfaceID **used;
+};
+
+#define NUM_SURFACES 21
+
 #define VIDEOBUFSIZE        (128*1024)
 #define SLICE_BUFFER_SIZE   (1194*1024)
 
@@ -73,6 +88,7 @@
   int                     thread_count;
   int8_t                  skip_loop_filter_enum;
   int8_t                  choose_speed_over_accuracy;
+  int                     enable_vaapi;
 
   xine_t                 *xine;
 } ff_video_class_t;
@@ -111,6 +127,7 @@
   int               slice_offset_size;
 
   AVFrame          *av_frame;
+  //AVPacket         av_pkt;
   AVCodecContext   *context;
   AVCodec          *codec;
 
@@ -138,8 +155,31 @@
 #ifdef LOG
   enum PixelFormat  debug_fmt;
 #endif
+
+};
+
+typedef struct ff_vaapi_context_s ff_vaapi_context_t;
+
+struct ff_vaapi_context_s {
+  VAImage           va_image;
+  Display           *display;
+  VADisplay         *va_display;
+  VAImageFormat     *va_ifmts;
+  uint8_t           *va_image_data;
+  VAContextID       va_context_id;
+  VAConfigID        va_config_id;
+  VASurfaceID       *va_surface_id;
+  struct ff_va_surfaces_s va_surfaces;
+  int               width;
+  int               height;
+  int               va_profile;
+  struct vaapi_context *vaapi_context;
+  int               use_vaapi;
 };
 
+static struct ff_vaapi_context_s *va_context;
+
+static VAStatus init_vaapi(struct ff_vaapi_context_s *va_context, int va_profile, int width, int height);
 
 static void set_stream_info(ff_video_decoder_t *this) {
   _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH,  this->bih.biWidth);
@@ -148,6 +188,63 @@
 }
 
 #ifdef ENABLE_DIRECT_RENDERING
+
+static void draw_slice(struct AVCodecContext *context, const AVFrame *src, int offset[4], int y, int type, int height) {
+  uint8_t *source[4]= {src->data[0] + offset[0], src->data[1] + offset[1], src->data[2] + offset[2], src->data[3] + offset[3]};
+  int strides[4] = {src->linesize[0], src->linesize[1], src->linesize[2]};
+
+  if (height < 0) {
+    int i;
+    height = -height;
+    y -= height;
+    for (i = 0; i < 4; i++) {
+      strides[i] = -strides[i];
+      source[i] -= strides[i];
+    }
+  }
+}
+
+static VAProfile* find_profile(VAProfile* p, int np, int codec)
+{
+  int i;
+  
+  for(i = 0; i < np; i++)
+  {
+    if(p[i] == codec)
+      return &p[i];
+  }
+
+  return NULL;
+}
+
+int get_profile(int codec_id) {
+  int profile;
+
+  switch (codec_id) {
+    case CODEC_ID_MPEG2VIDEO:
+      profile = VAProfileMPEG2Main;
+      break;
+    case CODEC_ID_MPEG4:
+    case CODEC_ID_H263:
+      profile = VAProfileMPEG4AdvancedSimple;
+      break;
+    case CODEC_ID_H264:
+      profile = VAProfileH264High;
+      break;
+    case CODEC_ID_WMV3:
+      profile = VAProfileVC1Main;
+      break;
+    case CODEC_ID_VC1:
+      profile = VAProfileVC1Advanced;
+      break;
+    default:
+      profile = -1;
+      break;
+  }
+
+  return profile;
+}
+
 /* called from ffmpeg to do direct rendering method 1 */
 static int get_buffer(AVCodecContext *context, AVFrame *av_frame){
   ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque;
@@ -169,6 +266,43 @@
 
   avcodec_align_dimensions(context, &width, &height);
 
+  if( va_context->use_vaapi ) {
+    int i = 0;
+    struct ff_va_surfaces_s *va_surfaces = &va_context->va_surfaces;
+
+    for(i = 0; i < va_surfaces->count; i++)
+    {
+      //printf("srfc #%d %p\n",i,va_srfcs->srfc_free[i]);
+      if(va_surfaces->free[i])
+      {
+        va_surfaces->used[i] = va_surfaces->free[i];
+        va_surfaces->free[i] = NULL;
+        break;
+      }
+    }
+    if(i == va_surfaces->count)
+    {
+      printf("ERROR get surface\n");
+      return -1;
+    }
+  
+  
+    av_frame->type = FF_BUFFER_TYPE_USER;
+    av_frame->age = 256*256*256*64; // FIXME FIXME from ffmpeg
+    av_frame->data[0] = (void*)va_surfaces->used[i];
+    av_frame->data[1] = NULL;
+    av_frame->data[2] = NULL;
+    av_frame->data[3] = (void*)(size_t)*va_surfaces->used[i];
+    av_frame->linesize[0] = 0;
+    av_frame->linesize[1] = 0;
+    av_frame->linesize[2] = 0;
+    av_frame->linesize[3] = 0;
+
+    this->is_direct_rendering_disabled = 1;
+  
+    return 0;
+  }
+
   if( this->context->pix_fmt != PIX_FMT_YUV420P && this->context->pix_fmt != PIX_FMT_YUVJ420P ) {
     if (!this->is_direct_rendering_disabled) {
       xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
@@ -238,10 +372,33 @@
 static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){
   ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque;
 
+  if( va_context->use_vaapi ) {
+    struct ff_va_surfaces_s *va_surfaces = &va_context->va_surfaces;
+    VASurfaceID va_surface_id = (VASurfaceID)(size_t)av_frame->data[3];
+    int i = 0;
+
+    for(i = 0; i < va_surfaces->count; i++)
+    {
+      //printf("srfc #%d %p 0x%08X\n",i,va_srfcs->srfc_used[i], va_srfcs->srfc_used[i] ? *va_srfcs->srfc_used[i] : -1);
+      if(va_surfaces->used[i] && (*va_surfaces->used[i] == va_surface_id))
+      {
+        va_surfaces->free[i] = va_surfaces->used[i];
+        va_surfaces->used[i] = NULL;
+        break;
+      }
+    }
+
+    av_frame->data[0] = NULL;
+    av_frame->data[1] = NULL;
+    av_frame->data[2] = NULL;
+    av_frame->data[3] = NULL;
+    return;
+  }
+
   if (av_frame->type == FF_BUFFER_TYPE_USER) {
     if ( av_frame->opaque ) {
-      vo_frame_t *img = (vo_frame_t *)av_frame->opaque;
-
+        vo_frame_t *img = (vo_frame_t *)av_frame->opaque;
+  
       img->free(img);
     }
 
@@ -283,13 +440,269 @@
   AVDISCARD_ALL
 };
 
+static const char *VAProfile2string(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
+    default: break;
+  }
+  return "<unknown>";
+}
+
+static const char *VAEntrypoint2string(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
+    default: break;
+  }
+  return "<unknown>";
+}
+
+static enum PixelFormat get_format(struct AVCodecContext *context, const enum PixelFormat *fmt)
+{
+    int i, profile;
+
+    for (i = 0; fmt[i] != PIX_FMT_NONE; i++) {
+        if (fmt[i] != PIX_FMT_VAAPI_VLD)
+            continue;
+
+        profile = get_profile(context->codec_id);
+
+        if (profile >= 0) {
+          VAStatus status;
+
+          status = init_vaapi(va_context, profile, context->width, context->height);
+
+          if( status == VA_STATUS_SUCCESS ) {
+
+            //context->draw_horiz_band = draw_slice;
+            context->draw_horiz_band = NULL;
+            context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
+            context->dsp_mask = FF_MM_FORCE | FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE;
+
+            va_context->vaapi_context->config_id   = va_context->va_config_id;
+            va_context->vaapi_context->context_id  = va_context->va_context_id;
+            context->hwaccel_context     = va_context->vaapi_context;
+            printf("init vaapi successfully\n");
+            va_context->use_vaapi = 1;
+            return fmt[i];
+          } else {
+            va_context->use_vaapi = 0;
+            printf("vaapi init error\n");
+          }
+        } else {
+          va_context->use_vaapi = 0;
+        }
+    }
+    return PIX_FMT_NONE;
+}
+
+static void close_vaapi(ff_vaapi_context_t *va_context) {
+  if(va_context->va_context_id) { 
+    if(va_context->va_image.image_id != VA_INVALID_ID ) { 
+      vaDestroyImage(va_context->va_display, va_context->va_image.image_id );
+    }
+    if(va_context->va_context_id != VA_INVALID_ID) {
+      vaDestroyContext(va_context->va_display, va_context->va_context_id);
+    }
+
+    int i = 0;
+    for( i = 0; i < va_context->va_surfaces.count; i++ ) {
+      if( va_context->va_surface_id[i] != VA_INVALID_SURFACE) {
+        vaDestroySurfaces(va_context->va_display, &va_context->va_surface_id[i], 1);
+      }
+    }
+
+    if(va_context->va_config_id)
+      vaDestroyConfig(va_context->va_display, va_context->va_config_id);
+
+    vaTerminate(va_context->va_display);
+    XCloseDisplay(va_context->display);
+
+    free(va_context->va_surfaces.free);
+    free(va_context->va_surfaces.used);
+    free(va_context->va_surface_id);
+    free(va_context->vaapi_context);
+    free(va_context);
+
+    va_context = NULL;
+  }
+}
+
+static VAStatus create_vaapi_image(struct ff_vaapi_context_s *va_context) {
+  int i;
+  int fmt_count = vaMaxNumImageFormats( va_context->va_display );
+  VAImageFormat *va_p_fmt = calloc( fmt_count, sizeof(*va_p_fmt) );
+  VAImageFormat va_fmt;
+
+  if( vaQueryImageFormats( va_context->va_display , va_p_fmt, &fmt_count ) ) {
+    free(va_p_fmt);
+    goto error;
+  }
+
+  for( i = 0; i < fmt_count; i++ ) {
+    if ( va_p_fmt[i].fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) ||
+         va_p_fmt[i].fourcc == VA_FOURCC( 'I', '4', '2', '0' ) ||
+         va_p_fmt[i].fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) ) {
+         
+      if( vaCreateImage( va_context->va_display, &va_p_fmt[i], va_context->width, va_context->height, &va_context->va_image) ) {
+          va_context->va_image.image_id = VA_INVALID_ID;
+          continue;
+       }
+       if( vaGetImage(va_context->va_display, va_context->va_surface_id[0], 0, 0, 
+                      va_context->width, va_context->height, va_context->va_image.image_id) ) {
+         vaDestroyImage( va_context->va_display, va_context->va_image.image_id );
+         va_context->va_image.image_id = VA_INVALID_ID;
+         continue;
+       }
+       printf("found valid image format\n");
+       va_fmt = va_p_fmt[i];
+       break;
+    }
+  }
+  free(va_p_fmt);
+
+  if(va_context->va_image.image_id == VA_INVALID_ID)
+    goto error;
+
+  return VA_STATUS_SUCCESS;
+
+error:
+  return VA_STATUS_ERROR_UNKNOWN;
+}
+
+static VAStatus init_vaapi(struct ff_vaapi_context_s *va_context, int va_profile, int width, int height) {
+  size_t              i;
+  VAStatus            status = VA_STATUS_ERROR_UNKNOWN;
+  int                 surface_count   = NUM_SURFACES;
+  VAConfigAttrib      va_attrib;
+  int                 maj, min;
+  VAProfile           *va_profiles = NULL;
+  VAProfile           *va_profile_search = NULL;
+  int                 number_profiles;
+
+  va_context->width = width;
+  va_context->height = height;
+  va_context->va_profile = va_profile;
+
+  va_context->va_surfaces.free = NULL;
+  va_context->va_surfaces.used = NULL;
+
+  va_context->va_display = NULL;
+  va_context->va_config_id = VA_INVALID_ID;
+  va_context->va_context_id = VA_INVALID_ID;
+  va_context->va_image.image_id = VA_INVALID_ID;
+
+  va_context->display = XOpenDisplay(NULL);
+  if(!va_context->display)
+    goto error;
+
+  va_context->va_display = vaGetDisplay(va_context->display);
+  va_context->vaapi_context->display = va_context->va_display;
+
+  if(!va_context->va_display)
+    goto error;
+
+  if(vaInitialize(va_context->va_display, &maj, &min))
+    goto error;
+
+  printf("libva: %d.%d\n", maj, min);
+
+  printf("AvCodecContext w %d h %d\n", va_context->width, va_context->height);
+
+  memset( &va_attrib, 0, sizeof(va_attrib) );
+  va_attrib.type = VAConfigAttribRTFormat;
+
+  va_profiles = malloc(vaMaxNumProfiles(va_context->va_display) * sizeof(VAProfile));
+
+  if(vaQueryConfigProfiles(va_context->va_display, va_profiles, &number_profiles)) {
+    free(va_profiles);
+    goto error;
+  }
+
+  free(va_profiles);
+
+
+  va_profile_search = find_profile(va_profiles, number_profiles, va_profile);
+
+  if(!va_profile_search)
+    goto error;
+
+  printf("Profile: %d (%s) Entrypoint %d (%s)\n", va_context->va_profile, VAProfile2string(va_context->va_profile), VAEntrypointVLD, VAEntrypoint2string(VAEntrypointVLD));
+
+  if( vaGetConfigAttributes(va_context->va_display, va_context->va_profile, VAEntrypointVLD, &va_attrib, 1) )
+    goto error;
+  
+  if( (va_attrib.value & VA_RT_FORMAT_YUV420) == 0 )
+    goto error;
+
+  if( vaCreateConfig(va_context->va_display, va_context->va_profile, VAEntrypointVLD, &va_attrib, 1, &va_context->va_config_id) ) {
+    va_context->va_config_id = VA_INVALID_ID;
+    goto error;
+  }
+
+  if(va_context->va_surface_id == NULL) {
+    va_context->va_surface_id = malloc(sizeof(VASurfaceID) * surface_count);
+    va_context->va_surfaces.free = malloc(sizeof(VASurfaceID*) * surface_count);
+    va_context->va_surfaces.used = malloc(sizeof(VASurfaceID*) * surface_count);
+  }
+
+  if( vaCreateSurfaces(va_context->va_display, va_context->width, va_context->height, VA_RT_FORMAT_YUV420, surface_count, va_context->va_surface_id) )
+    goto error;
+
+  for(i = 0; i < surface_count; i++) {
+    va_context->va_surfaces.free[i] = &va_context->va_surface_id[i];
+    va_context->va_surfaces.used[i] = NULL;
+  }
+
+  va_context->va_surfaces.count = surface_count;
+
+  if(vaCreateContext(va_context->va_display, va_context->va_config_id, va_context->width, va_context->height,
+                     VA_PROGRESSIVE, va_context->va_surface_id, surface_count, &va_context->va_context_id) ) {
+    va_context->va_context_id = VA_INVALID_ID;
+    goto error;
+  }
+
+  status = create_vaapi_image(va_context);
+  if(status != VA_STATUS_SUCCESS)
+    goto error;
+
+  va_context->use_vaapi = 1;
+  return VA_STATUS_SUCCESS;
+
+error:
+  va_context->use_vaapi = 0;
+  return VA_STATUS_ERROR_UNKNOWN;
+}
+
 static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) {
   size_t i;
 
   /* find the decoder */
   this->codec = NULL;
 
-  for(i = 0; i < sizeof(ff_video_lookup)/sizeof(ff_codec_t); i++)
+  for(i = 0; i < sizeof(ff_video_lookup)/sizeof(ff_codec_t); i++) {
     if(ff_video_lookup[i].type == codec_type) {
       pthread_mutex_lock(&ffmpeg_lock);
       this->codec = avcodec_find_decoder(ff_video_lookup[i].id);
@@ -298,6 +711,8 @@
                             ff_video_lookup[i].name);
       break;
     }
+  }
+  
 
   if (!this->codec) {
     xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
@@ -311,9 +726,11 @@
 
   this->context->width = this->bih.biWidth;
   this->context->height = this->bih.biHeight;
+
   this->context->stream_codec_tag = this->context->codec_tag =
     _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC);
 
+  //av_init_packet(&this->av_pkt);
 
   /* Some codecs (eg rv10) copy flags in init so it's necessary to set
    * this flag here in case we are going to use direct rendering */
@@ -323,7 +740,6 @@
 
   if (this->class->choose_speed_over_accuracy)
     this->context->flags2 |= CODEC_FLAG2_FAST;
-
   pthread_mutex_lock(&ffmpeg_lock);
   if (avcodec_open (this->context, this->codec) < 0) {
     pthread_mutex_unlock(&ffmpeg_lock);
@@ -337,7 +753,6 @@
 
   if (this->codec->id == CODEC_ID_VC1 &&
       (!this->bih.biWidth || !this->bih.biHeight)) {
-    /* VC1 codec must be re-opened with correct width and height. */
     avcodec_close(this->context);
 
     if (avcodec_open (this->context, this->codec) < 0) {
@@ -390,6 +805,13 @@
     xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
 	    _("ffmpeg_video_dec: direct rendering enabled\n"));
   }
+  if( this->class->enable_vaapi && !this->is_mpeg12) {
+    this->context->get_buffer = get_buffer;
+    this->context->reget_buffer = get_buffer;
+    this->context->release_buffer = release_buffer;
+    this->context->get_format = get_format;
+    this->context->thread_count = 1;
+  }
 #endif
 
   /* flag for interlaced streams */
@@ -413,7 +835,13 @@
       this->frame_flags |= VO_INTERLACED_FLAG;
       break;
   }
+}
+
+
+static void enable_vaapi(void *user_data, xine_cfg_entry_t *entry) {
+  ff_video_class_t   *class = (ff_video_class_t *) user_data;
 
+  class->enable_vaapi = entry->num_value;
 }
 
 static void choose_speed_over_accuracy_cb(void *user_data, xine_cfg_entry_t *entry) {
@@ -542,6 +970,36 @@
   return 1;
 }
 
+/*
+*/
+
+static int nv12_to_yv12(ff_video_decoder_t *this, uint8_t  *data, int len, vo_frame_t *img) {
+    unsigned int Y_size  = img->width * this->bih.biHeight;
+    unsigned int UV_size = img->width * this->bih.biHeight / 4;
+    unsigned int idx;
+    unsigned char *dst_Y = img->base[0];
+    unsigned char *dst_U = img->base[1];
+    unsigned char *dst_V = img->base[2];
+    unsigned char *src   = data + Y_size;
+
+    // sanity check raw stream
+    if ( (len != (Y_size + (UV_size<<1))) ) {
+        printf("hmblck: Image size inconsistent with data size.\n");
+        return 0;
+    }
+
+    // luma data is easy, just copy it
+    xine_fast_memcpy(dst_Y, data, Y_size);
+
+    // chroma data is interlaced UVUV... so deinterlace it
+    for(idx=0; idx<UV_size; idx++ ) {
+        *(dst_U + idx) = *(src + (idx<<1) + 0); 
+        *(dst_V + idx) = *(src + (idx<<1) + 1);
+    }
+
+    return 1;
+}
+
 static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
   int         y;
   uint8_t    *dy, *du, *dv, *sy, *su, *sv;
@@ -551,6 +1009,49 @@
     printf ("frame format == %08x\n", this->debug_fmt = this->context->pix_fmt);
 #endif
 
+  if(this->context->pix_fmt == PIX_FMT_VAAPI_VLD && va_context->va_image.image_id != VA_INVALID_ID) {
+    void *p_base;
+    const uint32_t fourcc = va_context->va_image.format.fourcc;
+    VAStatus status;
+
+    if( !vaGetImage( va_context->va_display, (VASurfaceID)(size_t)this->av_frame->data[3],
+                            0, 0, img->width, this->bih.biHeight, va_context->va_image.image_id) ) {
+
+      status = vaMapBuffer( va_context->va_display, va_context->va_image.buf, &p_base ) ;
+      if ( status == VA_STATUS_SUCCESS ) {
+        if( fourcc == VA_FOURCC('Y','V','1','2') ||
+          fourcc == VA_FOURCC('I','4','2','0') ) {
+
+            lprintf("VAAPI YV12 image\n");
+
+            yv12_to_yv12(
+            /* Y */
+              (uint8_t*)p_base, img->width,
+              img->base[0], img->pitches[0],
+            /* U */
+              (uint8_t*)p_base + (img->width * img->height * 5/4), img->width/2,
+              img->base[1], img->pitches[1],
+            /* V */
+              (uint8_t*)p_base + (img->width * img->height), img->width/2,
+              img->base[2], img->pitches[2],
+            /* width x height */
+              img->width, img->height);
+
+        }
+        if( fourcc == VA_FOURCC('N','V','1','2') ) {
+
+          lprintf("VAAPI NV12 image\n");
+
+          nv12_to_yv12(this, (uint8_t*)p_base, va_context->va_image.data_size,  img);
+
+        }
+
+        status = vaUnmapBuffer( va_context->va_display, va_context->va_image.buf );
+      }
+    }
+    return;
+  }
+
   dy = img->base[0];
   du = img->base[1];
   dv = img->base[2];
@@ -1022,6 +1523,11 @@
 
   lprintf("handle_mpeg12_buffer\n");
 
+  if (buf->decoder_flags & BUF_FLAG_FRAME_START) {
+    lprintf("BUF_FLAG_FRAME_START\n");
+    this->size = 0;
+  }
+
   while ((size > 0) || (flush == 1)) {
 
     uint8_t *current;
@@ -1307,10 +1813,19 @@
         this->context->hurry_up = (this->skipframes > 0);
 
         lprintf("buffer size: %d\n", this->size);
+
+        //this->av_pkt.size = this->size;
+        //this->av_pkt.data = &chunk_buf[offset];
+        //this->av_pkt.data = this->buf;
+
+        //len = avcodec_decode_video2 (this->context, this->av_frame, &got_picture, &this->av_pkt);
+
         len = avcodec_decode_video (this->context, this->av_frame,
                                     &got_picture, &chunk_buf[offset],
                                     this->size);
 
+        //av_free_packet(&this->av_pkt);
+
 #ifdef AVCODEC_HAS_REORDERED_OPAQUE
         /* reset consumed pts value */
         this->context->reordered_opaque = ff_tag_pts(this, 0);
@@ -1355,47 +1870,48 @@
 
       /* aspect ratio provided by ffmpeg, override previous setting */
       if ((this->aspect_ratio_prio < 2) &&
-	  av_cmp_q(this->context->sample_aspect_ratio, avr00)) {
+        av_cmp_q(this->context->sample_aspect_ratio, avr00)) {
 
         if (!this->bih.biWidth || !this->bih.biHeight) {
           this->bih.biWidth  = this->context->width;
           this->bih.biHeight = this->context->height;
         }
 
-	this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) *
-	  (double)this->bih.biWidth / (double)this->bih.biHeight;
-	this->aspect_ratio_prio = 2;
-	lprintf("ffmpeg aspect ratio: %f\n", this->aspect_ratio);
-	set_stream_info(this);
+	      this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) *
+	                                 (double)this->bih.biWidth / (double)this->bih.biHeight;
+	      this->aspect_ratio_prio = 2;
+	      lprintf("ffmpeg aspect ratio: %f\n", this->aspect_ratio);
+	      set_stream_info(this);
       }
 
       if (got_picture && this->av_frame->data[0]) {
         /* got a picture, draw it */
         got_one_picture = 1;
+
         if(!this->av_frame->opaque) {
-	  /* indirect rendering */
+	        /* indirect rendering */
 
-	  /* initialize the colorspace converter */
-	  if (!this->cs_convert_init) {
-	    if ((this->context->pix_fmt == PIX_FMT_RGB32) ||
-	        (this->context->pix_fmt == PIX_FMT_RGB565) ||
-	        (this->context->pix_fmt == PIX_FMT_RGB555) ||
-	        (this->context->pix_fmt == PIX_FMT_BGR24) ||
-	        (this->context->pix_fmt == PIX_FMT_RGB24) ||
-	        (this->context->pix_fmt == PIX_FMT_PAL8)) {
-	      this->output_format = XINE_IMGFMT_YUY2;
-	      init_yuv_planes(&this->yuv, (this->bih.biWidth + 15) & ~15, this->bih.biHeight);
-	      this->yuv_init = 1;
-	    }
-	    this->cs_convert_init = 1;
-	  }
-
-	  if (this->aspect_ratio_prio == 0) {
-	    this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight;
-	    this->aspect_ratio_prio = 1;
-	    lprintf("default aspect ratio: %f\n", this->aspect_ratio);
-	    set_stream_info(this);
-	  }
+	        /* initialize the colorspace converter */
+	        if (!this->cs_convert_init) {
+	          if ((this->context->pix_fmt == PIX_FMT_RGB32) ||
+	            (this->context->pix_fmt == PIX_FMT_RGB565) ||
+	            (this->context->pix_fmt == PIX_FMT_RGB555) ||
+	            (this->context->pix_fmt == PIX_FMT_BGR24) ||
+	            (this->context->pix_fmt == PIX_FMT_RGB24) ||
+	            (this->context->pix_fmt == PIX_FMT_PAL8)) {
+	              this->output_format = XINE_IMGFMT_YUY2;
+	              init_yuv_planes(&this->yuv, (this->bih.biWidth + 15) & ~15, this->bih.biHeight);
+	              this->yuv_init = 1;
+	          }
+	          this->cs_convert_init = 1;
+	        }
+
+	        if (this->aspect_ratio_prio == 0) {
+	          this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight;
+	          this->aspect_ratio_prio = 1;
+	          lprintf("default aspect ratio: %f\n", this->aspect_ratio);
+	          set_stream_info(this);
+	        }
 
           /* xine-lib expects the framesize to be a multiple of 16x16 (macroblock) */
           img = this->stream->video_out->get_frame (this->stream->video_out,
@@ -1436,7 +1952,7 @@
                         this->av_frame->pict_type);
 
         } else if (!this->av_frame->opaque) {
-	  /* colorspace conversion or copy */
+	        /* colorspace conversion or copy */
           ff_convert_frame(this, img);
         }
 
@@ -1524,6 +2040,15 @@
     _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, (this->reported_video_step = this->video_step));
   }
 
+  int codec_type = buf->type & 0xFFFF0000;
+  if (codec_type == BUF_VIDEO_MPEG) {
+    this->is_mpeg12 = 1;
+    if ( this->mpeg_parser == NULL ) {
+      this->mpeg_parser = calloc(1, sizeof(mpeg_parser_t));
+      mpeg_parser_init(this->mpeg_parser);
+    }
+  }
+
   if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
 
     ff_handle_preview_buffer(this, buf);
@@ -1541,24 +2066,24 @@
       ff_handle_header_buffer(this, buf);
 
       if (buf->decoder_flags & BUF_FLAG_ASPECT) {
-	if (this->aspect_ratio_prio < 3) {
-	  this->aspect_ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2];
-	  this->aspect_ratio_prio = 3;
-	  lprintf("aspect ratio: %f\n", this->aspect_ratio);
-	  set_stream_info(this);
-	}
+      	if (this->aspect_ratio_prio < 3) {
+          this->aspect_ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2];
+          this->aspect_ratio_prio = 3;
+          lprintf("aspect ratio: %f\n", this->aspect_ratio);
+          set_stream_info(this);
+        }
       }
 
     } else {
 
       /* decode */
       if (buf->pts)
-	this->pts = buf->pts;
+      	this->pts = buf->pts;
 
       if (this->is_mpeg12) {
-	ff_handle_mpeg12_buffer(this, buf);
+	      ff_handle_mpeg12_buffer(this, buf);
       } else {
-	ff_handle_buffer(this, buf);
+	      ff_handle_buffer(this, buf);
       }
 
     }
@@ -1637,6 +2162,8 @@
 
   lprintf ("ff_dispose\n");
 
+  close_vaapi(va_context);
+
   if (this->decoder_ok) {
     xine_list_iterator_t it;
     AVFrame *av_frame;
@@ -1728,6 +2255,9 @@
 
   this->dr1_frames        = xine_list_new();
 
+  va_context              = calloc(1, sizeof(ff_vaapi_context_t));
+  va_context->vaapi_context = calloc(1, sizeof(struct vaapi_context));
+
 #ifdef LOG
   this->debug_fmt = -1;
 #endif
@@ -1803,6 +2333,11 @@
       "A change of this setting will take effect with playing the next stream."),
     10, choose_speed_over_accuracy_cb, this);
 
+  this->enable_vaapi = xine->config->register_bool(config, "video.processing.ffmpeg_enable_vaapi", 1,
+    _("Enable usage of VAAPI"),
+    _("Let you enable the usage of VAAPI.\n"),
+    10, enable_vaapi, this);
+
   return this;
 }
 
diff -Naur xine-lib-1.1.19.orig/src/combined/ffmpeg/Makefile.am xine-lib-1.1.19/src/combined/ffmpeg/Makefile.am
--- xine-lib-1.1.19.orig/src/combined/ffmpeg/Makefile.am	2010-03-09 23:17:05.000000000 +0100
+++ xine-lib-1.1.19/src/combined/ffmpeg/Makefile.am	2010-10-14 14:49:01.000000000 +0200
@@ -43,7 +43,7 @@
 
 xineplug_decode_ff_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
 xineplug_decode_ff_la_LDFLAGS = $(xineplug_ldflags) $(IMPURE_TEXT_LDFLAGS)
-xineplug_decode_ff_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm $(ZLIB_LIBS) \
+xineplug_decode_ff_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm -lva-x11 -lva -lX11 $(ZLIB_LIBS) \
 	$(link_ffmpeg) $(PTHREAD_LIBS) $(LTLIBINTL)
 
 xineplug_decode_dvaudio_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
