aboutsummaryrefslogtreecommitdiff
path: root/multimedia
diff options
context:
space:
mode:
authorJuergen Lock <nox@FreeBSD.org>2013-11-23 19:20:55 +0000
committerJuergen Lock <nox@FreeBSD.org>2013-11-23 19:20:55 +0000
commita268657341ecf6cfa8ef072615d421393c41f496 (patch)
tree8ed126684fc5ca301458a6369f1d30d1f419d37e /multimedia
parentdacd35c759ae64348cd18f0579a1f57dbf089c9e (diff)
downloadports-a268657341ecf6cfa8ef072615d421393c41f496.tar.gz
ports-a268657341ecf6cfa8ef072615d421393c41f496.zip
- Fix LIBBLURAY and VAAPI knobs so they actually do something.
- No PORTREVISION bump as these are non-default options. - Remove unused patchfiles.
Notes
Notes: svn path=/head/; revision=334694
Diffstat (limited to 'multimedia')
-rw-r--r--multimedia/libxine/Makefile11
-rw-r--r--multimedia/libxine/files/extrapatch-vdpau-configure.ac11
-rw-r--r--multimedia/libxine/files/extrapatch-vdpau-src-vdr-input_vdr.c12
-rw-r--r--multimedia/libxine/files/extrapatch-vdpau-src-video_out-video_out_vdpau.c91
-rw-r--r--multimedia/libxine/files/ffmpeg-vaapi_xine-lib-1.2.2-defaultoff.diff5997
-rw-r--r--multimedia/libxine/pkg-plist1
6 files changed, 9 insertions, 6114 deletions
diff --git a/multimedia/libxine/Makefile b/multimedia/libxine/Makefile
index 3775e57dc926..88cfcf39a324 100644
--- a/multimedia/libxine/Makefile
+++ b/multimedia/libxine/Makefile
@@ -191,14 +191,18 @@ CONFIGURE_ARGS+= --without-wavpack
.if ${PORT_OPTIONS:MVAAPI}
LIB_DEPENDS+= libva.so:${PORTSDIR}/multimedia/libva
+PLIST_SUB+= VAAPI=""
+CONFIGURE_ARGS+= --enable-vaapi
+.else
+PLIST_SUB+= VAAPI="@comment "
.endif
.if ${PORT_OPTIONS:MLIBBLURAY}
-CONFIGURE_OPTS+= --enable-bluray
+CONFIGURE_ARGS+= --enable-bluray
LIB_DEPENDS+= libbluray.so:${PORTSDIR}/multimedia/libbluray
PLIST_SUB+= LIBBLURAY=""
.else
-CONFIGURE_OPTS+= --disable-bluray
+CONFIGURE_ARGS+= --disable-bluray
PLIST_SUB+= LIBBLURAY="@comment "
.endif
@@ -217,7 +221,8 @@ CONFIGURE_ARGS+= --disable-vidix
post-patch:
.if ${PORT_OPTIONS:MVAAPI}
- #@${PATCH} ${PATCH_DIST_ARGS} <${FILESDIR}/ffmpeg-vaapi_xine-lib-1.2.2-defaultoff.diff
+ @${REINPLACE_CMD} -e 's|-ldl||' \
+ ${WRKSRC}/src/video_out/Makefile.in
.endif
.for f in libtool ltmain.sh
@${REINPLACE_CMD} -e \
diff --git a/multimedia/libxine/files/extrapatch-vdpau-configure.ac b/multimedia/libxine/files/extrapatch-vdpau-configure.ac
deleted file mode 100644
index f4257562d495..000000000000
--- a/multimedia/libxine/files/extrapatch-vdpau-configure.ac
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -2528,7 +2528,7 @@ makeexpand () {
-
- xinelibdir='${libdir}/xine'
- xinedatadir='${datadir}/xine'
--pkgconfigdir='${libdir}/pkgconfig'
-+pkgconfigdir='${prefix}/libdata/pkgconfig'
- AC_SUBST(xinelibdir)
- AC_SUBST(xinedatadir)
- AC_SUBST(pkgconfigdir)
diff --git a/multimedia/libxine/files/extrapatch-vdpau-src-vdr-input_vdr.c b/multimedia/libxine/files/extrapatch-vdpau-src-vdr-input_vdr.c
deleted file mode 100644
index d88d63e7e8f0..000000000000
--- a/multimedia/libxine/files/extrapatch-vdpau-src-vdr-input_vdr.c
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/src/vdr/input_vdr.c
-+++ b/src/vdr/input_vdr.c
-@@ -32,6 +32,9 @@
- #include <errno.h>
- #include <pthread.h>
-
-+#ifdef __FreeBSD__
-+#include <netinet/in.h>
-+#endif
- #include <sys/socket.h>
- #include <resolv.h>
- #include <netdb.h>
diff --git a/multimedia/libxine/files/extrapatch-vdpau-src-video_out-video_out_vdpau.c b/multimedia/libxine/files/extrapatch-vdpau-src-video_out-video_out_vdpau.c
deleted file mode 100644
index c19114e3bbbd..000000000000
--- a/multimedia/libxine/files/extrapatch-vdpau-src-video_out-video_out_vdpau.c
+++ /dev/null
@@ -1,91 +0,0 @@
---- a/src/video_out/video_out_vdpau.c
-+++ b/src/video_out/video_out_vdpau.c
-@@ -53,6 +53,8 @@
-
- #define NUM_FRAMES_BACK 1
-
-+#define LOCKDISPLAY /*define this if you have a buggy libX11/xcb*/
-+
- #define DEINT_BOB 1
- #define DEINT_HALF_TEMPORAL 2
- #define DEINT_HALF_TEMPORAL_SPATIAL 3
-@@ -167,12 +169,30 @@ static void vdpau_reinit( vo_driver_t *t
- static VdpVideoSurfaceCreate *orig_vdp_video_surface_create;
- static VdpVideoSurfaceDestroy *orig_vdp_video_surface_destroy;
-
-+static VdpVideoSurfaceCreate *orig_vdp_output_surface_create;
-+static VdpVideoSurfaceDestroy *orig_vdp_output_surface_destroy;
-+
-+static VdpVideoSurfacePutBitsYCbCr *orig_vdp_video_surface_putbits_ycbcr;
-+
- static VdpDecoderCreate *orig_vdp_decoder_create;
- static VdpDecoderDestroy *orig_vdp_decoder_destroy;
- static VdpDecoderRender *orig_vdp_decoder_render;
-
- static Display *guarded_display;
-
-+static VdpStatus guarded_vdp_video_surface_putbits_ycbcr(VdpVideoSurface surface, VdpYCbCrFormat source_ycbcr_format, void const *const *source_data, uint32_t const *source_pitches)
-+{
-+ VdpStatus r;
-+#ifdef LOCKDISPLAY
-+ XLockDisplay(guarded_display);
-+#endif
-+ r = orig_vdp_video_surface_putbits_ycbcr(surface, source_ycbcr_format, source_data, source_pitches);
-+#ifdef LOCKDISPLAY
-+ XUnlockDisplay(guarded_display);
-+#endif
-+ return r;
-+}
-+
- static VdpStatus guarded_vdp_video_surface_create(VdpDevice device, VdpChromaType chroma_type, uint32_t width, uint32_t height,VdpVideoSurface *surface)
- {
- VdpStatus r;
-@@ -195,6 +215,28 @@ static VdpStatus guarded_vdp_video_surfa
- return r;
- }
-
-+static VdpStatus guarded_vdp_output_surface_create(VdpDevice device, VdpChromaType chroma_type, uint32_t width, uint32_t height,VdpVideoSurface *surface)
-+{
-+ VdpStatus r;
-+#ifdef LOCKDISPLAY
-+ XLockDisplay(guarded_display);
-+#endif
-+ r = orig_vdp_output_surface_create(device, chroma_type, width, height, surface);
-+#ifdef LOCKDISPLAY
-+ XUnlockDisplay(guarded_display);
-+#endif
-+ return r;
-+}
-+
-+static VdpStatus guarded_vdp_output_surface_destroy(VdpVideoSurface surface)
-+{
-+ VdpStatus r;
-+ XLockDisplay(guarded_display);
-+ r = orig_vdp_output_surface_destroy(surface);
-+ XUnlockDisplay(guarded_display);
-+ return r;
-+}
-+
- static VdpStatus guarded_vdp_decoder_create(VdpDevice device, VdpDecoderProfile profile, uint32_t width, uint32_t height, uint32_t max_references, VdpDecoder *decoder)
- {
- VdpStatus r;
-@@ -2324,16 +2366,16 @@ static vo_driver_t *vdpau_open_plugin (v
- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_VIDEO_SURFACE_DESTROY , (void*)&orig_vdp_video_surface_destroy ); vdp_video_surface_destroy = guarded_vdp_video_surface_destroy;
- if ( vdpau_init_error( st, "Can't get VIDEO_SURFACE_DESTROY proc address !!", &this->vo_driver, 1 ) )
- return NULL;
-- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR , (void*)&vdp_video_surface_putbits_ycbcr );
-+ st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR , (void*)&orig_vdp_video_surface_putbits_ycbcr ); vdp_video_surface_putbits_ycbcr = guarded_vdp_video_surface_putbits_ycbcr;
- if ( vdpau_init_error( st, "Can't get VIDEO_SURFACE_PUT_BITS_Y_CB_CR proc address !!", &this->vo_driver, 1 ) )
- return NULL;
- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR , (void*)&vdp_video_surface_getbits_ycbcr );
- if ( vdpau_init_error( st, "Can't get VIDEO_SURFACE_GET_BITS_Y_CB_CR proc address !!", &this->vo_driver, 1 ) )
- return NULL;
-- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_CREATE , (void*)&vdp_output_surface_create );
-+ st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_CREATE , (void*)&orig_vdp_output_surface_create ); vdp_output_surface_create = guarded_vdp_output_surface_create;
- if ( vdpau_init_error( st, "Can't get OUTPUT_SURFACE_CREATE proc address !!", &this->vo_driver, 1 ) )
- return NULL;
-- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY , (void*)&vdp_output_surface_destroy );
-+ st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY , (void*)&orig_vdp_output_surface_destroy ); vdp_output_surface_destroy = guarded_vdp_output_surface_destroy;
- if ( vdpau_init_error( st, "Can't get OUTPUT_SURFACE_DESTROY proc address !!", &this->vo_driver, 1 ) )
- return NULL;
- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE , (void*)&vdp_output_surface_render_bitmap_surface );
diff --git a/multimedia/libxine/files/ffmpeg-vaapi_xine-lib-1.2.2-defaultoff.diff b/multimedia/libxine/files/ffmpeg-vaapi_xine-lib-1.2.2-defaultoff.diff
deleted file mode 100644
index dc413e56b236..000000000000
--- a/multimedia/libxine/files/ffmpeg-vaapi_xine-lib-1.2.2-defaultoff.diff
+++ /dev/null
@@ -1,5997 +0,0 @@
-diff --git a/README.vaapi b/README.vaapi
-new file mode 100644
-index 0000000..8ba7edc
---- /dev/null
-+++ b/README.vaapi
-@@ -0,0 +1,97 @@
-+Make sure you have the following in your ~/.xine/config.
-+
-+General ffmpeg settings :
-+
-+# Priorität für Dekoder ffmpeg-wmv8
-+# numeric, default: 0
-+engine.decoder_priorities.ffmpeg-wmv8:0
-+
-+# Priorität für Dekoder ffmpeg-wmv9
-+# numeric, default: 0
-+engine.decoder_priorities.ffmpeg-wmv9:0
-+
-+# Priorität für Dekoder ffmpegvideo
-+# numeric, default: 0
-+engine.decoder_priorities.ffmpegvideo:1
-+
-+# Priorität für Dekoder mpeg2
-+# numeric, default: 0
-+#engine.decoder_priorities.mpeg2:0
-+
-+Video out settings :
-+
-+#vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob ).
-+# numeric, default: 0
-+#video.output.vaapi_deinterlace:0
-+
-+# vaapi: VDR osd height workaround.
-+# numeric, default: 0
-+#video.output.vaapi_vdr_osd_height:0
-+
-+# vaapi: VDR osd width workaround.
-+# numeric, default: 0
-+#video.output.vaapi_vdr_osd_width:0
-+
-+# VAAPI Mpeg2 softdecoding
-+# bool, default: 0
-+#video.processing.vaapi_mpeg_softdec:0
-+
-+# VAAPI Mpeg2 softdecoding deinterlace
-+# bool, default: 0
-+#video.processing.vaapi_mpeg_softdec_deinterlace:0
-+
-+# vaapi: opengl output rendering
-+# bool, default: 0
-+#video.output.vaapi_opengl_render:0
-+
-+# vaapi: opengl rendering tfp
-+# bool, default: 0
-+#video.output.vaapi_opengl_use_tfp:0
-+
-+# vaapi: set vaapi_guarded_render to 0 ( yes ) 1 ( no )
-+# numeric, default: 0
-+#video.output.vaapi_guarded_render:0
-+
-+If you see crashes set guarded render mode.
-+
-+# vaapi: swap UV planes.
-+# bool, default: 0
-+#video.output.vaapi_swap_uv_planes:0
-+
-+Swap UV is a workaround for IronLake chipsets where the driver is bugy.
-+
-+
-+Notes on use with VDR. The OSD will have some delay. This is technical and can only be overcome
-+writting a complete new decoder which use VAAPI direct and not ffmpeg.
-+
-+For using unsclaed OSD there you can overwrite the OSD size in the config file.
-+
-+For xineliboutput use the defaults.
-+
-+For vdr-xine set in VDR the OSD size to 1920x1080 and use the following in ~/.xine/config :
-+
-+video.output.vaapi_vdr_osd_height:0
-+video.output.vaapi_vdr_osd_width:0
-+
-+The workaround is needed, because vdr-xine does not report the real unscaled OSD size.
-+
-+
-+When you get GPU hangs on Mpeg2 material set :
-+
-+video.processing.vaapi_mpeg_softdec:1
-+
-+This disables VAAPI fpr Mpeg2.
-+
-+
-+You can use example.config.vaapi as an example config for xine.
-+
-+Call xine like : xine -V vaapi video.mkv
-+
-+xvba-vaapi hints:
-+
-+export LIBVA_DRIVER_NAME=xvba
-+export LIBVA_DRIVERS_PATH=/usr/lib/dri/
-+video.output.vaapi_opengl_render:1
-+
-+
-+Postprocessing does not work. Do not use "--post vdr_video --post vdr-audio --post vdr" in your xine call.
-diff --git a/example.config.vaapi b/example.config.vaapi
-new file mode 100644
-index 0000000..901860b
---- /dev/null
-+++ b/example.config.vaapi
-@@ -0,0 +1,749 @@
-+#
-+# xine config file
-+#
-+.version:2
-+
-+# Entries which are still set to their default values are commented out.
-+# Remove the '#' at the beginning of the line, if you want to change them.
-+
-+# Deinterlacing automatisch aktivieren
-+# bool, default: 0
-+#gui.deinterlace_by_default:0
-+
-+# Erfahrenheit einstellen
-+# { Beginner Advanced Expert Master of the known universe }, default: 0
-+#gui.experience_level:Beginner
-+
-+# OSD-Unterstützung aktivieren
-+# bool, default: 1
-+#gui.osd_enabled:1
-+
-+# OSD Anzeigezeit [s]
-+# numeric, default: 3
-+#gui.osd_timeout:3
-+
-+# Benutzer fragen bei Wiedergabe mit nichtunterstütztem coder
-+# bool, default: 0
-+#gui.play_anyway:0
-+
-+# Automatische alte Playliste wiederherstellen
-+# bool, default: 0
-+#gui.playlist_auto_reload:0
-+
-+# Audio-Visualisierung
-+# { oscope fftscope fftgraph goom }, default: 0
-+#gui.post_audio_plugin:oscope
-+
-+# gui skin Thema
-+# { xinetic }, default: 0
-+#gui.skin:xinetic
-+
-+# xine-Verhalten für unerfahrene Benutzer anpassen
-+# bool, default: 1
-+#gui.smart_mode:1
-+
-+# Schnappschußverzeichnis
-+# string, default: /home/gimli
-+#gui.snapshotdir:/home/gimli
-+
-+# Startbildschirm anzeigen
-+# bool, default: 1
-+#gui.splash:1
-+
-+# Untertitel automatisch laden
-+# bool, default: 1
-+#gui.subtitle_autoload:1
-+
-+# Stil der Videoanimation
-+# { None Post Plugin Stream Animation }, default: 1
-+#gui.visual_anim:Post Plugin
-+
-+# Fensterüberlagerung (mehr)
-+# bool, default: 0
-+#gui.always_layer_above:0
-+
-+# Audiomischpultmethode
-+# { Sound card Software }, default: 0
-+#gui.audio_mixer_method:Sound card
-+
-+# Anzeigeverhalten von Bedienfeld
-+# bool, default: 0
-+#gui.auto_panel_visibility:0
-+
-+# Anzeigeverhalten des Ausgabefensters
-+# bool, default: 0
-+#gui.auto_video_output_visibility:0
-+
-+# Deinterlace-Plugin.
-+# string, default: tvtime:method=LinearBlend,cheap_mode=1,pulldown=0,use_progressive_frame_flag=1
-+#gui.deinterlace_plugin:tvtime:method=LinearBlend,cheap_mode=1,pulldown=0,use_progressive_frame_flag=1
-+
-+# Verhalten von Ereignissender
-+# bool, default: 1
-+#gui.eventer_sticky:1
-+
-+# Fensterüberlagerung
-+# bool, default: 0
-+#gui.layer_above:0
-+
-+# Unvergrößertes OSD benutzen
-+# bool, default: 1
-+#gui.osd_use_unscaled:1
-+
-+# Bildschirmschoner Resetintervall [s]
-+# numeric, default: 10
-+#gui.screensaver_timeout:10
-+
-+# Menu Tastenkürzelstil
-+# { Windows style Emacs style }, default: 0
-+#gui.shortcut_style:Windows style
-+
-+# Datenstrominformationen
-+# bool, default: 0
-+#gui.sinfo_auto_update:0
-+
-+# Skin-Server URL
-+# string, default: http://xine.sourceforge.net/skins/skins.slx
-+#gui.skin_server_url:http://xine.sourceforge.net/skins/skins.slx
-+
-+# Kapitelspringen
-+# bool, default: 1
-+#gui.skip_by_chapter:1
-+
-+# Neue Datemstromgröße verändert Ausgabefenstergröße
-+# bool, default: 1
-+#gui.stream_resize_window:1
-+
-+# Hinweiszeit (ms)
-+# numeric, default: 5000
-+#gui.tips_timeout:5000
-+
-+# gui Hinweise sichtbar
-+# bool, default: 1
-+#gui.tips_visible:1
-+
-+# Name des Video-Bildschirms
-+# string, default:
-+#gui.video_display:
-+
-+# Synchrones X-Protokoll (Fehlersuche)
-+# bool, default: 0
-+#gui.xsynchronize:0
-+
-+# Doppelte Größe für kleine Datemströme (Erfordert stream_resize_window)
-+# bool, default: 0
-+#gui.zoom_small_stream:0
-+
-+# Logo MRL
-+# string, default: /usr/share/xine/skins/xine-ui_logo.png
-+#gui.logo_mrl:/usr/share/xine/skins/xine-ui_logo.png
-+
-+# Benutze XVidModeExtension beim Umschalten auf Vollbild
-+# bool, default: 0
-+#gui.use_xvidext:0
-+
-+# Höhe für Xinerama-Vollbildmodus (-8192 = automatisch)
-+# numeric, default: -8192
-+#gui.xinerama_fullscreen_height:-8192
-+
-+# Breite für Xinerama-Vollbildmodus (-8192 = automatisch)
-+# numeric, default: -8192
-+#gui.xinerama_fullscreen_width:-8192
-+
-+# X-Koordinate für Xinerama-Vollbildmodus (-8192 = automatisch)
-+# numeric, default: -8192
-+#gui.xinerama_fullscreen_x:-8192
-+
-+# Y-Koordinate für Xinerama-Vollbildmodus (-8192 = automatisch)
-+# numeric, default: -8192
-+#gui.xinerama_fullscreen_y:-8192
-+
-+# Zu nutzende Bildschirme im Xinerama Vollbildmodus (z.B. 0 2 3)
-+# string, default: 0 1
-+#gui.xinerama_use_screens:0 1
-+
-+# Verstärkungslevel
-+# [0..200], default: 100
-+#gui.amp_level:100
-+
-+# gui Fenster sichtbar
-+# bool, default: 1
-+gui.panel_visible:0
-+
-+# numeric, default: 200
-+#gui.panel_x:200
-+
-+# numeric, default: 100
-+#gui.panel_y:100
-+
-+gui.setup_x:81
-+
-+gui.setup_y:104
-+
-+# color specification yuv-opacity
-+# string, default: 8080c0-f
-+#gui.osdmenu.color_focused_button:8080c0-f
-+
-+# color specification yuv-opacity
-+# string, default: 808080-f
-+#gui.osdmenu.color_focused_slider:808080-f
-+
-+# color specification yuv-opacity
-+# string, default: ff8080-f
-+#gui.osdmenu.color_focused_slider_knob:ff8080-f
-+
-+# color specification yuv-opacity
-+# string, default: 808080-f
-+#gui.osdmenu.color_focused_text_border:808080-f
-+
-+# color specification yuv-opacity
-+# string, default: ff8080-f
-+#gui.osdmenu.color_focused_text_foreground:ff8080-f
-+
-+# color specification yuv-opacity
-+# string, default: 0080c0-f
-+#gui.osdmenu.color_label_border:0080c0-f
-+
-+# color specification yuv-opacity
-+# string, default: c08080-f
-+#gui.osdmenu.color_label_foreground:c08080-f
-+
-+# color specification yuv-opacity
-+# string, default: 0080c0-f
-+#gui.osdmenu.color_label_window:0080c0-f
-+
-+# color specification yuv-opacity
-+# string, default: 008000-f
-+#gui.osdmenu.color_slider:008000-f
-+
-+# color specification yuv-opacity
-+# string, default: ffff00-f
-+#gui.osdmenu.color_slider_knob:ffff00-f
-+
-+# color specification yuv-opacity
-+# string, default: 008000-f
-+#gui.osdmenu.color_text_border:008000-f
-+
-+# color specification yuv-opacity
-+# string, default: ffff00-f
-+#gui.osdmenu.color_text_foreground:ffff00-f
-+
-+# color specification yuv-opacity
-+# string, default: 0080c0-f
-+#gui.osdmenu.color_text_window:0080c0-f
-+
-+# directory a media in dvd device will be mounted
-+# string, default: /dvd
-+#gui.osdmenu.dvd_mountpoint:/dvd
-+
-+# Farbpalette (Vordergrund-Rand-Hintergrund) für Untertitel und OSD
-+# { white-black-transparent white-none-transparent white-none-translucid yellow-black-transparent }, default: 0
-+#ui.osd.text_palette:white-black-transparent
-+
-+# Änderungen an Hardwaremixer melden
-+# bool, default: 1
-+#audio.alsa_hw_mixer:1
-+
-+# Zu benutzender Audiotreiber
-+# { auto null alsa oss file none }, default: 0
-+#audio.driver:auto
-+
-+# Benutze dynamische A/52 Bereichskomprimierung
-+# bool, default: 0
-+#audio.a52.dynamic_range:0
-+
-+# Heruntermischen zu Zweikanal Stereo Raumklang
-+# bool, default: 0
-+#audio.a52.surround_downmix:0
-+
-+# A/52 Lautstärke
-+# [0..200], default: 100
-+#audio.a52.level:100
-+
-+# Gerät für Monoausgabe
-+# string, default: default
-+#audio.device.alsa_default_device:default
-+
-+# Gerät für Stereoausgabe
-+# string, default: plug:front:default
-+audio.device.alsa_front_device:default
-+
-+# ALSA Mixergerät
-+# string, default: PCM
-+#audio.device.alsa_mixer_name:PCM
-+
-+# Soundkarte unterstützt mmap
-+# bool, default: 0
-+#audio.device.alsa_mmap_enable:0
-+
-+# Gerät für 5.1-Kanalausgabe
-+# string, default: iec958:AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2
-+#audio.device.alsa_passthrough_device:iec958:AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2
-+
-+# Gerät für 4-Kanalausgabe
-+# string, default: plug:surround40:0
-+#audio.device.alsa_surround40_device:plug:surround40:0
-+
-+# Gerät für 5.1-Kanalausgabe
-+# string, default: plug:surround51:0
-+#audio.device.alsa_surround51_device:plug:surround51:0
-+
-+# Lautsprecherplazierung
-+# { Mono 1.0 Stereo 2.0 Headphones 2.0 Stereo 2.1 Surround 3.0 Surround 4.0 Surround 4.1 Surround 5.0 Surround 5.1 Surround 6.0 Surround 6.1 Surround 7.1 Pass Through }, default: 1
-+#audio.output.speaker_arrangement:Stereo 2.0
-+
-+# Versatz für digitales Passthrough
-+# numeric, default: 0
-+#audio.synchronization.passthrough_offset:0
-+
-+# Audiowiedergabe während langsamer/schneller Geschwindigkeit
-+# bool, default: 0
-+#audio.synchronization.slow_fast_audio:0
-+
-+# Methode für Audio/Videosynchronisation
-+# { metronom feedback resample }, default: 0
-+#audio.synchronization.av_sync_method:metronom feedback
-+
-+# Wenn !=0, immer auf diese Rate anpassen
-+# numeric, default: 0
-+#audio.synchronization.force_rate:0
-+
-+# Resampling benutzen
-+# { auto off on }, default: 0
-+#audio.synchronization.resample_mode:auto
-+
-+# Startlautstärke
-+# [0..100], default: 50
-+#audio.volume.mixer_volume:50
-+
-+# Lautstärke beim Starten wiederherstellen
-+# bool, default: 0
-+#audio.volume.remember_volume:0
-+
-+# Zu benutzender Videotreiber
-+# { auto vdpau xv vaapi opengl raw xshm none fb }, default: 0
-+video.driver:vaapi
-+
-+# Alle Videoskalierungen deaktivieren
-+# bool, default: 0
-+#video.output.disable_scaling:0
-+
-+# Horizontale Bildposition im Ausgabefenster
-+# [0..100], default: 50
-+#video.output.horizontal_position:50
-+
-+# vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob ).
-+# numeric, default: 0
-+#video.output.vaapi_deinterlace:0
-+
-+# vaapi: indirect output rendering
-+# bool, default: 0
-+#video.output.vaapi_indirect_render:0
-+
-+# vaapi: VDR osd height workaround.
-+# numeric, default: 0
-+#video.output.vaapi_vdr_osd_height:0
-+
-+# vaapi: VDR osd width workaround.
-+# numeric, default: 0
-+#video.output.vaapi_vdr_osd_width:0
-+
-+# Vertikale Bildposition im Ausgabefenster
-+# [0..100], default: 50
-+#video.output.vertical_position:50
-+
-+# Choose speed over specification compliance
-+# bool, default: 0
-+#video.processing.ffmpeg_choose_speed_over_accuracy:0
-+
-+# Enable usage of VAAPI
-+# bool, default: 1
-+#video.processing.ffmpeg_enable_vaapi:0
-+
-+# Qualität der MPEG-4 Nachbearbeitungsstufe
-+# [0..6], default: 3
-+#video.processing.ffmpeg_pp_quality:3
-+
-+# Skip loop filter
-+# { default none nonref bidir nonkey all }, default: 0
-+#video.processing.ffmpeg_skip_loop_filter:default
-+
-+# FFmpeg video decoding thread count
-+# numeric, default: 1
-+#video.processing.ffmpeg_thread_count:1
-+
-+# VAAPI Mpeg2 softdecoding
-+# bool, default: 0
-+#video.processing.vaapi_mpeg_sofdec:0
-+
-+# VAAPI Mpeg2 softdecoding deinterlace
-+# bool, default: 0
-+#video.processing.vaapi_mpeg_sofdec_deinterlace:0
-+
-+# Gerät für CD-Audio
-+# string, default: /dev/cdrom
-+#media.audio_cd.device:/dev/cdrom
-+
-+# Laufwerk auf diesen Faktor verlangsamen
-+# numeric, default: 4
-+#media.audio_cd.drive_slowdown:4
-+
-+# CDDB abfragen
-+# bool, default: 1
-+#media.audio_cd.use_cddb:1
-+
-+# CDDB Serverport
-+# numeric, default: 8880
-+#media.audio_cd.cddb_port:8880
-+
-+# CDDB Servername
-+# string, default: freedb.freedb.org
-+#media.audio_cd.cddb_server:freedb.freedb.org
-+
-+# BluRay player country code
-+# string, default: en
-+#media.bluray.country:en
-+
-+# device used for BluRay playback
-+# string, default: /dev/dvd
-+#media.bluray.device:/dev/dvd
-+
-+# default language for BluRay playback
-+# string, default: eng
-+#media.bluray.language:eng
-+
-+# BluRay mount point
-+# string, default: /mnt/bluray
-+#media.bluray.mountpoint:/mnt/bluray
-+
-+# parental control age limit (1-99)
-+# numeric, default: 99
-+#media.bluray.parental:99
-+
-+# BluRay player region code (1=A, 2=B, 4=C)
-+# numeric, default: 7
-+#media.bluray.region:7
-+
-+# Pfad zum Sichen von Datenströmen
-+# string, default:
-+#media.capture.save_dir:
-+
-+# Nummer der zu benutzenden DVB-Karte.
-+# numeric, default: 0
-+#media.dvb.adapter:0
-+
-+# Zuletzt gesehenen DVB-Kanal vermerken
-+# bool, default: 1
-+#media.dvb.remember_channel:1
-+
-+# Number of seconds until tuning times out.
-+# numeric, default: 0
-+#media.dvb.tuning_timeout:0
-+
-+# Enable the DVB GUI
-+# bool, default: 1
-+#media.dvb.gui_enabled:1
-+
-+# Zuletzt gesehener DVB-Kanal
-+# numeric, default: -1
-+#media.dvb.last_channel:-1
-+
-+# Standardsprache für die DVD-Wiedergabe
-+# string, default: en
-+#media.dvd.language:en
-+
-+# Region (1-8), aus der der DVD Player zu kommen scheint
-+# numeric, default: 1
-+#media.dvd.region:1
-+
-+# Gerät für DVD Wiedergabe
-+# string, default: /dev/dvd
-+#media.dvd.device:/dev/dvd
-+
-+# Pfad zum RAW-Device des DVD-Laufwerks
-+# string, default: /dev/rdvd
-+#media.dvd.raw_device:/dev/rdvd
-+
-+# Vorauseilendes Caching benutzen
-+# bool, default: 1
-+#media.dvd.readahead:1
-+
-+# CSS Entschlüsselungsmethode
-+# { key disc title }, default: 0
-+#media.dvd.css_decryption_method:key
-+
-+# Wiedergabemodus falls Titel/Kapitel angegeben
-+# { entire dvd one chapter }, default: 0
-+#media.dvd.play_single_chapter:entire dvd
-+
-+# Einheit beim Suchen
-+# { seek in program chain seek in program }, default: 0
-+#media.dvd.seek_behaviour:seek in program chain
-+
-+# Einheit für die Überspringen-Aktion
-+# { skip program skip part skip title }, default: 0
-+#media.dvd.skip_behaviour:skip program
-+
-+# Startverzeichnis für Dateisuche
-+# string, default: /home/gimli
-+#media.files.origin_path:/home/gimli
-+
-+# Versteckte Dateien anzeigen
-+# bool, default: 0
-+#media.files.show_hidden_files:0
-+
-+# Netzwerkbandbreite
-+# { 14.4 Kbps (Modem) 19.2 Kbps (Modem) 28.8 Kbps (Modem) 33.6 Kbps (Modem) 34.4 Kbps (Modem) 57.6 Kbps (Modem) 115.2 Kbps (ISDN) 262.2 Kbps (Cable/DSL) 393.2 Kbps (Cable/DSL) 524.3 Kbps (Cable/DSL) }, default: 10
-+
-+# Zeitüberschreitung für Netzwerkdatenströme (in Sekunden)
-+# numeric, default: 30
-+#media.network.timeout:30
-+
-+# Domains, die den HTTP Proxy umgehen
-+# string, default:
-+#media.network.http_no_proxy:
-+
-+# HTTP Proxy Rechnername
-+# string, default:
-+#media.network.http_proxy_host:
-+
-+# HTTP Proxy Passwort
-+# string, default:
-+#media.network.http_proxy_password:
-+
-+# HTTP Proxy Portnummer
-+# numeric, default: 80
-+#media.network.http_proxy_port:80
-+
-+# HTTP Proxy Benutzername
-+# string, default:
-+#media.network.http_proxy_user:
-+
-+# MMS-Protokoll
-+# { auto TCP HTTP }, default: 0
-+#media.network.mms_protocol:auto
-+
-+# default VDR host
-+# string, default: xvdr://127.0.0.1#nocache;demux:mpeg_block
-+#media.xvdr.default_mrl:xvdr://127.0.0.1#nocache;demux:mpeg_block
-+
-+# Fast (low-quality) OSD scaling
-+# bool, default: 0
-+#media.xvdr.fast_osd_scaling:0
-+
-+# number of buffers for HD content
-+# numeric, default: 2500
-+#media.xvdr.num_buffers_hd:2500
-+
-+# SCR-Treshold for HD-Playback (%)
-+# numeric, default: 40
-+#media.xvdr.scr_treshold_hd:40
-+
-+# SCR-Treshold for SD-Playback (%)
-+# numeric, default: 50
-+#media.xvdr.scr_treshold_sd:50
-+
-+# SRC tuning step
-+# numeric, default: 5000
-+#media.xvdr.scr_tuning_step:5000
-+
-+# Smoother SRC tuning
-+# bool, default: 0
-+#media.xvdr.smooth_scr_tuning:0
-+
-+# opacity for the black parts of bitmapped subtitles
-+# [0..100], default: 67
-+#subtitles.bitmap.black_opacity:67
-+
-+# opacity for the colour parts of bitmapped subtitles
-+# [0..100], default: 100
-+#subtitles.bitmap.colour_opacity:100
-+
-+# Untertitelgröße
-+# { tiny small normal large very large huge }, default: 1
-+#subtitles.separate.subtitle_size:small
-+
-+# Vertikaler Versatz für Untertitel
-+# numeric, default: 0
-+#subtitles.separate.vertical_offset:0
-+
-+# Zeichensatz für Untertitel
-+# string, default: sans
-+#subtitles.separate.font:sans
-+
-+# Zeichenkodierung für Untertitel
-+# string, default: iso-8859-1
-+#subtitles.separate.src_encoding:iso-8859-1
-+
-+# Benutze unskaliertes OSD falls möglich
-+# bool, default: 1
-+#subtitles.separate.use_unscaled_osd:1
-+
-+# Zu generierende Bilder/Sekunde
-+# numeric, default: 14
-+#effects.goom.fps:14
-+
-+# Goom Bildhöhe
-+# numeric, default: 240
-+#effects.goom.height:240
-+
-+# Goom Bildbreite
-+# numeric, default: 320
-+#effects.goom.width:320
-+
-+# Farbraumkonvertierungsmethode
-+# { Fast but not photorealistic Slow but looks better }, default: 0
-+#effects.goom.csc_method:Fast but not photorealistic
-+
-+# Anzahl der Audiopuffer
-+# numeric, default: 230
-+#engine.buffers.audio_num_buffers:230
-+
-+# Anzahl der Videopuffer
-+# numeric, default: 500
-+#engine.buffers.video_num_buffers:500
-+
-+# Standardanzahl von Videobildern
-+# numeric, default: 21
-+engine.buffers.video_num_frames:22
-+
-+# disable decoder flush at discontinuity
-+# bool, default: 0
-+#engine.decoder.disable_flush_at_discontinuity:0
-+
-+# disable decoder flush from video out
-+# bool, default: 0
-+#engine.decoder.disable_flush_from_video_out:0
-+
-+# Priorität für Dekoder a/52
-+# numeric, default: 0
-+#engine.decoder_priorities.a/52:0
-+
-+# Priorität für Dekoder bitplane
-+# numeric, default: 0
-+#engine.decoder_priorities.bitplane:0
-+
-+# Priorität für Dekoder dts
-+# numeric, default: 0
-+#engine.decoder_priorities.dts:0
-+
-+# Priorität für Dekoder dvaudio
-+# numeric, default: 0
-+#engine.decoder_priorities.dvaudio:0
-+
-+# Priorität für Dekoder faad
-+# numeric, default: 0
-+#engine.decoder_priorities.faad:0
-+
-+# Priorität für Dekoder ffmpeg-wmv8
-+# numeric, default: 0
-+#engine.decoder_priorities.ffmpeg-wmv8:0
-+
-+# Priorität für Dekoder ffmpeg-wmv9
-+# numeric, default: 0
-+#engine.decoder_priorities.ffmpeg-wmv9:0
-+
-+# Priorität für Dekoder ffmpegaudio
-+# numeric, default: 0
-+#engine.decoder_priorities.ffmpegaudio:0
-+
-+# Priorität für Dekoder ffmpegvideo
-+# numeric, default: 0
-+engine.decoder_priorities.ffmpegvideo:1
-+
-+# Priorität für Dekoder flacdec
-+# numeric, default: 0
-+#engine.decoder_priorities.flacdec:0
-+
-+# Priorität für Dekoder gsm610
-+# numeric, default: 0
-+#engine.decoder_priorities.gsm610:0
-+
-+# Priorität für Dekoder mad
-+# numeric, default: 0
-+#engine.decoder_priorities.mad:0
-+
-+# Priorität für Dekoder mpeg2
-+# numeric, default: 0
-+#engine.decoder_priorities.mpeg2:0
-+
-+# Priorität für Dekoder pcm
-+# numeric, default: 0
-+#engine.decoder_priorities.pcm:0
-+
-+# Priorität für Dekoder rgb
-+# numeric, default: 0
-+#engine.decoder_priorities.rgb:0
-+
-+# Priorität für Dekoder spucc
-+# numeric, default: 0
-+#engine.decoder_priorities.spucc:0
-+
-+# Priorität für Dekoder spucmml
-+# numeric, default: 0
-+#engine.decoder_priorities.spucmml:0
-+
-+# Priorität für Dekoder spudec
-+# numeric, default: 0
-+#engine.decoder_priorities.spudec:0
-+
-+# Priorität für Dekoder spudvb
-+# numeric, default: 0
-+#engine.decoder_priorities.spudvb:0
-+
-+# Priorität für Dekoder spuhdmv
-+# numeric, default: 0
-+#engine.decoder_priorities.spuhdmv:0
-+
-+# Priorität für Dekoder sputext
-+# numeric, default: 0
-+#engine.decoder_priorities.sputext:0
-+
-+# Priorität für Dekoder theora
-+# numeric, default: 0
-+#engine.decoder_priorities.theora:0
-+
-+# Priorität für Dekoder vdpau_h264
-+# numeric, default: 0
-+#engine.decoder_priorities.vdpau_h264:0
-+
-+# Priorität für Dekoder vdpau_mpeg12
-+# numeric, default: 0
-+#engine.decoder_priorities.vdpau_mpeg12:0
-+
-+# Priorität für Dekoder vdpau_mpeg4
-+# numeric, default: 0
-+#engine.decoder_priorities.vdpau_mpeg4:0
-+
-+# Priorität für Dekoder vdpau_vc1
-+# numeric, default: 0
-+#engine.decoder_priorities.vdpau_vc1:0
-+
-+# Priorität für Dekoder vorbis
-+# numeric, default: 0
-+#engine.decoder_priorities.vorbis:0
-+
-+# Priorität für Dekoder yuv
-+# numeric, default: 0
-+#engine.decoder_priorities.yuv:0
-+
-+# Medienformaterkennungsstrategie
-+# { default reverse content extension }, default: 0
-+#engine.demux.strategy:default
-+
-+# xines Methode zum Kopieren von Speicher
-+# { probe libc kernel mmx mmxext sse }, default: 0
-+engine.performance.memcpy_method:libc
-+
-+# Erlaubter Prozentsatz für verworfene Frames
-+# numeric, default: 10
-+#engine.performance.warn_discarded_threshold:10
-+
-+# Erlaubter Prozentsatz für übersprungene Frames
-+# numeric, default: 10
-+#engine.performance.warn_skipped_threshold:10
-+
-+# Erlaube implizierte Änderungen an Konfiguration (z.B. durch MRL)
-+# bool, default: 0
-+#misc.implicit_config:0
-+
-diff --git a/include/xine.h b/include/xine.h
-index 073a9fa..b6112e9 100644
---- a/include/xine.h
-+++ b/include/xine.h
-@@ -458,6 +458,7 @@ int xine_get_current_frame_data (xine_stream_t *stream,
- #define XINE_IMGFMT_XVMC (('C'<<24)|('M'<<16)|('v'<<8)|'X')
- #define XINE_IMGFMT_XXMC (('C'<<24)|('M'<<16)|('x'<<8)|'X')
- #define XINE_IMGFMT_VDPAU (('A'<<24)|('P'<<16)|('D'<<8)|'V')
-+#define XINE_IMGFMT_VAAPI (('P'<<24)|('A'<<16)|('A'<<8)|'V')
-
- /* get current xine's virtual presentation timestamp (1/90000 sec)
- * note: this is mostly internal data.
-diff --git a/include/xine/video_out.h b/include/xine/video_out.h
-index 1712f5d..6f8c265 100644
---- a/include/xine/video_out.h
-+++ b/include/xine/video_out.h
-@@ -305,6 +305,7 @@ struct xine_video_port_s {
- #define VO_CAP_VDPAU_MPEG12 0x00000100 /* driver can use VDPAU for mpeg1/2 */
- #define VO_CAP_VDPAU_VC1 0x00000200 /* driver can use VDPAU for VC1 */
- #define VO_CAP_VDPAU_MPEG4 0x00000400 /* driver can use VDPAU for mpeg4-part2 */
-+#define VO_CAP_VAAPI 0x00000600 /* driver can use VAAPI */
- #define VO_CAP_HUE 0x00010000
- #define VO_CAP_SATURATION 0x00020000
- #define VO_CAP_CONTRAST 0x00040000
-diff --git a/src/combined/ffmpeg/Makefile.am b/src/combined/ffmpeg/Makefile.am
-index 3ae65f1..2fb87a0 100644
---- a/src/combined/ffmpeg/Makefile.am
-+++ b/src/combined/ffmpeg/Makefile.am
-@@ -20,12 +20,12 @@ EXTRA_DIST = xine_video.list xine_audio.list mkcodeclist.pl
- noinst_HEADERS = ffmpeg_compat.h
-
- xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \
-- ff_mpeg_parser.c ffmpeg_decoder.h ff_mpeg_parser.h
-+ ff_mpeg_parser.c ffmpeg_decoder.h ff_mpeg_parser.h
-
- nodist_xineplug_decode_ff_la_SOURCES = ffmpeg_config.h
-
- xineplug_decode_ff_la_CFLAGS = $(AM_CFLAGS) $(FFMPEG_CFLAGS) $(FFMPEG_POSTPROC_CFLAGS)
--xineplug_decode_ff_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm $(ZLIB_LIBS) \
-+xineplug_decode_ff_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) $(ZLIB_LIBS) \
- $(FFMPEG_LIBS) $(AVUTIL_LIBS) $(FFMPEG_POSTPROC_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL)
- xineplug_decode_ff_la_LDFLAGS = $(AM_LDFLAGS) $(IMPURE_TEXT_LDFLAGS)
-
-diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c
-index ca3e488..24908df 100644
---- a/src/combined/ffmpeg/ff_video_decoder.c
-+++ b/src/combined/ffmpeg/ff_video_decoder.c
-@@ -50,6 +50,8 @@
- # include <libpostproc/postprocess.h>
- #endif
-
-+#include <libavcodec/vaapi.h>
-+#include "accel_vaapi.h"
- #include "ffmpeg_compat.h"
-
- #define VIDEOBUFSIZE (128*1024)
-@@ -68,6 +70,9 @@ typedef struct ff_video_class_s {
- int thread_count;
- int8_t skip_loop_filter_enum;
- int8_t choose_speed_over_accuracy;
-+ int enable_vaapi;
-+ int vaapi_mpeg_softdec;
-+ int vaapi_mpeg_softdec_deinterlace;
- uint8_t enable_dri;
-
- xine_t *xine;
-@@ -138,6 +143,11 @@ struct ff_video_decoder_s {
- #ifdef LOG
- enum PixelFormat debug_fmt;
- #endif
-+
-+ struct vaapi_context vaapi_context;
-+ vaapi_accel_t *accel;
-+ vo_frame_t *accel_img;
-+ uint8_t set_stream_info;
- };
-
- static void ff_check_colorspace (ff_video_decoder_t *this) {
-@@ -200,14 +210,76 @@ static int get_buffer(AVCodecContext *context, AVFrame *av_frame){
- this->aspect_ratio = (double)width / (double)height;
- this->aspect_ratio_prio = 1;
- lprintf("default aspect ratio: %f\n", this->aspect_ratio);
-- set_stream_info(this);
-+ this->set_stream_info = 1;
- }
- }
-
- avcodec_align_dimensions(context, &width, &height);
-
-+ if( this->context->pix_fmt == PIX_FMT_VAAPI_VLD) {
-+
-+ av_frame->opaque = NULL;
-+ av_frame->data[0] = NULL;
-+ av_frame->data[1] = NULL;
-+ av_frame->data[2] = NULL;
-+ av_frame->data[3] = NULL;
-+ av_frame->type = FF_BUFFER_TYPE_USER;
-+#ifdef AVFRAMEAGE
-+ av_frame->age = 1;
-+#endif
-+ av_frame->reordered_opaque = context->reordered_opaque;
-+
-+ if(!this->accel->guarded_render(this->accel_img)) {
-+ img = this->stream->video_out->get_frame (this->stream->video_out,
-+ width,
-+ height,
-+ this->aspect_ratio,
-+ this->output_format,
-+ VO_BOTH_FIELDS|this->frame_flags);
-+
-+ av_frame->opaque = img;
-+ xine_list_push_back(this->dr1_frames, av_frame);
-+
-+ vaapi_accel_t *accel = (vaapi_accel_t*)img->accel_data;
-+ ff_vaapi_surface_t *va_surface = accel->get_vaapi_surface(img);
-+
-+ if(va_surface) {
-+ av_frame->data[0] = (void *)va_surface;//(void *)(uintptr_t)va_surface->va_surface_id;
-+ av_frame->data[3] = (void *)(uintptr_t)va_surface->va_surface_id;
-+ }
-+ } else {
-+ ff_vaapi_surface_t *va_surface = this->accel->get_vaapi_surface(this->accel_img);
-+
-+ if(va_surface) {
-+ av_frame->data[0] = (void *)va_surface;//(void *)(uintptr_t)va_surface->va_surface_id;
-+ av_frame->data[3] = (void *)(uintptr_t)va_surface->va_surface_id;
-+ }
-+ }
-+
-+ lprintf("1: 0x%08x\n", av_frame->data[3]);
-+
-+ 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;
-+ }
-+
-+ /* on vaapi out do not use direct rendeing */
-+ if(this->class->enable_vaapi) {
-+ this->output_format = XINE_IMGFMT_YV12;
-+ }
-+
-+ int guarded_render = 0;
-+ if(this->accel)
-+ guarded_render = this->accel->guarded_render(this->accel_img);
-+
- if (this->full2mpeg || (this->context->pix_fmt != PIX_FMT_YUV420P &&
-- this->context->pix_fmt != PIX_FMT_YUVJ420P)) {
-+ this->context->pix_fmt != PIX_FMT_YUVJ420P) || guarded_render) {
-+
- if (!this->is_direct_rendering_disabled) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _("ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n"));
-@@ -278,6 +350,18 @@ static int get_buffer(AVCodecContext *context, AVFrame *av_frame){
- static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){
- ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque;
-
-+ if( this->context->pix_fmt == PIX_FMT_VAAPI_VLD ) {
-+ if(this->accel->guarded_render(this->accel_img)) {
-+ ff_vaapi_surface_t *va_surface = (ff_vaapi_surface_t *)av_frame->data[0];
-+ if(va_surface != NULL) {
-+ this->accel->release_vaapi_surface(this->accel_img, va_surface);
-+ lprintf("release_buffer: va_surface_id 0x%08x\n", (unsigned int)av_frame->data[3]);
-+ }
-+ }
-+ }
-+
-+ lprintf("3: 0x%08x\n", av_frame->data[3]);
-+
- if (av_frame->type == FF_BUFFER_TYPE_USER) {
- if ( av_frame->opaque ) {
- vo_frame_t *img = (vo_frame_t *)av_frame->opaque;
-@@ -288,7 +372,7 @@ static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){
- xine_list_iterator_t it;
-
- it = xine_list_find(this->dr1_frames, av_frame->opaque);
-- assert(it);
-+ //assert(it);
- if( it != NULL ) {
- xine_list_remove(this->dr1_frames, it);
- }
-@@ -324,6 +408,51 @@ static const int skip_loop_filter_enum_values[] = {
- AVDISCARD_ALL
- };
-
-+static enum PixelFormat get_format(struct AVCodecContext *context, const enum PixelFormat *fmt)
-+{
-+ int i, profile;
-+ ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque;
-+
-+ if(!this->class->enable_vaapi || !this->accel_img)
-+ return PIX_FMT_YUV420P;
-+
-+ vaapi_accel_t *accel = (vaapi_accel_t*)this->accel_img->accel_data;
-+
-+ for (i = 0; fmt[i] != PIX_FMT_NONE; i++) {
-+ if (fmt[i] != PIX_FMT_VAAPI_VLD)
-+ continue;
-+
-+ profile = accel->profile_from_imgfmt(this->accel_img, fmt[i], context->codec_id, this->class->vaapi_mpeg_softdec);
-+
-+ if (profile >= 0) {
-+ VAStatus status;
-+
-+ status = accel->vaapi_init(this->accel_img, profile, context->width, context->height, 0);
-+
-+ if( status == VA_STATUS_SUCCESS ) {
-+ ff_vaapi_context_t *va_context = accel->get_context(this->accel_img);
-+
-+ if(!va_context)
-+ return PIX_FMT_YUV420P;
-+
-+ context->draw_horiz_band = NULL;
-+ context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
-+ context->dsp_mask = 0;
-+
-+ this->vaapi_context.config_id = va_context->va_config_id;
-+ this->vaapi_context.context_id = va_context->va_context_id;
-+ this->vaapi_context.display = va_context->va_display;
-+
-+ context->hwaccel_context = &this->vaapi_context;
-+ this->pts = 0;
-+
-+ return fmt[i];
-+ }
-+ }
-+ }
-+ return PIX_FMT_YUV420P;
-+}
-+
- static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) {
- size_t i;
-
-@@ -369,6 +498,39 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type)
- if (this->class->choose_speed_over_accuracy)
- this->context->flags2 |= CODEC_FLAG2_FAST;
-
-+ if(this->class->enable_vaapi)
-+ {
-+ this->class->thread_count = this->context->thread_count = 1;
-+
-+ this->context->skip_loop_filter = AVDISCARD_DEFAULT;
-+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
-+ _("ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n"));
-+ } else {
-+ this->context->skip_loop_filter = skip_loop_filter_enum_values[this->class->skip_loop_filter_enum];
-+ }
-+
-+ /* enable direct rendering by default */
-+ this->output_format = XINE_IMGFMT_YV12;
-+#ifdef ENABLE_DIRECT_RENDERING
-+ if( this->codec->capabilities & CODEC_CAP_DR1 && this->class->enable_dri ) {
-+ this->context->get_buffer = get_buffer;
-+ this->context->release_buffer = release_buffer;
-+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
-+ _("ffmpeg_video_dec: direct rendering enabled\n"));
-+ }
-+#endif
-+
-+ if( this->class->enable_vaapi ) {
-+ this->class->enable_dri = 1;
-+ this->output_format = XINE_IMGFMT_VAAPI;
-+ this->context->get_buffer = get_buffer;
-+ this->context->reget_buffer = get_buffer;
-+ this->context->release_buffer = release_buffer;
-+ this->context->get_format = get_format;
-+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
-+ _("ffmpeg_video_dec: direct rendering enabled\n"));
-+ }
-+
- #ifdef DEPRECATED_AVCODEC_THREAD_INIT
- if (this->class->thread_count > 1) {
- if (this->codec->id != CODEC_ID_SVQ3)
-@@ -406,7 +568,7 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type)
- #ifndef DEPRECATED_AVCODEC_THREAD_INIT
- if (this->class->thread_count > 1) {
- if (this->codec->id != CODEC_ID_SVQ3
-- && avcodec_thread_init(this->context, this->class->thread_count) != -1)
-+ && avcodec_thread_init(this->context, this->class->thread_count) != -1)
- this->context->thread_count = this->class->thread_count;
- }
- #endif
-@@ -435,37 +597,28 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type)
-
- this->skipframes = 0;
-
-- /* enable direct rendering by default */
-- this->output_format = XINE_IMGFMT_YV12;
--#ifdef ENABLE_DIRECT_RENDERING
-- if( this->codec->capabilities & CODEC_CAP_DR1 && this->class->enable_dri ) {
-- this->context->get_buffer = get_buffer;
-- this->context->release_buffer = release_buffer;
-- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
-- _("ffmpeg_video_dec: direct rendering enabled\n"));
-- }
--#endif
--
- /* flag for interlaced streams */
- this->frame_flags = 0;
- /* FIXME: which codecs can be interlaced?
- FIXME: check interlaced DCT and other codec specific info. */
-- switch( codec_type ) {
-- case BUF_VIDEO_DV:
-- this->frame_flags |= VO_INTERLACED_FLAG;
-- break;
-- case BUF_VIDEO_MPEG:
-- this->frame_flags |= VO_INTERLACED_FLAG;
-- break;
-- case BUF_VIDEO_MJPEG:
-- this->frame_flags |= VO_INTERLACED_FLAG;
-- break;
-- case BUF_VIDEO_HUFFYUV:
-- this->frame_flags |= VO_INTERLACED_FLAG;
-- break;
-- case BUF_VIDEO_H264:
-- this->frame_flags |= VO_INTERLACED_FLAG;
-- break;
-+ if(!this->class->enable_vaapi) {
-+ switch( codec_type ) {
-+ case BUF_VIDEO_DV:
-+ this->frame_flags |= VO_INTERLACED_FLAG;
-+ break;
-+ case BUF_VIDEO_MPEG:
-+ this->frame_flags |= VO_INTERLACED_FLAG;
-+ break;
-+ case BUF_VIDEO_MJPEG:
-+ this->frame_flags |= VO_INTERLACED_FLAG;
-+ break;
-+ case BUF_VIDEO_HUFFYUV:
-+ this->frame_flags |= VO_INTERLACED_FLAG;
-+ break;
-+ case BUF_VIDEO_H264:
-+ this->frame_flags |= VO_INTERLACED_FLAG;
-+ break;
-+ }
- }
-
- #ifdef AVCODEC_HAS_REORDERED_OPAQUE
-@@ -474,6 +627,24 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type)
- #endif
- }
-
-+static void vaapi_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 vaapi_mpeg_softdec_func(void *user_data, xine_cfg_entry_t *entry) {
-+ ff_video_class_t *class = (ff_video_class_t *) user_data;
-+
-+ class->vaapi_mpeg_softdec = entry->num_value;
-+}
-+
-+static void vaapi_mpeg_softdec_deinterlace(void *user_data, xine_cfg_entry_t *entry) {
-+ ff_video_class_t *class = (ff_video_class_t *) user_data;
-+
-+ class->vaapi_mpeg_softdec_deinterlace = entry->num_value;
-+}
-+
- static void choose_speed_over_accuracy_cb(void *user_data, xine_cfg_entry_t *entry) {
- ff_video_class_t *class = (ff_video_class_t *) user_data;
-
-@@ -595,7 +766,7 @@ static int ff_handle_mpeg_sequence(ff_video_decoder_t *this, mpeg_parser_t *pars
- return 1;
- }
-
--static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
-+static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img, AVFrame *av_frame) {
- int y;
- uint8_t *dy, *du, *dv, *sy, *su, *sv;
-
-@@ -609,9 +780,9 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- dy = img->base[0];
- du = img->base[1];
- dv = img->base[2];
-- sy = this->av_frame->data[0];
-- su = this->av_frame->data[1];
-- sv = this->av_frame->data[2];
-+ sy = av_frame->data[0];
-+ su = av_frame->data[1];
-+ sv = av_frame->data[2];
-
- /* Some segfaults & heap corruption have been observed with img->height,
- * so we use this->bih.biHeight instead (which is the displayed height)
-@@ -621,18 +792,18 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
-
- yuv9_to_yv12(
- /* Y */
-- this->av_frame->data[0],
-- this->av_frame->linesize[0],
-+ av_frame->data[0],
-+ av_frame->linesize[0],
- img->base[0],
- img->pitches[0],
- /* U */
-- this->av_frame->data[1],
-- this->av_frame->linesize[1],
-+ av_frame->data[1],
-+ av_frame->linesize[1],
- img->base[1],
- img->pitches[1],
- /* V */
-- this->av_frame->data[2],
-- this->av_frame->linesize[2],
-+ av_frame->data[2],
-+ av_frame->linesize[2],
- img->base[2],
- img->pitches[2],
- /* width x height */
-@@ -643,18 +814,18 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
-
- yuv411_to_yv12(
- /* Y */
-- this->av_frame->data[0],
-- this->av_frame->linesize[0],
-+ av_frame->data[0],
-+ av_frame->linesize[0],
- img->base[0],
- img->pitches[0],
- /* U */
-- this->av_frame->data[1],
-- this->av_frame->linesize[1],
-+ av_frame->data[1],
-+ av_frame->linesize[1],
- img->base[1],
- img->pitches[1],
- /* V */
-- this->av_frame->data[2],
-- this->av_frame->linesize[2],
-+ av_frame->data[2],
-+ av_frame->linesize[2],
- img->base[2],
- img->pitches[2],
- /* width x height */
-@@ -684,7 +855,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b);
- plane_ptr++;
- }
-- sy += this->av_frame->linesize[0];
-+ sy += av_frame->linesize[0];
- }
-
- yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]);
-@@ -713,7 +884,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b);
- plane_ptr++;
- }
-- sy += this->av_frame->linesize[0];
-+ sy += av_frame->linesize[0];
- }
-
- yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]);
-@@ -742,7 +913,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b);
- plane_ptr++;
- }
-- sy += this->av_frame->linesize[0];
-+ sy += av_frame->linesize[0];
- }
-
- yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]);
-@@ -766,7 +937,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b);
- plane_ptr++;
- }
-- sy += this->av_frame->linesize[0];
-+ sy += av_frame->linesize[0];
- }
-
- yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]);
-@@ -790,7 +961,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b);
- plane_ptr++;
- }
-- sy += this->av_frame->linesize[0];
-+ sy += av_frame->linesize[0];
- }
-
- yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]);
-@@ -829,7 +1000,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- this->yuv.v[plane_ptr] = v_palette[pixel];
- plane_ptr++;
- }
-- sy += this->av_frame->linesize[0];
-+ sy += av_frame->linesize[0];
- }
-
- yuv444_to_yuy2(&this->yuv, img->base[0], img->pitches[0]);
-@@ -853,7 +1024,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- q = dy;
- for (x = img->width; x > 0; x--) *q++ = ytab[*p++];
- dy += img->pitches[0];
-- sy += this->av_frame->linesize[0];
-+ sy += av_frame->linesize[0];
- }
-
- for (y = 0; y < this->bih.biHeight / 2; y++) {
-@@ -871,11 +1042,11 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- du += img->pitches[1];
- dv += img->pitches[2];
- if (subsampv) {
-- su += 2 * this->av_frame->linesize[1];
-- sv += 2 * this->av_frame->linesize[2];
-+ su += 2 * av_frame->linesize[1];
-+ sv += 2 * av_frame->linesize[2];
- } else {
-- su += this->av_frame->linesize[1];
-- sv += this->av_frame->linesize[2];
-+ su += av_frame->linesize[1];
-+ sv += av_frame->linesize[2];
- }
- }
-
-@@ -884,7 +1055,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- for (y = 0; y < this->bih.biHeight; y++) {
- xine_fast_memcpy (dy, sy, img->width);
- dy += img->pitches[0];
-- sy += this->av_frame->linesize[0];
-+ sy += av_frame->linesize[0];
- }
-
- for (y = 0; y < this->bih.biHeight / 2; y++) {
-@@ -913,11 +1084,11 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
- du += img->pitches[1];
- dv += img->pitches[2];
- if (subsampv) {
-- su += 2*this->av_frame->linesize[1];
-- sv += 2*this->av_frame->linesize[2];
-+ su += 2*av_frame->linesize[1];
-+ sv += 2*av_frame->linesize[2];
- } else {
-- su += this->av_frame->linesize[1];
-- sv += this->av_frame->linesize[2];
-+ su += av_frame->linesize[1];
-+ sv += av_frame->linesize[2];
- }
- }
-
-@@ -1223,6 +1394,10 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu
- int offset = 0;
- int flush = 0;
- int size = buf->size;
-+ uint8_t *buf_deint = 0;
-+ AVFrame *av_framedisp = this->av_frame;
-+ AVFrame *av_framedeint = NULL;
-+ int bDeint = 0;
-
- lprintf("handle_mpeg12_buffer\n");
-
-@@ -1284,12 +1459,23 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu
- avpkt.data = (uint8_t *)this->mpeg_parser->chunk_buffer;
- avpkt.size = this->mpeg_parser->buffer_size;
- avpkt.flags = AV_PKT_FLAG_KEY;
-- len = avcodec_decode_video2 (this->context, this->av_frame,
-+ if(this->accel) {
-+ len = this->accel->avcodec_decode_video2 ( this->accel_img, this->context, av_framedisp,
- &got_picture, &avpkt);
-+ } else {
-+ len = avcodec_decode_video2 ( this->context, av_framedisp,
-+ &got_picture, &avpkt);
-+ }
- #else
-- len = avcodec_decode_video (this->context, this->av_frame,
-+ if(this->accel) {
-+ len = this->accel->avcodec_decode_video ( this->accel_img, this->context, av_framedisp,
-+ &got_picture, this->mpeg_parser->chunk_buffer,
-+ this->mpeg_parser->buffer_size);
-+ } else {
-+ len = avcodec_decode_video (this->context, av_framedisp,
- &got_picture, this->mpeg_parser->chunk_buffer,
- this->mpeg_parser->buffer_size);
-+ }
- #endif
- lprintf("avcodec_decode_video: decoded_size=%d, got_picture=%d\n",
- len, got_picture);
-@@ -1307,9 +1493,24 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu
- offset += len;
- }
-
-- if (got_picture && this->av_frame->data[0]) {
-+ if(got_picture && this->class->enable_vaapi) {
-+ int width, height;
-+ width = this->context->width;
-+ height = this->context->height;
-+ if((this->bih.biWidth != width) || (this->bih.biHeight != height)) {
-+ this->bih.biWidth = width;
-+ this->bih.biHeight = height;
-+ }
-+ }
-+
-+ if( this->set_stream_info) {
-+ set_stream_info(this);
-+ this->set_stream_info = 0;
-+ }
-+
-+ if (got_picture && av_framedisp->data[0]) {
- /* got a picture, draw it */
-- if(!this->av_frame->opaque) {
-+ if(!av_framedisp->opaque) {
- /* indirect rendering */
- img = this->stream->video_out->get_frame (this->stream->video_out,
- this->bih.biWidth,
-@@ -1320,17 +1521,56 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu
- free_img = 1;
- } else {
- /* DR1 */
-- img = (vo_frame_t*) this->av_frame->opaque;
-+ img = (vo_frame_t*) av_framedisp->opaque;
- free_img = 0;
- }
-
-+ if( this->context->pix_fmt != PIX_FMT_VAAPI_VLD) {
-+ if(av_framedisp->interlaced_frame && this->class->vaapi_mpeg_softdec_deinterlace) {
-+ int size;
-+ int ret;
-+
-+ av_framedeint = avcodec_alloc_frame();
-+
-+ size = avpicture_get_size(this->context->pix_fmt, this->context->width, this->context->height);
-+ buf_deint = av_malloc(size);
-+
-+ if(av_framedeint) {
-+ avpicture_fill((AVPicture*)av_framedeint, buf_deint, this->context->pix_fmt, this->context->width, this->context->height);
-+
-+ ret = avpicture_deinterlace((AVPicture*)av_framedeint, (AVPicture*) av_framedisp,
-+ this->context->pix_fmt, this->context->width, this->context->height);
-+
-+ if(ret) {
-+ av_free( buf_deint );
-+ av_free( av_framedeint );
-+ } else {
-+ bDeint = 1;
-+ av_framedisp = av_framedeint;
-+ }
-+ } else {
-+ av_free( buf_deint );
-+ }
-+ }
-+
-+ if(bDeint) {
-+ ff_convert_frame(this, img, av_framedeint);
-+ } else {
-+ ff_convert_frame(this, img, av_framedisp);
-+ }
-+ }
-+
-+ img->progressive_frame = !this->av_frame->interlaced_frame;
-+ img->top_field_first = this->av_frame->top_field_first;
-+ img->bad_frame = 0;
-+
- /* get back reordered pts */
- img->pts = ff_untag_pts (this, this->av_frame->reordered_opaque);
- ff_check_pts_tagging (this, this->av_frame->reordered_opaque);
- this->av_frame->reordered_opaque = 0;
- this->context->reordered_opaque = 0;
-
-- if (this->av_frame->repeat_pict)
-+ if (av_framedisp->repeat_pict)
- img->duration = this->video_step * 3 / 2;
- else
- img->duration = this->video_step;
-@@ -1338,6 +1578,14 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu
- img->crop_right = this->crop_right;
- img->crop_bottom = this->crop_bottom;
-
-+ if( this->context->pix_fmt == PIX_FMT_VAAPI_VLD) {
-+ if(this->accel->guarded_render(this->accel_img)) {
-+ ff_vaapi_surface_t *va_surface = (ff_vaapi_surface_t *)av_framedisp->data[0];
-+ this->accel->render_vaapi_surface(img, va_surface);
-+ lprintf("handle_mpeg12_buffer: render_vaapi_surface va_surface_id 0x%08x\n", av_framedisp->data[0]);
-+ }
-+ }
-+
- this->skipframes = img->draw(img, this->stream);
-
- if(free_img)
-@@ -1366,6 +1614,12 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu
- img->free(img);
- }
- }
-+
-+ /* free deinterlace picture */
-+ if(bDeint) {
-+ av_free( buf_deint );
-+ av_free( av_framedeint );
-+ }
- }
- }
-
-@@ -1462,12 +1716,23 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
- avpkt.data = (uint8_t *)&chunk_buf[offset];
- avpkt.size = this->size;
- avpkt.flags = AV_PKT_FLAG_KEY;
-- len = avcodec_decode_video2 (this->context, this->av_frame,
-+ if(this->accel) {
-+ len = this->accel->avcodec_decode_video2 ( this->accel_img, this->context, this->av_frame,
-+ &got_picture, &avpkt);
-+ } else {
-+ len = avcodec_decode_video2 (this->context, this->av_frame,
- &got_picture, &avpkt);
-+ }
- #else
-+ if(this->accel) {
-+ len = this->accel->avcodec_decode_video ( this->accel_img, this->context, this->av_frame,
-+ &got_picture, &chunk_buf[offset],
-+ this->size);
-+ } else {
- len = avcodec_decode_video (this->context, this->av_frame,
- &got_picture, &chunk_buf[offset],
- this->size);
-+ }
- #endif
- /* reset consumed pts value */
- this->context->reordered_opaque = ff_tag_pts(this, 0);
-@@ -1519,6 +1784,11 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
- set_stream_info(this);
- }
-
-+ if( this->set_stream_info) {
-+ set_stream_info(this);
-+ this->set_stream_info = 0;
-+ }
-+
- if (got_picture && this->av_frame->data[0]) {
- /* got a picture, draw it */
- got_one_picture = 1;
-@@ -1526,7 +1796,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
- /* indirect rendering */
-
- /* initialize the colorspace converter */
-- if (!this->cs_convert_init) {
-+ if (!this->cs_convert_init && !this->context->pix_fmt != PIX_FMT_VAAPI_VLD) {
- if ((this->context->pix_fmt == PIX_FMT_RGB32) ||
- (this->context->pix_fmt == PIX_FMT_RGB565) ||
- (this->context->pix_fmt == PIX_FMT_RGB555) ||
-@@ -1562,10 +1832,10 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
- }
-
- /* post processing */
-- if(this->pp_quality != this->class->pp_quality)
-+ if(this->pp_quality != this->class->pp_quality && this->context->pix_fmt != PIX_FMT_VAAPI_VLD)
- pp_change_quality(this);
-
-- if(this->pp_available && this->pp_quality) {
-+ if(this->pp_available && this->pp_quality && this->context->pix_fmt != PIX_FMT_VAAPI_VLD) {
-
- if(this->av_frame->opaque) {
- /* DR1 */
-@@ -1578,7 +1848,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
- free_img = 1;
- }
-
-- pp_postprocess(this->av_frame->data, this->av_frame->linesize,
-+ pp_postprocess((const uint8_t **)this->av_frame->data, this->av_frame->linesize,
- img->base, img->pitches,
- img->width, img->height,
- this->av_frame->qscale_table, this->av_frame->qstride,
-@@ -1587,7 +1857,8 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
-
- } else if (!this->av_frame->opaque) {
- /* colorspace conversion or copy */
-- ff_convert_frame(this, img);
-+ if( this->context->pix_fmt != PIX_FMT_VAAPI_VLD)
-+ ff_convert_frame(this, img, this->av_frame);
- }
-
- img->pts = ff_untag_pts(this, this->av_frame->reordered_opaque);
-@@ -1616,6 +1887,15 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
- img->progressive_frame = !this->av_frame->interlaced_frame;
- img->top_field_first = this->av_frame->top_field_first;
-
-+ if( this->context->pix_fmt == PIX_FMT_VAAPI_VLD) {
-+ if(this->accel->guarded_render(this->accel_img)) {
-+ ff_vaapi_surface_t *va_surface = (ff_vaapi_surface_t *)this->av_frame->data[0];
-+ this->accel->render_vaapi_surface(img, va_surface);
-+ if(va_surface)
-+ lprintf("handle_buffer: render_vaapi_surface va_surface_id 0x%08x\n", this->av_frame->data[0]);
-+ }
-+ }
-+
- this->skipframes = img->draw(img, this->stream);
-
- if(free_img)
-@@ -1839,6 +2119,9 @@ static void ff_dispose (video_decoder_t *this_gen) {
-
- xine_list_delete(this->dr1_frames);
-
-+ if(this->accel_img)
-+ this->accel_img->free(this->accel_img);
-+
- free (this_gen);
- }
-
-@@ -1882,11 +2165,42 @@ static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen,
- this->mpeg_parser = NULL;
-
- this->dr1_frames = xine_list_new();
-+ this->set_stream_info = 0;
-
- #ifdef LOG
- this->debug_fmt = -1;
- #endif
-
-+ memset(&this->vaapi_context, 0x0 ,sizeof(struct vaapi_context));
-+
-+ this->dr1_frames = xine_list_new();
-+
-+ this->accel = NULL;
-+ this->accel_img = NULL;
-+
-+
-+ if(this->class->enable_vaapi && (stream->video_driver->get_capabilities(stream->video_driver) & VO_CAP_VAAPI)) {
-+ xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: vaapi_mpeg_softdec %d\n"),
-+ this->class->vaapi_mpeg_softdec );
-+ xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: vaapi_mpeg_softdec_deinterlace %d\n"),
-+ this->class->vaapi_mpeg_softdec_deinterlace );
-+
-+ this->accel_img = stream->video_out->get_frame( stream->video_out, 1920, 1080, 1, XINE_IMGFMT_VAAPI, VO_BOTH_FIELDS );
-+
-+ if( this->accel_img ) {
-+ this->accel = (vaapi_accel_t*)this->accel_img->accel_data;
-+ xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: VAAPI Enabled in config.\n"));
-+ } else {
-+ this->class->enable_vaapi = 0;
-+ xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n"));
-+ }
-+ } else {
-+ this->class->enable_vaapi = 0;
-+ this->class->vaapi_mpeg_softdec = 0;
-+ this->class->vaapi_mpeg_softdec_deinterlace = 0;
-+ xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n"));
-+ }
-+
- return &this->video_decoder;
- }
-
-@@ -1946,6 +2260,20 @@ void *init_video_plugin (xine_t *xine, void *data) {
- "A change of this setting will take effect with playing the next stream."),
- 10, choose_speed_over_accuracy_cb, this);
-
-+ this->vaapi_mpeg_softdec = xine->config->register_bool(config, "video.processing.vaapi_mpeg_softdec", 0,
-+ _("VAAPI Mpeg2 softdecoding"),
-+ _("If the machine freezes on mpeg2 decoding use mpeg2 software decoding."),
-+ 10, vaapi_mpeg_softdec_func, this);
-+
-+ this->vaapi_mpeg_softdec_deinterlace = xine->config->register_bool(config, "video.processing.vaapi_mpeg_softdec_deinterlace", 0,
-+ _("VAAPI Mpeg2 softdecoding deinterlace"),
-+ _("FFMPEGS simple deinterlacer with Mpeg2 software decoding."),
-+ 10, vaapi_mpeg_softdec_deinterlace, this);
-+
-+ this->enable_vaapi = xine->config->register_bool(config, "video.processing.ffmpeg_enable_vaapi", 0,
-+ _("Enable VAAPI"),
-+ _("Enable or disable usage of vaapi"),
-+ 10, vaapi_enable_vaapi, this);
- this->enable_dri = xine->config->register_bool(config, "video.processing.ffmpeg_direct_rendering", 1,
- _("Enable direct rendering"),
- _("Disable direct rendering if you are experiencing lock-ups with\n"
-diff --git a/src/combined/ffmpeg/ffmpeg_decoder.c b/src/combined/ffmpeg/ffmpeg_decoder.c
-index 4f44a7f..cb747fb 100644
---- a/src/combined/ffmpeg/ffmpeg_decoder.c
-+++ b/src/combined/ffmpeg/ffmpeg_decoder.c
-@@ -40,6 +40,9 @@ void init_once_routine(void) {
- pthread_mutex_init(&ffmpeg_lock, NULL);
- avcodec_init();
- avcodec_register_all();
-+
-+ av_log_set_level(AV_LOG_QUIET);
-+
- }
-
- /*
-diff --git a/src/combined/ffmpeg/xine_video.list b/src/combined/ffmpeg/xine_video.list
-index 009f4da..6364c45 100644
---- a/src/combined/ffmpeg/xine_video.list
-+++ b/src/combined/ffmpeg/xine_video.list
-@@ -70,7 +70,7 @@ WNV1 WNV1 Winnow Video
- XL VIXL Miro/Pinnacle VideoXL
- RT21 INDEO2 Indeo/RealTime 2
- FPS1 FRAPS Fraps
--MPEG MPEG1VIDEO MPEG 1/2
-+MPEG MPEG2VIDEO MPEG 1/2
- CSCD CSCD CamStudio
- AVS AVS AVS
- ALGMM MMVIDEO American Laser Games MM
-diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
-index 9ae05d6..66a111a 100644
---- a/src/video_out/Makefile.am
-+++ b/src/video_out/Makefile.am
-@@ -43,6 +43,8 @@ if ENABLE_VDPAU
- vdpau_module = xineplug_vo_out_vdpau.la
- endif
-
-+vaapi_module = xineplug_vo_out_vaapi.la
-+
- if ENABLE_XCB
- XCBOSD = xcbosd.c
- if ENABLE_XCBSHM
-@@ -117,6 +119,7 @@ xineplug_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \
- $(xcbshm_module) \
- $(xcbxv_module) \
- $(vdpau_module) \
-+ $(vaapi_module) \
- xineplug_vo_out_raw.la \
- xineplug_vo_out_none.la
-
-@@ -124,6 +127,10 @@ xineplug_vo_out_vdpau_la_SOURCES = video_out_vdpau.c
- xineplug_vo_out_vdpau_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) $(AVUTIL_LIBS) $(PTHREAD_LIBS) $(X_LIBS) $(LTLIBINTL) $(VDPAU_LIBS) -lm
- xineplug_vo_out_vdpau_la_CFLAGS = $(VISIBILITY_FLAG) $(MLIB_CFLAGS) $(X_CFLAGS) $(VDPAU_CFLAGS) $(AVUTIL_CFLAGS) -fno-strict-aliasing
-
-+xineplug_vo_out_vaapi_la_SOURCES = $(X11OSD) video_out_vaapi.c
-+xineplug_vo_out_vaapi_la_LIBADD = $(YUV_LIBS) $(XINE_LIB) $(OPENGL_LIBS) $(FFMPEG_LIBS) $(AVUTIL_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) -ldl -lGLU -lva-glx -lva-x11 -lva
-+xineplug_vo_out_vaapi_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(XV_CFLAGS) -fno-strict-aliasing
-+
- xineplug_vo_out_xcbshm_la_SOURCES = video_out_xcbshm.c $(XCBOSD)
- xineplug_vo_out_xcbshm_la_LIBADD = $(YUV_LIBS) $(PTHREAD_LIBS) $(XCB_LIBS) $(XCBSHM_LIBS) $(LTLIBINTL)
- xineplug_vo_out_xcbshm_la_CFLAGS = $(AM_CFLAGS) $(XCB_CFLAGS) $(XCBSHM_CFLAGS) $(AVUTIL_CFLAGS) -fno-strict-aliasing
-diff --git a/src/video_out/video_out_vaapi.c b/src/video_out/video_out_vaapi.c
-new file mode 100644
-index 0000000..699950f
---- /dev/null
-+++ b/src/video_out/video_out_vaapi.c
-@@ -0,0 +1,4009 @@
-+/*
-+ * Copyright (C) 2000-2004, 2008 the xine project
-+ *
-+ * This file is part of xine, a free video player.
-+ *
-+ * xine 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.
-+ *
-+ * xine 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 this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
-+ *
-+ * video_out_vaapi.c, VAAPI video extension interface for xine
-+ *
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <math.h>
-+
-+#include <sys/types.h>
-+#if defined(__FreeBSD__)
-+#include <machine/param.h>
-+#endif
-+#include <sys/ipc.h>
-+#include <sys/shm.h>
-+#include <sys/time.h>
-+
-+#include <X11/Xlib.h>
-+#include <X11/Xutil.h>
-+#include <X11/cursorfont.h>
-+#include <time.h>
-+#include <unistd.h>
-+#include "yuv2rgb.h"
-+
-+#define LOG_MODULE "video_out_vaapi"
-+#define LOG_VERBOSE
-+/*
-+#define LOG
-+*/
-+/*
-+#define DEBUG_SURFACE
-+*/
-+#include "xine.h"
-+#include <xine/video_out.h>
-+#include <xine/xine_internal.h>
-+#include <xine/xineutils.h>
-+#include <xine/vo_scale.h>
-+
-+#include <GL/glu.h>
-+#include <GL/glx.h>
-+#include <GL/glext.h>
-+#include <GL/gl.h>
-+#include <dlfcn.h>
-+
-+#include <va/va_x11.h>
-+#include <va/va_glx.h>
-+
-+#include "accel_vaapi.h"
-+
-+#define RENDER_SURFACES 50
-+#define SOFT_SURFACES 3
-+#define SW_WIDTH 1920
-+#define SW_HEIGHT 1080
-+#define STABLE_FRAME_COUNTER 4
-+#define SW_CONTEXT_INIT_FORMAT -1 //VAProfileH264Main
-+
-+#if defined VA_SRC_BT601 && defined VA_SRC_BT709
-+# define USE_VAAPI_COLORSPACE 1
-+#else
-+# define USE_VAAPI_COLORSPACE 0
-+#endif
-+
-+#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)
-+
-+#define FOVY 60.0f
-+#define ASPECT 1.0f
-+#define Z_NEAR 0.1f
-+#define Z_FAR 100.0f
-+#define Z_CAMERA 0.869f
-+
-+#ifndef GLAPIENTRY
-+#ifdef APIENTRY
-+#define GLAPIENTRY APIENTRY
-+#else
-+#define GLAPIENTRY
-+#endif
-+#endif
-+
-+#if defined(__linux__)
-+// Linux select() changes its timeout parameter upon return to contain
-+// the remaining time. Most other unixen leave it unchanged or undefined.
-+#define SELECT_SETS_REMAINING
-+#elif defined(__FreeBSD__) || defined(__sun__) || (defined(__MACH__) && defined(__APPLE__))
-+#define USE_NANOSLEEP
-+#elif defined(HAVE_PTHREADS) && defined(sgi)
-+// SGI pthreads has a bug when using pthreads+signals+nanosleep,
-+// so instead of using nanosleep, wait on a CV which is never signalled.
-+#include <pthread.h>
-+#define USE_COND_TIMEDWAIT
-+#endif
-+
-+#define LOCKDISPLAY
-+
-+#ifdef LOCKDISPLAY
-+#define DO_LOCKDISPLAY XLockDisplay(guarded_display)
-+#define DO_UNLOCKDISPLAY XUnlockDisplay(guarded_display)
-+static Display *guarded_display;
-+#else
-+#define DO_LOCKDISPLAY
-+#define DO_UNLOCKDISPLAY
-+#endif
-+
-+#define RECT_IS_EQ(a, b) ((a).x1 == (b).x1 && (a).y1 == (b).y1 && (a).x2 == (b).x2 && (a).y2 == (b).y2)
-+
-+static const char *const scaling_level_enum_names[] = {
-+ "default", /* VA_FILTER_SCALING_DEFAULT */
-+ "fast", /* VA_FILTER_SCALING_FAST */
-+ "hq", /* VA_FILTER_SCALING_HQ */
-+ "nla", /* VA_FILTER_SCALING_NL_ANAMORPHIC */
-+ NULL
-+};
-+
-+static const int scaling_level_enum_values[] = {
-+ VA_FILTER_SCALING_DEFAULT,
-+ VA_FILTER_SCALING_FAST,
-+ VA_FILTER_SCALING_HQ,
-+ VA_FILTER_SCALING_NL_ANAMORPHIC
-+};
-+
-+typedef struct vaapi_driver_s vaapi_driver_t;
-+
-+typedef struct {
-+ int x0, y0;
-+ int x1, y1, x2, y2;
-+} vaapi_rect_t;
-+
-+typedef struct {
-+ vo_frame_t vo_frame;
-+
-+ int width, height, format, flags;
-+ double ratio;
-+
-+ vaapi_accel_t vaapi_accel_data;
-+} vaapi_frame_t;
-+
-+typedef struct {
-+ VADisplayAttribType type;
-+ int value;
-+ int min;
-+ int max;
-+ int atom;
-+
-+ cfg_entry_t *entry;
-+
-+ vaapi_driver_t *this;
-+
-+} va_property_t;
-+
-+struct vaapi_driver_s {
-+
-+ vo_driver_t vo_driver;
-+
-+ config_values_t *config;
-+
-+ /* X11 related stuff */
-+ Display *display;
-+ int screen;
-+ Drawable drawable;
-+ XColor black;
-+ Window window;
-+
-+ uint32_t capabilities;
-+
-+ int ovl_changed;
-+ vo_overlay_t *overlays[XINE_VORAW_MAX_OVL];
-+ uint32_t *overlay_bitmap;
-+ int overlay_bitmap_size;
-+ uint32_t overlay_bitmap_width;
-+ uint32_t overlay_bitmap_height;
-+ vaapi_rect_t overlay_bitmap_src;
-+ vaapi_rect_t overlay_bitmap_dst;
-+
-+ uint32_t vdr_osd_width;
-+ uint32_t vdr_osd_height;
-+
-+ uint32_t overlay_output_width;
-+ uint32_t overlay_output_height;
-+ vaapi_rect_t overlay_dirty_rect;
-+ int has_overlay;
-+
-+ uint32_t overlay_unscaled_width;
-+ uint32_t overlay_unscaled_height;
-+ vaapi_rect_t overlay_unscaled_dirty_rect;
-+
-+ yuv2rgb_factory_t *yuv2rgb_factory;
-+ yuv2rgb_t *ovl_yuv2rgb;
-+
-+ /* all scaling information goes here */
-+ vo_scale_t sc;
-+
-+ xine_t *xine;
-+
-+ unsigned int deinterlace;
-+
-+ int valid_opengl_context;
-+ int opengl_render;
-+ int opengl_use_tfp;
-+ int query_va_status;
-+
-+ GLuint gl_texture;
-+ GLXContext gl_context;
-+ XVisualInfo *gl_vinfo;
-+ Pixmap gl_pixmap;
-+ Pixmap gl_image_pixmap;
-+
-+ ff_vaapi_context_t *va_context;
-+
-+ int num_frame_buffers;
-+ vaapi_frame_t *frames[RENDER_SURFACES];
-+
-+ pthread_mutex_t vaapi_lock;
-+
-+ unsigned int init_opengl_render;
-+ unsigned int guarded_render;
-+ unsigned int scaling_level_enum;
-+ unsigned int scaling_level;
-+ va_property_t props[VO_NUM_PROPERTIES];
-+ unsigned int swap_uv_planes;
-+};
-+
-+ff_vaapi_surface_t *va_render_surfaces = NULL;
-+VASurfaceID *va_surface_ids = NULL;
-+VASurfaceID *va_soft_surface_ids = NULL;
-+VAImage *va_soft_images = NULL;
-+
-+static void vaapi_destroy_subpicture(vo_driver_t *this_gen);
-+static void vaapi_destroy_image(vo_driver_t *this_gen, VAImage *va_image);
-+static int vaapi_ovl_associate(vo_driver_t *this_gen, int format, int bShow);
-+static VAStatus vaapi_destroy_soft_surfaces(vo_driver_t *this_gen);
-+static VAStatus vaapi_destroy_render_surfaces(vo_driver_t *this_gen);
-+static const char *vaapi_profile_to_string(VAProfile profile);
-+static int vaapi_set_property (vo_driver_t *this_gen, int property, int value);
-+static void vaapi_show_display_props(vo_driver_t *this_gen);
-+
-+static void nv12_to_yv12(const uint8_t *y_src, int y_src_pitch,
-+ const uint8_t *uv_src, int uv_src_pitch,
-+ uint8_t *y_dst, int y_dst_pitch,
-+ uint8_t *u_dst, int u_dst_pitch,
-+ uint8_t *v_dst, int v_dst_pitch,
-+ int src_width, int src_height,
-+ int dst_width, int dst_height,
-+ int src_data_size);
-+
-+static void yv12_to_nv12(const uint8_t *y_src, int y_src_pitch,
-+ const uint8_t *u_src, int u_src_pitch,
-+ const uint8_t *v_src, int v_src_pitch,
-+ uint8_t *y_dst, int y_dst_pitch,
-+ uint8_t *uv_dst, int uv_dst_pitch,
-+ int src_width, int src_height,
-+ int dst_width, int dst_height,
-+ int dst_data_size);
-+
-+void (GLAPIENTRY *mpglGenTextures)(GLsizei, GLuint *);
-+void (GLAPIENTRY *mpglBindTexture)(GLenum, GLuint);
-+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);
-+const GLubyte *(GLAPIENTRY *mpglGetString)(GLenum);
-+void (GLAPIENTRY *mpglGenPrograms)(GLsizei, GLuint *);
-+
-+#ifdef LOG
-+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;
-+}
-+#endif
-+
-+static int vaapi_check_status(vo_driver_t *this_gen, VAStatus vaStatus, const char *msg)
-+{
-+
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ if (vaStatus != VA_STATUS_SUCCESS) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " Error : %s: %s\n", msg, vaErrorStr(vaStatus));
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+/* Wrapper for ffmpeg avcodec_decode_video2 */
-+#if AVVIDEO > 1
-+static int guarded_avcodec_decode_video2(vo_frame_t *frame_gen, AVCodecContext *avctx, AVFrame *picture,
-+ int *got_picture_ptr, AVPacket *avpkt) {
-+
-+ vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver;
-+
-+ int len = 0;
-+
-+
-+ if(this->guarded_render) {
-+ lprintf("guarded_avcodec_decode_video2 enter\n");
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ //DO_LOCKDISPLAY;
-+ }
-+
-+ len = avcodec_decode_video2 (avctx, picture, got_picture_ptr, avpkt);
-+
-+ if(this->guarded_render) {
-+ //DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+ lprintf("guarded_avcodec_decode_video2 exit\n");
-+ }
-+
-+
-+ return len;
-+}
-+#else
-+static int guarded_avcodec_decode_video(vo_frame_t *frame_gen, AVCodecContext *avctx, AVFrame *picture,
-+ int *got_picture_ptr, uint8_t *buf, int buf_size) {
-+
-+ vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver;
-+
-+ int len = 0;
-+
-+
-+ if(this->guarded_render) {
-+ lprintf("guarded_avcodec_decode_video enter\n");
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ //DO_LOCKDISPLAY;
-+ }
-+
-+ len = avcodec_decode_video (avctx, picture, got_picture_ptr, buf, buf_size);
-+
-+ if(this->guarded_render) {
-+ //DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+ lprintf("guarded_avcodec_decode_video exit\n");
-+ }
-+
-+
-+ return len;
-+}
-+#endif
-+
-+static int guarded_render(vo_frame_t *frame_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver;
-+
-+ return this->guarded_render;
-+}
-+
-+static ff_vaapi_surface_t *get_vaapi_surface(vo_frame_t *frame_gen) {
-+
-+ vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver;
-+ vaapi_frame_t *frame = (vaapi_frame_t *) frame_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ ff_vaapi_surface_t *va_surface = NULL;
-+ VAStatus vaStatus;
-+
-+ lprintf("get_vaapi_surface\n");
-+
-+ if(!va_render_surfaces)
-+ return NULL;
-+
-+ if(this->guarded_render) {
-+ /* Get next VAAPI surface marked as SURFACE_FREE */
-+ for(;;) {
-+ int old_head = va_context->va_head;
-+ va_context->va_head = (va_context->va_head + 1) % ((RENDER_SURFACES));
-+
-+ va_surface = &va_render_surfaces[old_head];
-+
-+ if( va_surface->status == SURFACE_FREE ) {
-+
-+ VASurfaceStatus surf_status = 0;
-+
-+ if(this->query_va_status) {
-+ vaStatus = vaQuerySurfaceStatus(va_context->va_display, va_surface->va_surface_id, &surf_status);
-+ vaapi_check_status(va_context->driver, vaStatus, "vaQuerySurfaceStatus()");
-+ } else {
-+ surf_status = VASurfaceReady;
-+ }
-+
-+ if(surf_status == VASurfaceReady) {
-+
-+ va_surface->status = SURFACE_ALOC;
-+
-+#ifdef DEBUG_SURFACE
-+ printf("get_vaapi_surface 0x%08x\n", va_surface->va_surface_id);
-+#endif
-+
-+ return &va_render_surfaces[old_head];
-+ } else {
-+#ifdef DEBUG_SURFACE
-+ printf("get_vaapi_surface busy\n");
-+#endif
-+ }
-+ }
-+#ifdef DEBUG_SURFACE
-+ printf("get_vaapi_surface miss\n");
-+#endif
-+ }
-+ } else {
-+ va_surface = &va_render_surfaces[frame->vaapi_accel_data.index];
-+ }
-+
-+ return va_surface;
-+}
-+
-+/* Set VAAPI surface status to render */
-+static void render_vaapi_surface(vo_frame_t *frame_gen, ff_vaapi_surface_t *va_surface) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver;
-+ vaapi_accel_t *accel = (vaapi_accel_t*)frame_gen->accel_data;
-+
-+ lprintf("render_vaapi_surface\n");
-+
-+ if(!this->guarded_render || !accel || !va_surface)
-+ return;
-+
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ //DO_LOCKDISPLAY;
-+
-+ accel->index = va_surface->index;
-+
-+ va_surface->status = SURFACE_RENDER;
-+#ifdef DEBUG_SURFACE
-+ printf("render_vaapi_surface 0x%08x\n", va_surface->va_surface_id);
-+#endif
-+
-+ //DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+}
-+
-+/* Set VAAPI surface status to free */
-+static void release_vaapi_surface(vo_frame_t *frame_gen, ff_vaapi_surface_t *va_surface) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver;
-+
-+ lprintf("release_vaapi_surface\n");
-+
-+ if(va_surface == NULL || !this->guarded_render) {
-+ return;
-+ }
-+
-+ if(va_surface->status == SURFACE_RENDER) {
-+ va_surface->status = SURFACE_RENDER_RELEASE;
-+ } else if (va_surface->status != SURFACE_RENDER_RELEASE) {
-+ va_surface->status = SURFACE_FREE;
-+#ifdef DEBUG_SURFACE
-+ printf("release_surface 0x%08x\n", va_surface->va_surface_id);
-+#endif
-+ }
-+}
-+
-+static VADisplay vaapi_get_display(Display *display, int opengl_render)
-+{
-+ VADisplay ret;
-+
-+ if(opengl_render) {
-+ ret = vaGetDisplayGLX(display);
-+ } else {
-+ ret = vaGetDisplay(display);
-+ }
-+
-+ if(vaDisplayIsValid(ret))
-+ return ret;
-+ else
-+ return 0;
-+}
-+
-+typedef struct {
-+ void *funcptr;
-+ const char *extstr;
-+ const char *funcnames[7];
-+ void *fallback;
-+} extfunc_desc_t;
-+
-+#define DEF_FUNC_DESC(name) {&mpgl##name, NULL, {"gl"#name, NULL}, gl ##name}
-+static const extfunc_desc_t extfuncs[] = {
-+ DEF_FUNC_DESC(GenTextures),
-+
-+ {&mpglBindTexture, NULL, {"glBindTexture", "glBindTextureARB", "glBindTextureEXT", 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}},
-+ {&mpglGenPrograms, "_program", {"glGenProgramsARB", NULL}},
-+ {NULL}
-+};
-+
-+typedef struct {
-+ video_driver_class_t driver_class;
-+
-+ config_values_t *config;
-+ xine_t *xine;
-+} vaapi_class_t;
-+
-+static int gl_visual_attr[] = {
-+ GLX_RGBA,
-+ GLX_RED_SIZE, 1,
-+ GLX_GREEN_SIZE, 1,
-+ GLX_BLUE_SIZE, 1,
-+ GLX_DOUBLEBUFFER,
-+ GL_NONE
-+};
-+
-+static void delay_usec(unsigned int usec)
-+{
-+ int was_error;
-+
-+#if defined(USE_NANOSLEEP)
-+ struct timespec elapsed, tv;
-+#elif defined(USE_COND_TIMEDWAIT)
-+ // Use a local mutex and cv, so threads remain independent
-+ pthread_cond_t delay_cond = PTHREAD_COND_INITIALIZER;
-+ pthread_mutex_t delay_mutex = PTHREAD_MUTEX_INITIALIZER;
-+ struct timespec elapsed;
-+ uint64_t future;
-+#else
-+ struct timeval tv;
-+#ifndef SELECT_SETS_REMAINING
-+ uint64_t then, now, elapsed;
-+#endif
-+#endif
-+
-+ // Set the timeout interval - Linux only needs to do this once
-+#if defined(SELECT_SETS_REMAINING)
-+ tv.tv_sec = 0;
-+ tv.tv_usec = usec;
-+#elif defined(USE_NANOSLEEP)
-+ elapsed.tv_sec = 0;
-+ elapsed.tv_nsec = usec * 1000;
-+#elif defined(USE_COND_TIMEDWAIT)
-+ future = get_ticks_usec() + usec;
-+ elapsed.tv_sec = future / 1000000;
-+ elapsed.tv_nsec = (future % 1000000) * 1000;
-+#else
-+ then = get_ticks_usec();
-+#endif
-+
-+ do {
-+ errno = 0;
-+#if defined(USE_NANOSLEEP)
-+ tv.tv_sec = elapsed.tv_sec;
-+ tv.tv_nsec = elapsed.tv_nsec;
-+ was_error = nanosleep(&tv, &elapsed);
-+#elif defined(USE_COND_TIMEDWAIT)
-+ was_error = pthread_mutex_lock(&delay_mutex);
-+ was_error = pthread_cond_timedwait(&delay_cond, &delay_mutex, &elapsed);
-+ was_error = pthread_mutex_unlock(&delay_mutex);
-+#else
-+#ifndef SELECT_SETS_REMAINING
-+ // Calculate the time interval left (in case of interrupt)
-+ now = get_ticks_usec();
-+ elapsed = now - then;
-+ then = now;
-+ if (elapsed >= usec)
-+ break;
-+ usec -= elapsed;
-+ tv.tv_sec = 0;
-+ tv.tv_usec = usec;
-+#endif
-+ was_error = select(0, NULL, NULL, NULL, &tv);
-+#endif
-+ } while (was_error && (errno == EINTR));
-+}
-+
-+static void vaapi_x11_wait_event(Display *dpy, Window w, int type)
-+{
-+ XEvent e;
-+ while (!XCheckTypedWindowEvent(dpy, w, type, &e))
-+ delay_usec(10);
-+}
-+
-+/* X11 Error handler and error functions */
-+static int vaapi_x11_error_code = 0;
-+static int (*vaapi_x11_old_error_handler)(Display *, XErrorEvent *);
-+
-+static int vaapi_x11_error_handler(Display *dpy, XErrorEvent *error)
-+{
-+ vaapi_x11_error_code = error->error_code;
-+ return 0;
-+}
-+
-+static void vaapi_x11_trap_errors(void)
-+{
-+ vaapi_x11_error_code = 0;
-+ vaapi_x11_old_error_handler = XSetErrorHandler(vaapi_x11_error_handler);
-+}
-+
-+static int vaapi_x11_untrap_errors(void)
-+{
-+ XSetErrorHandler(vaapi_x11_old_error_handler);
-+ return vaapi_x11_error_code;
-+}
-+
-+static void vaapi_appendstr(char **dst, const char *str)
-+{
-+ int newsize;
-+ char *newstr;
-+ if (!str)
-+ return;
-+ newsize = strlen(*dst) + 1 + strlen(str) + 1;
-+ newstr = realloc(*dst, newsize);
-+ if (!newstr)
-+ return;
-+ *dst = newstr;
-+ strcat(*dst, " ");
-+ strcat(*dst, str);
-+}
-+
-+/* Return the address of a linked function */
-+static void *vaapi_getdladdr (const char *s) {
-+ void *ret = NULL;
-+ void *handle = dlopen(NULL, RTLD_LAZY);
-+ if (!handle)
-+ return NULL;
-+ ret = dlsym(handle, s);
-+ dlclose(handle);
-+
-+ return ret;
-+}
-+
-+/* Resolve opengl functions. */
-+static void vaapi_get_functions(vo_driver_t *this_gen, void *(*getProcAddress)(const GLubyte *),
-+ const char *ext2) {
-+ const extfunc_desc_t *dsc;
-+ const char *extensions;
-+ char *allexts;
-+
-+ if (!getProcAddress)
-+ getProcAddress = (void *)vaapi_getdladdr;
-+
-+ /* special case, we need glGetString before starting to find the other functions */
-+ mpglGetString = getProcAddress("glGetString");
-+ if (!mpglGetString)
-+ mpglGetString = glGetString;
-+
-+ extensions = (const char *)mpglGetString(GL_EXTENSIONS);
-+ if (!extensions) extensions = "";
-+ if (!ext2) ext2 = "";
-+ allexts = malloc(strlen(extensions) + strlen(ext2) + 2);
-+ strcpy(allexts, extensions);
-+ strcat(allexts, " ");
-+ strcat(allexts, ext2);
-+ lprintf("vaapi_get_functions: OpenGL extensions string:\n%s\n", allexts);
-+ for (dsc = extfuncs; dsc->funcptr; dsc++) {
-+ void *ptr = NULL;
-+ int i;
-+ if (!dsc->extstr || strstr(allexts, dsc->extstr)) {
-+ for (i = 0; !ptr && dsc->funcnames[i]; i++)
-+ ptr = getProcAddress((const GLubyte *)dsc->funcnames[i]);
-+ }
-+ if (!ptr)
-+ ptr = dsc->fallback;
-+ *(void **)dsc->funcptr = ptr;
-+ }
-+ lprintf("\n");
-+ free(allexts);
-+}
-+
-+/* Check if opengl indirect/software rendering is used */
-+static int vaapi_opengl_verify_direct (x11_visual_t *vis) {
-+ Window root, win;
-+ XVisualInfo *visinfo;
-+ GLXContext ctx;
-+ XSetWindowAttributes xattr;
-+ int ret = 0;
-+
-+ if (!vis || !vis->display || ! (root = RootWindow (vis->display, vis->screen))) {
-+ lprintf ("vaapi_opengl_verify_direct: Don't have a root window to verify\n");
-+ return 0;
-+ }
-+
-+ if (! (visinfo = glXChooseVisual (vis->display, vis->screen, gl_visual_attr)))
-+ return 0;
-+
-+ if (! (ctx = glXCreateContext (vis->display, visinfo, NULL, 1)))
-+ return 0;
-+
-+ memset (&xattr, 0, sizeof (xattr));
-+ xattr.colormap = XCreateColormap(vis->display, root, visinfo->visual, AllocNone);
-+ xattr.event_mask = StructureNotifyMask | ExposureMask;
-+
-+ if ( (win = XCreateWindow (vis->display, root, 0, 0, 1, 1, 0, visinfo->depth,
-+ InputOutput, visinfo->visual,
-+ CWBackPixel | CWBorderPixel | CWColormap | CWEventMask,
-+ &xattr))) {
-+ if (glXMakeCurrent (vis->display, win, ctx)) {
-+ const char *renderer = (const char *) glGetString(GL_RENDERER);
-+ if (glXIsDirect (vis->display, ctx) &&
-+ ! strstr (renderer, "Software") &&
-+ ! strstr (renderer, "Indirect"))
-+ ret = 1;
-+ glXMakeCurrent (vis->display, None, NULL);
-+ }
-+ XDestroyWindow (vis->display, win);
-+ }
-+ glXDestroyContext (vis->display, ctx);
-+ XFreeColormap (vis->display, xattr.colormap);
-+
-+ return ret;
-+}
-+
-+static int vaapi_glx_bind_texture(vo_driver_t *this_gen)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ glEnable(GL_TEXTURE_2D);
-+ mpglBindTexture(GL_TEXTURE_2D, this->gl_texture);
-+
-+ if (this->opengl_use_tfp) {
-+ vaapi_x11_trap_errors();
-+ mpglXBindTexImage(this->display, this->gl_pixmap, GLX_FRONT_LEFT_EXT, NULL);
-+ XSync(this->display, False);
-+ if (vaapi_x11_untrap_errors())
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_bind_texture : Update bind_tex_image failed\n");
-+ }
-+
-+ return 0;
-+}
-+
-+static int vaapi_glx_unbind_texture(vo_driver_t *this_gen)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ if (this->opengl_use_tfp) {
-+ vaapi_x11_trap_errors();
-+ mpglXReleaseTexImage(this->display, this->gl_pixmap, GLX_FRONT_LEFT_EXT);
-+ if (vaapi_x11_untrap_errors())
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_unbind_texture : Failed to release?\n");
-+ }
-+
-+ mpglBindTexture(GL_TEXTURE_2D, 0);
-+ glDisable(GL_TEXTURE_2D);
-+ return 0;
-+}
-+
-+static void vaapi_glx_render_frame(vo_frame_t *frame_gen, int left, int top, int right, int bottom)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver;
-+ vaapi_frame_t *frame = (vaapi_frame_t *) frame_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ int x1, x2, y1, y2;
-+ float tx, ty;
-+
-+ if (vaapi_glx_bind_texture(frame_gen->driver) < 0)
-+ return;
-+
-+ /* Calc texture/rectangle coords */
-+ x1 = this->sc.output_xoffset;
-+ y1 = this->sc.output_yoffset;
-+ x2 = x1 + this->sc.output_width;
-+ y2 = y1 + this->sc.output_height;
-+ tx = (float) frame->width / va_context->width;
-+ ty = (float) frame->height / va_context->height;
-+
-+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-+ /* Draw quad */
-+ glBegin (GL_QUADS);
-+
-+ glTexCoord2f (tx, ty); glVertex2i (x2, y2);
-+ glTexCoord2f (0, ty); glVertex2i (x1, y2);
-+ glTexCoord2f (0, 0); glVertex2i (x1, y1);
-+ glTexCoord2f (tx, 0); glVertex2i (x2, y1);
-+ lprintf("render_frame left %d top %d right %d bottom %d\n", x1, y1, x2, y2);
-+
-+ glEnd ();
-+
-+ if (vaapi_glx_unbind_texture(frame_gen->driver) < 0)
-+ return;
-+}
-+
-+static void vaapi_glx_flip_page(vo_frame_t *frame_gen, int left, int top, int right, int bottom)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver;
-+
-+ glClear(GL_COLOR_BUFFER_BIT);
-+
-+ vaapi_glx_render_frame(frame_gen, left, top, right, bottom);
-+
-+ //if (gl_finish)
-+ // glFinish();
-+
-+ glXSwapBuffers(this->display, this->window);
-+
-+}
-+
-+static void destroy_glx(vo_driver_t *this_gen)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ if(!this->opengl_render || !va_context->valid_context)
-+ return;
-+
-+ //if (gl_finish)
-+ // glFinish();
-+
-+ if(va_context->gl_surface) {
-+ VAStatus vaStatus = vaDestroySurfaceGLX(va_context->va_display, va_context->gl_surface);
-+ vaapi_check_status(this_gen, vaStatus, "vaDestroySurfaceGLX()");
-+ va_context->gl_surface = NULL;
-+ }
-+
-+ if(this->gl_context)
-+ glXMakeCurrent(this->display, None, NULL);
-+
-+ if(this->gl_pixmap) {
-+ vaapi_x11_trap_errors();
-+ mpglXDestroyPixmap(this->display, this->gl_pixmap);
-+ XSync(this->display, False);
-+ vaapi_x11_untrap_errors();
-+ this->gl_pixmap = None;
-+ }
-+
-+ if(this->gl_image_pixmap) {
-+ XFreePixmap(this->display, this->gl_image_pixmap);
-+ this->gl_image_pixmap = None;
-+ }
-+
-+ if(this->gl_texture) {
-+ glDeleteTextures(1, &this->gl_texture);
-+ this->gl_texture = GL_NONE;
-+ }
-+
-+ if(this->gl_context) {
-+ glXDestroyContext(this->display, this->gl_context);
-+ this->gl_context = 0;
-+ }
-+
-+ if(this->gl_vinfo) {
-+ XFree(this->gl_vinfo);
-+ this->gl_vinfo = NULL;
-+ }
-+
-+ this->valid_opengl_context = 0;
-+}
-+
-+static GLXFBConfig *get_fbconfig_for_depth(vo_driver_t *this_gen, int depth)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ GLXFBConfig *fbconfigs, *ret = NULL;
-+ int n_elements, i, found;
-+ int db, stencil, alpha, rgba, value;
-+
-+ static GLXFBConfig *cached_config = NULL;
-+ static int have_cached_config = 0;
-+
-+ if (have_cached_config)
-+ return cached_config;
-+
-+ fbconfigs = glXGetFBConfigs(this->display, this->screen, &n_elements);
-+
-+ db = SHRT_MAX;
-+ stencil = SHRT_MAX;
-+ rgba = 0;
-+
-+ found = n_elements;
-+
-+ for (i = 0; i < n_elements; i++) {
-+ XVisualInfo *vi;
-+ int visual_depth;
-+
-+ vi = glXGetVisualFromFBConfig(this->display, fbconfigs[i]);
-+ if (!vi)
-+ continue;
-+
-+ visual_depth = vi->depth;
-+ XFree(vi);
-+
-+ if (visual_depth != depth)
-+ continue;
-+
-+ glXGetFBConfigAttrib(this->display, fbconfigs[i], GLX_ALPHA_SIZE, &alpha);
-+ glXGetFBConfigAttrib(this->display, fbconfigs[i], GLX_BUFFER_SIZE, &value);
-+ if (value != depth && (value - alpha) != depth)
-+ continue;
-+
-+ value = 0;
-+ if (depth == 32) {
-+ glXGetFBConfigAttrib(this->display, fbconfigs[i],
-+ GLX_BIND_TO_TEXTURE_RGBA_EXT, &value);
-+ if (value)
-+ rgba = 1;
-+ }
-+
-+ if (!value) {
-+ if (rgba)
-+ continue;
-+
-+ glXGetFBConfigAttrib(this->display, fbconfigs[i],
-+ GLX_BIND_TO_TEXTURE_RGB_EXT, &value);
-+ if (!value)
-+ continue;
-+ }
-+
-+ glXGetFBConfigAttrib(this->display, fbconfigs[i], GLX_DOUBLEBUFFER, &value);
-+ if (value > db)
-+ continue;
-+ db = value;
-+
-+ glXGetFBConfigAttrib(this->display, 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 vaapi_glx_config_tfp(vo_driver_t *this_gen, unsigned int width, unsigned int height)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ GLXFBConfig *fbconfig;
-+ int attribs[7], i = 0;
-+ const int depth = 24;
-+
-+ if (!mpglXBindTexImage || !mpglXReleaseTexImage) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : No GLX texture-from-pixmap extension available\n");
-+ return 0;
-+ }
-+
-+ if (depth != 24 && depth != 32) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : color depth wrong.\n");
-+ return 0;
-+ }
-+
-+ this->gl_image_pixmap = XCreatePixmap(this->display, this->window, width, height, depth);
-+ if (!this->gl_image_pixmap) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : Could not create X11 pixmap\n");
-+ return 0;
-+ }
-+
-+ fbconfig = get_fbconfig_for_depth(this_gen, depth);
-+ if (!fbconfig) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : Could not find an FBConfig for 32-bit pixmap\n");
-+ return 0;
-+ }
-+
-+ 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;
-+
-+ vaapi_x11_trap_errors();
-+ this->gl_pixmap = mpglXCreatePixmap(this->display, *fbconfig, this->gl_image_pixmap, attribs);
-+ XSync(this->display, False);
-+ if (vaapi_x11_untrap_errors()) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : Could not create GLX pixmap\n");
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static int vaapi_glx_config_glx(vo_driver_t *this_gen, unsigned int width, unsigned int height)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ this->gl_vinfo = glXChooseVisual(this->display, this->screen, gl_visual_attr);
-+ if(!this->gl_vinfo) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : error glXChooseVisual\n");
-+ this->opengl_render = 0;
-+ }
-+
-+ glXMakeCurrent(this->display, None, NULL);
-+ this->gl_context = glXCreateContext (this->display, this->gl_vinfo, NULL, True);
-+ if (this->gl_context) {
-+ if(!glXMakeCurrent (this->display, this->window, this->gl_context)) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : error glXMakeCurrent\n");
-+ goto error;
-+ }
-+ } else {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : error glXCreateContext\n");
-+ goto error;
-+ }
-+
-+ void *(*getProcAddress)(const GLubyte *);
-+ const char *(*glXExtStr)(Display *, int);
-+ char *glxstr = strdup(" ");
-+
-+ getProcAddress = vaapi_getdladdr("glXGetProcAddress");
-+ if (!getProcAddress)
-+ getProcAddress = vaapi_getdladdr("glXGetProcAddressARB");
-+ glXExtStr = vaapi_getdladdr("glXQueryExtensionsString");
-+ if (glXExtStr)
-+ vaapi_appendstr(&glxstr, glXExtStr(this->display, this->screen));
-+ glXExtStr = vaapi_getdladdr("glXGetClientString");
-+ if (glXExtStr)
-+ vaapi_appendstr(&glxstr, glXExtStr(this->display, GLX_EXTENSIONS));
-+ glXExtStr = vaapi_getdladdr("glXGetServerString");
-+ if (glXExtStr)
-+ vaapi_appendstr(&glxstr, glXExtStr(this->display, GLX_EXTENSIONS));
-+
-+ vaapi_get_functions(this_gen, getProcAddress, glxstr);
-+ if (!mpglGenPrograms && mpglGetString &&
-+ getProcAddress &&
-+ strstr(mpglGetString(GL_EXTENSIONS), "GL_ARB_vertex_program")) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : Broken glXGetProcAddress detected, trying workaround\n");
-+ vaapi_get_functions(this_gen, NULL, glxstr);
-+ }
-+ free(glxstr);
-+
-+ glDisable(GL_DEPTH_TEST);
-+ glDepthMask(GL_FALSE);
-+ glDisable(GL_CULL_FACE);
-+ glEnable(GL_TEXTURE_2D);
-+ glDrawBuffer(GL_BACK);
-+ 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(this->opengl_use_tfp && vaapi_glx_config_tfp(this_gen, width, height)) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : Using GLX texture-from-pixmap extension\n");
-+ } else {
-+ this->opengl_use_tfp = 0;
-+ }
-+
-+ /* Create OpenGL texture */
-+ /* XXX: assume GL_ARB_texture_non_power_of_two is available */
-+ glEnable(GL_TEXTURE_2D);
-+ glGenTextures(1, &this->gl_texture);
-+ mpglBindTexture(GL_TEXTURE_2D, this->gl_texture);
-+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-+ if (!this->opengl_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(!this->gl_texture) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : gl_texture NULL\n");
-+ goto error;
-+ }
-+
-+ if(!this->opengl_use_tfp) {
-+ VAStatus vaStatus = vaCreateSurfaceGLX(va_context->va_display, GL_TEXTURE_2D, this->gl_texture, &va_context->gl_surface);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaCreateSurfaceGLX()")) {
-+ va_context->gl_surface = NULL;
-+ goto error;
-+ }
-+ } else {
-+ va_context->gl_surface = NULL;
-+ }
-+
-+ lprintf("vaapi_glx_config_glx : GL setup done\n");
-+
-+ this->valid_opengl_context = 1;
-+ return 1;
-+
-+error:
-+ destroy_glx(this_gen);
-+ this->valid_opengl_context = 0;
-+ return 0;
-+}
-+
-+static uint32_t vaapi_get_capabilities (vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ return this->capabilities;
-+}
-+
-+static const struct {
-+ int fmt;
-+ enum PixelFormat pix_fmt;
-+ enum CodecID codec_id;
-+} conversion_map[] = {
-+ {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},
-+ {0, PIX_FMT_NONE}
-+};
-+
-+static int vaapi_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 &&
-+ (conversion_map[i].codec_id == 0 ||
-+ conversion_map[i].codec_id == codec_id)) {
-+ break;
-+ }
-+ }
-+ fmt = conversion_map[i].fmt;
-+ return fmt;
-+}
-+
-+static int vaapi_has_profile(VAProfile *va_profiles, int va_num_profiles, 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 profile_from_imgfmt(vo_frame_t *frame_gen, enum PixelFormat pix_fmt, int codec_id, int vaapi_mpeg_sofdec)
-+{
-+ vo_driver_t *this_gen = (vo_driver_t *) frame_gen->driver;
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAStatus vaStatus;
-+ int profile = -1;
-+ int maj, min;
-+ int i;
-+ int va_num_profiles;
-+ int max_profiles;
-+ VAProfile *va_profiles = NULL;
-+ int inited = 0;
-+
-+ if(va_context->va_display == NULL) {
-+ lprintf("profile_from_imgfmt vaInitialize\n");
-+ inited = 1;
-+ va_context->va_display = vaapi_get_display(this->display, this->opengl_render);
-+ if(!va_context->va_display)
-+ goto out;
-+
-+ vaStatus = vaInitialize(va_context->va_display, &maj, &min);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaInitialize()"))
-+ goto out;
-+
-+ }
-+
-+ max_profiles = vaMaxNumProfiles(va_context->va_display);
-+ va_profiles = calloc(max_profiles, sizeof(*va_profiles));
-+ if (!va_profiles)
-+ goto out;
-+
-+ vaStatus = vaQueryConfigProfiles(va_context->va_display, va_profiles, &va_num_profiles);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaQueryConfigProfiles()"))
-+ goto out;
-+
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " VAAPI Supported Profiles : ");
-+ for (i = 0; i < va_num_profiles; i++) {
-+ printf("%s ", vaapi_profile_to_string(va_profiles[i]));
-+ }
-+ printf("\n");
-+
-+ uint32_t format = vaapi_pixfmt2imgfmt(pix_fmt, codec_id);
-+
-+ 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:
-+ if(!vaapi_mpeg_sofdec) {
-+ 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) {
-+ int i;
-+ for (i = 0; profiles[i] != -1; i++) {
-+ if (vaapi_has_profile(va_profiles, va_num_profiles, profiles[i])) {
-+ profile = profiles[i];
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " VAAPI Profile %s supported by your hardware\n", vaapi_profile_to_string(profiles[i]));
-+ break;
-+ }
-+ }
-+ }
-+
-+out:
-+ if(va_profiles)
-+ free(va_profiles);
-+ if(inited) {
-+ vaStatus = vaTerminate(va_context->va_display);
-+ vaapi_check_status(this_gen, vaStatus, "vaTerminate()");
-+ }
-+ return profile;
-+}
-+
-+
-+static const char *vaapi_profile_to_string(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 *vaapi_entrypoint_to_string(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>";
-+}
-+
-+/* Init subpicture */
-+static void vaapi_init_subpicture(vaapi_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ va_context->va_subpic_width = 0;
-+ va_context->va_subpic_height = 0;
-+ va_context->va_subpic_id = VA_INVALID_ID;
-+ va_context->va_subpic_image.image_id = VA_INVALID_ID;
-+
-+ this->overlay_output_width = this->overlay_output_height = 0;
-+ this->overlay_unscaled_width = this->overlay_unscaled_height = 0;
-+ this->ovl_changed = 0;
-+ this->has_overlay = 0;
-+ this->overlay_bitmap = NULL;
-+ this->overlay_bitmap_size = 0;
-+
-+}
-+
-+/* Init vaapi context */
-+static void vaapi_init_va_context(vaapi_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ int i;
-+
-+ va_context->va_config_id = VA_INVALID_ID;
-+ va_context->va_context_id = VA_INVALID_ID;
-+ va_context->va_profile = 0;
-+ va_context->va_colorspace = 1;
-+ va_context->is_bound = 0;
-+ va_context->gl_surface = NULL;
-+ va_context->soft_head = 0;
-+ va_context->valid_context = 0;
-+ va_context->va_head = 0;
-+ va_context->va_soft_head = 0;
-+
-+ for(i = 0; i < RENDER_SURFACES; i++) {
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[i];
-+
-+ va_surface->index = i;
-+ va_surface->status = SURFACE_FREE;
-+ va_surface->va_surface_id = VA_INVALID_SURFACE;
-+
-+ va_surface_ids[i] = VA_INVALID_SURFACE;
-+ }
-+
-+ for(i = 0; i < SOFT_SURFACES; i++) {
-+ va_soft_surface_ids[i] = VA_INVALID_SURFACE;
-+ va_soft_images[i].image_id = VA_INVALID_ID;
-+ }
-+
-+ va_context->va_image_formats = NULL;
-+ va_context->va_num_image_formats = 0;
-+
-+ va_context->va_subpic_formats = NULL;
-+ va_context->va_num_subpic_formats = 0;
-+}
-+
-+/* Close vaapi */
-+static void vaapi_close(vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAStatus vaStatus;
-+
-+ if(!va_context || !va_context->va_display || !va_context->valid_context)
-+ return;
-+
-+ vaapi_ovl_associate(this_gen, 0, 0);
-+
-+ destroy_glx((vo_driver_t *)this);
-+
-+ if(va_context->va_context_id != VA_INVALID_ID) {
-+ vaStatus = vaDestroyContext(va_context->va_display, va_context->va_context_id);
-+ vaapi_check_status(this_gen, vaStatus, "vaDestroyContext()");
-+ va_context->va_context_id = VA_INVALID_ID;
-+ }
-+
-+ vaapi_destroy_subpicture(this_gen);
-+ vaapi_destroy_soft_surfaces(this_gen);
-+ vaapi_destroy_render_surfaces(this_gen);
-+
-+ if(va_context->va_config_id != VA_INVALID_ID) {
-+ vaStatus = vaDestroyConfig(va_context->va_display, va_context->va_config_id);
-+ vaapi_check_status(this_gen, vaStatus, "vaDestroyConfig()");
-+ va_context->va_config_id = VA_INVALID_ID;
-+ }
-+
-+ vaStatus = vaTerminate(va_context->va_display);
-+ vaapi_check_status(this_gen, vaStatus, "vaTerminate()");
-+ va_context->va_display = NULL;
-+
-+ if(va_context->va_image_formats) {
-+ free(va_context->va_image_formats);
-+ va_context->va_image_formats = NULL;
-+ va_context->va_num_image_formats = 0;
-+ }
-+ if(va_context->va_subpic_formats) {
-+ free(va_context->va_subpic_formats);
-+ va_context->va_subpic_formats = NULL;
-+ va_context->va_num_subpic_formats = 0;
-+ }
-+
-+ va_context->valid_context = 0;
-+}
-+
-+/* Returns internal VAAPI context */
-+static ff_vaapi_context_t *get_context(vo_frame_t *frame_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver;
-+
-+ return this->va_context;
-+}
-+
-+/* Free allocated VAAPI image */
-+static void vaapi_destroy_image(vo_driver_t *this_gen, VAImage *va_image) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAStatus vaStatus;
-+
-+ if(va_image->image_id != VA_INVALID_ID) {
-+ lprintf("vaapi_destroy_image 0x%08x\n", va_image->image_id);
-+ vaStatus = vaDestroyImage(va_context->va_display, va_image->image_id);
-+ vaapi_check_status(this_gen, vaStatus, "vaDestroyImage()");
-+ }
-+ va_image->image_id = VA_INVALID_ID;
-+ va_image->width = 0;
-+ va_image->height = 0;
-+}
-+
-+/* Allocated VAAPI image */
-+static VAStatus vaapi_create_image(vo_driver_t *this_gen, VASurfaceID va_surface_id, VAImage *va_image, int width, int height, int clear) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ int i = 0;
-+ VAStatus vaStatus;
-+
-+ if(!va_context->valid_context || va_context->va_image_formats == NULL || va_context->va_num_image_formats == 0)
-+ return VA_STATUS_ERROR_UNKNOWN;
-+
-+ va_context->is_bound = 0;
-+
-+ vaStatus = vaDeriveImage(va_context->va_display, va_surface_id, va_image);
-+ if(vaStatus == VA_STATUS_SUCCESS) {
-+ if (va_image->image_id != VA_INVALID_ID && va_image->buf != VA_INVALID_ID) {
-+ va_context->is_bound = 1;
-+ }
-+ }
-+
-+ if(!va_context->is_bound) {
-+ for (i = 0; i < va_context->va_num_image_formats; i++) {
-+ if (va_context->va_image_formats[i].fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) ||
-+ va_context->va_image_formats[i].fourcc == VA_FOURCC( 'I', '4', '2', '0' ) /*||
-+ va_context->va_image_formats[i].fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) */) {
-+ vaStatus = vaCreateImage( va_context->va_display, &va_context->va_image_formats[i], width, height, va_image );
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaCreateImage()"))
-+ goto error;
-+ break;
-+ }
-+ }
-+ }
-+
-+ void *p_base = NULL;
-+
-+ vaStatus = vaMapBuffer( va_context->va_display, va_image->buf, &p_base );
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaMapBuffer()"))
-+ goto error;
-+
-+ if(clear) {
-+ if(va_image->format.fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) ||
-+ va_image->format.fourcc == VA_FOURCC( 'I', '4', '2', '0' )) {
-+ memset((uint8_t*)p_base + va_image->offsets[0], 0, va_image->pitches[0] * va_image->height);
-+ memset((uint8_t*)p_base + va_image->offsets[1], 128, va_image->pitches[1] * (va_image->height/2));
-+ memset((uint8_t*)p_base + va_image->offsets[2], 128, va_image->pitches[2] * (va_image->height/2));
-+ } else if (va_image->format.fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) ) {
-+ memset((uint8_t*)p_base + va_image->offsets[0], 0, va_image->pitches[0] * va_image->height);
-+ memset((uint8_t*)p_base + va_image->offsets[1], 128, va_image->pitches[1] * (va_image->height/2));
-+ }
-+ }
-+
-+ vaStatus = vaUnmapBuffer( va_context->va_display, va_image->buf );
-+ vaapi_check_status(this_gen, vaStatus, "vaUnmapBuffer()");
-+
-+ lprintf("vaapi_create_image 0x%08x width %d height %d format %s\n", va_image->image_id, va_image->width, va_image->height,
-+ string_of_VAImageFormat(&va_image->format));
-+
-+ return VA_STATUS_SUCCESS;
-+
-+error:
-+ /* house keeping */
-+ vaapi_destroy_image(this_gen, va_image);
-+ return VA_STATUS_ERROR_UNKNOWN;
-+}
-+
-+/* Deassociate and free subpicture */
-+static void vaapi_destroy_subpicture(vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAStatus vaStatus;
-+
-+ lprintf("destroy sub 0x%08x 0x%08x 0x%08x\n", va_context->va_subpic_id,
-+ va_context->va_subpic_image.image_id, va_context->va_subpic_image.buf);
-+
-+ if(va_context->va_subpic_id != VA_INVALID_ID) {
-+ vaStatus = vaDestroySubpicture(va_context->va_display, va_context->va_subpic_id);
-+ vaapi_check_status(this_gen, vaStatus, "vaDeassociateSubpicture()");
-+ }
-+ va_context->va_subpic_id = VA_INVALID_ID;
-+
-+ vaapi_destroy_image(this_gen, &va_context->va_subpic_image);
-+
-+}
-+
-+/* Create VAAPI subpicture */
-+static VAStatus vaapi_create_subpicture(vo_driver_t *this_gen, int width, int height) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAStatus vaStatus;
-+
-+ int i = 0;
-+
-+ if(!va_context->valid_context || !va_context->va_subpic_formats || va_context->va_num_subpic_formats == 0)
-+ return VA_STATUS_ERROR_UNKNOWN;
-+
-+ for (i = 0; i < va_context->va_num_subpic_formats; i++) {
-+ if ( va_context->va_subpic_formats[i].fourcc == VA_FOURCC('B','G','R','A')) {
-+
-+ vaStatus = vaCreateImage( va_context->va_display, &va_context->va_subpic_formats[i], width, height, &va_context->va_subpic_image );
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaCreateImage()"))
-+ goto error;
-+
-+ vaStatus = vaCreateSubpicture(va_context->va_display, va_context->va_subpic_image.image_id, &va_context->va_subpic_id );
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaCreateSubpicture()"))
-+ goto error;
-+ }
-+ }
-+
-+ if(va_context->va_subpic_image.image_id == VA_INVALID_ID || va_context->va_subpic_id == VA_INVALID_ID)
-+ goto error;
-+
-+ void *p_base = NULL;
-+
-+ lprintf("create sub 0x%08x 0x%08x 0x%08x\n", va_context->va_subpic_id,
-+ va_context->va_subpic_image.image_id, va_context->va_subpic_image.buf);
-+
-+ vaStatus = vaMapBuffer(va_context->va_display, va_context->va_subpic_image.buf, &p_base);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaMapBuffer()"))
-+ goto error;
-+
-+ memset((uint32_t *)p_base, 0x0, va_context->va_subpic_image.data_size);
-+ vaStatus = vaUnmapBuffer(va_context->va_display, va_context->va_subpic_image.buf);
-+ vaapi_check_status(this_gen, vaStatus, "vaUnmapBuffer()");
-+
-+ this->overlay_output_width = width;
-+ this->overlay_output_height = height;
-+
-+ lprintf("vaapi_create_subpicture 0x%08x format %s\n", va_context->va_subpic_image.image_id,
-+ string_of_VAImageFormat(&va_context->va_subpic_image.format));
-+
-+ return VA_STATUS_SUCCESS;
-+
-+error:
-+ /* house keeping */
-+ if(va_context->va_subpic_id != VA_INVALID_ID)
-+ vaapi_destroy_subpicture(this_gen);
-+ va_context->va_subpic_id = VA_INVALID_ID;
-+
-+ vaapi_destroy_image(this_gen, &va_context->va_subpic_image);
-+
-+ this->overlay_output_width = 0;
-+ this->overlay_output_height = 0;
-+
-+ return VA_STATUS_ERROR_UNKNOWN;
-+}
-+
-+static inline int vaapi_get_colorspace_flags(vo_driver_t *this_gen)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ if(!va_context)
-+ return 0;
-+
-+ int colorspace = 0;
-+#if USE_VAAPI_COLORSPACE
-+ switch (va_context->va_colorspace) {
-+ case 0:
-+ colorspace = ((va_context->sw_width >= 1280 || va_context->sw_height > 576) ?
-+ VA_SRC_BT709 : VA_SRC_BT601);
-+ break;
-+ case 1:
-+ colorspace = VA_SRC_BT601;
-+ break;
-+ case 2:
-+ colorspace = VA_SRC_BT709;
-+ break;
-+ case 3:
-+ colorspace = VA_SRC_SMPTE_240;
-+ break;
-+ default:
-+ colorspace = VA_SRC_BT601;
-+ break;
-+ }
-+#endif
-+ return colorspace;
-+}
-+
-+static void vaapi_property_callback (void *property_gen, xine_cfg_entry_t *entry) {
-+ va_property_t *property = (va_property_t *) property_gen;
-+ vaapi_driver_t *this = property->this;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+
-+ VADisplayAttribute attr;
-+
-+ attr.type = property->type;
-+ attr.value = entry->num_value;
-+
-+ lprintf("vaapi_property_callback property=%d, value=%d\n", property->type, entry->num_value );
-+
-+ VAStatus vaStatus = vaSetDisplayAttributes(va_context->va_display, &attr, 1);
-+ //vaapi_check_status((vo_driver_t *)this, vaStatus, "vaSetDisplayAttributes()");
-+
-+ vaapi_show_display_props((vo_driver_t*)this);
-+
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+}
-+
-+/* called xlocked */
-+static void vaapi_check_capability (vaapi_driver_t *this,
-+ int property, VADisplayAttribute attr,
-+ const char *config_name,
-+ const char *config_desc,
-+ const char *config_help) {
-+ int int_default = 0;
-+ cfg_entry_t *entry;
-+
-+ this->props[property].type = attr.type;
-+ this->props[property].min = attr.min_value;
-+ this->props[property].max = attr.max_value;
-+ int_default = attr.value;
-+ this->props[property].atom = 1;
-+
-+ if (config_name) {
-+ /* is this a boolean property ? */
-+ if ((attr.min_value == 0) && (attr.max_value == 1)) {
-+ this->config->register_bool (this->config, config_name, int_default,
-+ config_desc,
-+ config_help, 20, vaapi_property_callback, &this->props[property]);
-+
-+ } else {
-+ this->config->register_range (this->config, config_name, int_default,
-+ this->props[property].min, this->props[property].max,
-+ config_desc,
-+ config_help, 20, vaapi_property_callback, &this->props[property]);
-+ }
-+
-+ entry = this->config->lookup_entry (this->config, config_name);
-+ if((entry->num_value < this->props[property].min) ||
-+ (entry->num_value > this->props[property].max)) {
-+
-+ this->config->update_num(this->config, config_name,
-+ ((this->props[property].min + this->props[property].max) >> 1));
-+
-+ entry = this->config->lookup_entry (this->config, config_name);
-+ }
-+
-+ this->props[property].entry = entry;
-+
-+ vaapi_set_property(&this->vo_driver, property, entry->num_value);
-+ } else {
-+ this->props[property].value = int_default;
-+ }
-+}
-+
-+static void vaapi_show_display_props(vo_driver_t *this_gen) {
-+ /*
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ if(this->capabilities & VO_CAP_BRIGHTNESS)
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : brightness : %d\n", this->props[VO_PROP_BRIGHTNESS].value);
-+ if(this->capabilities & VO_CAP_CONTRAST)
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : contrast : %d\n", this->props[VO_PROP_CONTRAST].value);
-+ if(this->capabilities & VO_CAP_HUE)
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : hue : %d\n", this->props[VO_PROP_HUE].value);
-+ if(this->capabilities & VO_CAP_SATURATION)
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : saturation : %d\n", this->props[VO_PROP_SATURATION].value);
-+ */
-+}
-+
-+/* VAAPI display attributes. */
-+static void vaapi_display_attribs(vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ int num_display_attrs, max_display_attrs;
-+ VAStatus vaStatus;
-+ VADisplayAttribute *display_attrs;
-+ int i;
-+
-+ max_display_attrs = vaMaxNumDisplayAttributes(va_context->va_display);
-+ display_attrs = calloc(max_display_attrs, sizeof(*display_attrs));
-+
-+ if (display_attrs) {
-+ num_display_attrs = 0;
-+ vaStatus = vaQueryDisplayAttributes(va_context->va_display,
-+ display_attrs, &num_display_attrs);
-+ if(vaapi_check_status(this_gen, vaStatus, "vaQueryDisplayAttributes()")) {
-+ for (i = 0; i < num_display_attrs; i++) {
-+ switch (display_attrs[i].type) {
-+ case VADisplayAttribBrightness:
-+ if( ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_GETTABLE ) &&
-+ ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE ) ) {
-+ this->capabilities |= VO_CAP_BRIGHTNESS;
-+ vaapi_check_capability(this, VO_PROP_BRIGHTNESS, display_attrs[i], "video.output.vaapi_brightness", "Brightness setting", "Brightness setting");
-+ }
-+ break;
-+ case VADisplayAttribContrast:
-+ if( ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_GETTABLE ) &&
-+ ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE ) ) {
-+ this->capabilities |= VO_CAP_CONTRAST;
-+ vaapi_check_capability(this, VO_PROP_CONTRAST, display_attrs[i], "video.output.vaapi_contrast", "Contrast setting", "Contrast setting");
-+ }
-+ break;
-+ case VADisplayAttribHue:
-+ if( ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_GETTABLE ) &&
-+ ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE ) ) {
-+ this->capabilities |= VO_CAP_HUE;
-+ vaapi_check_capability(this, VO_PROP_HUE, display_attrs[i], "video.output.vaapi_hue", "Hue setting", "Hue setting");
-+ }
-+ break;
-+ case VADisplayAttribSaturation:
-+ if( ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_GETTABLE ) &&
-+ ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE ) ) {
-+ this->capabilities |= VO_CAP_SATURATION;
-+ vaapi_check_capability(this, VO_PROP_SATURATION, display_attrs[i], "video.output.vaapi_saturation", "Saturation setting", "Saturation setting");
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ }
-+ free(display_attrs);
-+ }
-+ vaapi_show_display_props(this_gen);
-+}
-+
-+static void vaapi_set_background_color(vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *)this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAStatus vaStatus;
-+
-+ if(!va_context->valid_context)
-+ return;
-+
-+ VADisplayAttribute attr;
-+ memset( &attr, 0, sizeof(attr) );
-+
-+ attr.type = VADisplayAttribBackgroundColor;
-+ attr.value = 0x000000;
-+
-+ vaStatus = vaSetDisplayAttributes(va_context->va_display, &attr, 1);
-+ //vaapi_check_status(this_gen, vaStatus, "vaSetDisplayAttributes()");
-+}
-+
-+static VAStatus vaapi_destroy_render_surfaces(vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *)this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ int i;
-+ VAStatus vaStatus;
-+
-+ for(i = 0; i < RENDER_SURFACES; i++) {
-+ if(va_surface_ids[i] != VA_INVALID_SURFACE) {
-+ vaStatus = vaSyncSurface(va_context->va_display, va_surface_ids[i]);
-+ vaapi_check_status(this_gen, vaStatus, "vaSyncSurface()");
-+ vaStatus = vaDestroySurfaces(va_context->va_display, &va_surface_ids[i], 1);
-+ vaapi_check_status(this_gen, vaStatus, "vaDestroySurfaces()");
-+ va_surface_ids[i] = VA_INVALID_SURFACE;
-+
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[i];
-+ va_surface->index = i;
-+ va_surface->status = SURFACE_FREE;
-+ va_surface->va_surface_id = va_surface_ids[i];
-+ }
-+ }
-+
-+ return VA_STATUS_SUCCESS;
-+}
-+
-+static VAStatus vaapi_destroy_soft_surfaces(vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *)this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ int i;
-+ VAStatus vaStatus;
-+
-+
-+ for(i = 0; i < SOFT_SURFACES; i++) {
-+ if(va_soft_images[i].image_id != VA_INVALID_ID)
-+ vaapi_destroy_image((vo_driver_t *)this, &va_soft_images[i]);
-+ va_soft_images[i].image_id = VA_INVALID_ID;
-+
-+ if(va_soft_surface_ids[i] != VA_INVALID_SURFACE) {
-+#ifdef DEBUG_SURFACE
-+ printf("vaapi_close destroy render surface 0x%08x\n", va_soft_surface_ids[i]);
-+#endif
-+ vaStatus = vaSyncSurface(va_context->va_display, va_soft_surface_ids[i]);
-+ vaapi_check_status(this_gen, vaStatus, "vaSyncSurface()");
-+ vaStatus = vaDestroySurfaces(va_context->va_display, &va_soft_surface_ids[i], 1);
-+ vaapi_check_status(this_gen, vaStatus, "vaDestroySurfaces()");
-+ va_soft_surface_ids[i] = VA_INVALID_SURFACE;
-+ }
-+ }
-+
-+ va_context->sw_width = 0;
-+ va_context->sw_height = 0;
-+ return VA_STATUS_SUCCESS;
-+}
-+
-+static VAStatus vaapi_init_soft_surfaces(vo_driver_t *this_gen, int width, int height) {
-+ vaapi_driver_t *this = (vaapi_driver_t *)this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAStatus vaStatus;
-+ int i;
-+
-+ vaapi_destroy_soft_surfaces(this_gen);
-+
-+ vaStatus = vaCreateSurfaces(va_context->va_display, width, height, VA_RT_FORMAT_YUV420, SOFT_SURFACES, va_soft_surface_ids);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaCreateSurfaces()"))
-+ goto error;
-+
-+ /* allocate software surfaces */
-+ for(i = 0; i < SOFT_SURFACES; i++) {
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[i];
-+
-+ vaStatus = vaapi_create_image((vo_driver_t *)this, va_soft_surface_ids[i], &va_soft_images[i], width, height, 1);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaapi_create_image()")) {
-+ va_soft_images[i].image_id = VA_INVALID_ID;
-+ goto error;
-+ }
-+
-+ va_surface->index = i;
-+
-+ if(!va_context->is_bound) {
-+ vaStatus = vaPutImage(va_context->va_display, va_soft_surface_ids[i], va_soft_images[i].image_id,
-+ 0, 0, va_soft_images[i].width, va_soft_images[i].height,
-+ 0, 0, va_soft_images[i].width, va_soft_images[i].height);
-+ vaapi_check_status(this_gen, vaStatus, "vaPutImage()");
-+ }
-+#ifdef DEBUG_SURFACE
-+ printf("vaapi_init_soft_surfaces 0x%08x\n", va_soft_surface_ids[i]);
-+#endif
-+ }
-+
-+ va_context->sw_width = width;
-+ va_context->sw_height = height;
-+ return VA_STATUS_SUCCESS;
-+
-+error:
-+ va_context->sw_width = 0;
-+ va_context->sw_height = 0;
-+ vaapi_destroy_soft_surfaces(this_gen);
-+ return VA_STATUS_ERROR_UNKNOWN;
-+}
-+
-+static VAStatus vaapi_init_internal(vo_driver_t *this_gen, int va_profile, int width, int height, int softrender) {
-+ vaapi_driver_t *this = (vaapi_driver_t *)this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAConfigAttrib va_attrib;
-+ int maj, min, i;
-+ VAStatus vaStatus;
-+
-+ vaapi_close(this_gen);
-+ vaapi_init_va_context(this);
-+
-+ this->va_context->va_display = vaapi_get_display(this->display, this->opengl_render);
-+
-+ if(!this->va_context->va_display)
-+ goto error;
-+
-+ vaStatus = vaInitialize(this->va_context->va_display, &maj, &min);
-+ if(!vaapi_check_status((vo_driver_t *)this, vaStatus, "vaInitialize()"))
-+ goto error;
-+
-+ lprintf("libva: %d.%d\n", maj, min);
-+
-+ va_context->valid_context = 1;
-+
-+ int fmt_count = 0;
-+ fmt_count = vaMaxNumImageFormats( va_context->va_display );
-+ va_context->va_image_formats = calloc( fmt_count, sizeof(*va_context->va_image_formats) );
-+
-+ vaStatus = vaQueryImageFormats(va_context->va_display, va_context->va_image_formats, &va_context->va_num_image_formats);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaQueryImageFormats()"))
-+ goto error;
-+
-+ fmt_count = vaMaxNumSubpictureFormats( va_context->va_display );
-+ va_context->va_subpic_formats = calloc( fmt_count, sizeof(*va_context->va_subpic_formats) );
-+
-+ vaStatus = vaQuerySubpictureFormats( va_context->va_display , va_context->va_subpic_formats, 0, &va_context->va_num_subpic_formats );
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaQuerySubpictureFormats()"))
-+ goto error;
-+
-+ const char *vendor = vaQueryVendorString(va_context->va_display);
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Vendor : %s\n", vendor);
-+
-+ this->query_va_status = 1;
-+ char *p = (char *)vendor;
-+ for(i = 0; i < strlen(vendor); i++, p++) {
-+ if(strncmp(p, "VDPAU", strlen("VDPAU")) == 0) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Enable Splitted-Desktop Systems VDPAU-VIDEO workarounds.\n");
-+ this->query_va_status = 0;
-+ this->opengl_use_tfp = 0;
-+ break;
-+ }
-+ }
-+
-+ vaapi_set_background_color(this_gen);
-+ vaapi_display_attribs((vo_driver_t *)this);
-+
-+ va_context->width = width;
-+ va_context->height = height;
-+ va_context->va_profile = va_profile;
-+
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : Context width %d height %d\n", va_context->width, va_context->height);
-+
-+ /* allocate decoding surfaces */
-+ vaStatus = vaCreateSurfaces(va_context->va_display, va_context->width, va_context->height, VA_RT_FORMAT_YUV420, RENDER_SURFACES, va_surface_ids);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaCreateSurfaces()"))
-+ goto error;
-+
-+ /* hardware decoding needs more setup */
-+ if(!softrender && va_profile >= 0) {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : Profile: %d (%s) Entrypoint %d (%s) Surfaces %d\n", va_context->va_profile, vaapi_profile_to_string(va_context->va_profile), VAEntrypointVLD, vaapi_entrypoint_to_string(VAEntrypointVLD), RENDER_SURFACES);
-+
-+ memset( &va_attrib, 0, sizeof(va_attrib) );
-+ va_attrib.type = VAConfigAttribRTFormat;
-+
-+ vaStatus = vaGetConfigAttributes(va_context->va_display, va_context->va_profile, VAEntrypointVLD, &va_attrib, 1);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaGetConfigAttributes()"))
-+ goto error;
-+
-+ if( (va_attrib.value & VA_RT_FORMAT_YUV420) == 0 )
-+ goto error;
-+
-+ vaStatus = vaCreateConfig(va_context->va_display, va_context->va_profile, VAEntrypointVLD, &va_attrib, 1, &va_context->va_config_id);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaCreateConfig()")) {
-+ va_context->va_config_id = VA_INVALID_ID;
-+ goto error;
-+ }
-+
-+ vaStatus = vaCreateContext(va_context->va_display, va_context->va_config_id, va_context->width, va_context->height,
-+ VA_PROGRESSIVE, va_surface_ids, RENDER_SURFACES, &va_context->va_context_id);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaCreateContext()")) {
-+ va_context->va_context_id = VA_INVALID_ID;
-+ goto error;
-+ }
-+ }
-+
-+ /* xine was told to allocate RENDER_SURFACES frames. assign the frames the rendering surfaces. */
-+ for(i = 0; i < RENDER_SURFACES; i++) {
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[i];
-+ va_surface->index = i;
-+ va_surface->status = SURFACE_FREE;
-+ va_surface->va_surface_id = va_surface_ids[i];
-+
-+ if(this->frames[i]) {
-+ vaapi_frame_t *frame = this->frames[i];
-+ frame->vaapi_accel_data.index = i;
-+
-+ VAImage va_image;
-+ vaStatus = vaapi_create_image(va_context->driver, va_surface_ids[i], &va_image, width, height, 1);
-+ if(vaapi_check_status(va_context->driver, vaStatus, "vaapi_create_image()") && !va_context->is_bound) {
-+ vaStatus = vaPutImage(va_context->va_display, va_surface_ids[i], va_image.image_id,
-+ 0, 0, va_image.width, va_image.height,
-+ 0, 0, va_image.width, va_image.height);
-+ vaapi_destroy_image(va_context->driver, &va_image);
-+ }
-+ }
-+#ifdef DEBUG_SURFACE
-+ printf("vaapi_init_internal 0x%08x\n", va_surface_ids[i]);
-+#endif
-+ }
-+
-+ vaStatus = vaapi_init_soft_surfaces(this_gen, width, height);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaapi_init_soft_surfaces()")) {
-+ vaapi_destroy_soft_surfaces(this_gen);
-+ goto error;
-+ }
-+
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : guarded render : %d\n", this->guarded_render);
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : glxrender : %d\n", this->opengl_render);
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : glxrender tfp : %d\n", this->opengl_use_tfp);
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : is_bound : %d\n", va_context->is_bound);
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : scaling level : name %s value 0x%08x\n", scaling_level_enum_names[this->scaling_level_enum], this->scaling_level);
-+
-+ this->init_opengl_render = 1;
-+
-+ return VA_STATUS_SUCCESS;
-+
-+error:
-+ vaapi_close(this_gen);
-+ vaapi_init_va_context(this);
-+ va_context->valid_context = 0;
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : error init vaapi\n");
-+
-+ return VA_STATUS_ERROR_UNKNOWN;
-+}
-+
-+/*
-+ * Init VAAPI. This function is called from the decoder side.
-+ * When the decoder uses software decoding vaapi_init is not called.
-+ * Therefore we do it in vaapi_display_frame to get a valid VAAPI context
-+ */
-+static VAStatus vaapi_init(vo_frame_t *frame_gen, int va_profile, int width, int height, int softrender) {
-+ if(!frame_gen)
-+ return VA_STATUS_ERROR_UNKNOWN;
-+
-+ vo_driver_t *this_gen = (vo_driver_t *) frame_gen->driver;
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ VAStatus vaStatus;
-+
-+ unsigned int last_sub_img_fmt = va_context->last_sub_image_fmt;
-+
-+ if(last_sub_img_fmt)
-+ vaapi_ovl_associate(this_gen, frame_gen->format, 0);
-+
-+ if(!this->guarded_render) {
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+ }
-+
-+ vaStatus = vaapi_init_internal(this_gen, va_profile, width, height, softrender);
-+
-+ if(!this->guarded_render) {
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+ }
-+
-+ if(last_sub_img_fmt)
-+ vaapi_ovl_associate(this_gen, frame_gen->format, this->has_overlay);
-+
-+ return vaStatus;
-+}
-+
-+static void vaapi_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src)
-+{
-+ vo_img->proc_called = 1;
-+}
-+
-+static void vaapi_frame_field (vo_frame_t *vo_img, int which_field)
-+{
-+}
-+
-+static void vaapi_frame_dispose (vo_frame_t *vo_img) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) vo_img->driver;
-+ vaapi_frame_t *frame = (vaapi_frame_t *) vo_img ;
-+ vaapi_accel_t *accel = &frame->vaapi_accel_data;
-+
-+ lprintf("vaapi_frame_dispose\n");
-+
-+ av_free (frame->vo_frame.base[0]);
-+ av_free (frame->vo_frame.base[1]);
-+ av_free (frame->vo_frame.base[2]);
-+
-+ if(this->guarded_render) {
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[accel->index];
-+ va_surface->status = SURFACE_FREE;
-+ }
-+
-+ free (frame);
-+}
-+
-+static vo_frame_t *vaapi_alloc_frame (vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ vaapi_frame_t *frame;
-+
-+ frame = (vaapi_frame_t *) calloc(1, sizeof(vaapi_frame_t));
-+
-+ if (!frame)
-+ return NULL;
-+
-+ this->frames[this->num_frame_buffers++] = frame;
-+
-+ frame->vo_frame.base[0] = frame->vo_frame.base[1] = frame->vo_frame.base[2] = NULL;
-+ frame->width = frame->height = frame->format = frame->flags = 0;
-+
-+ frame->vo_frame.accel_data = &frame->vaapi_accel_data;
-+
-+ pthread_mutex_init (&frame->vo_frame.mutex, NULL);
-+
-+ /*
-+ * supply required functions
-+ */
-+ frame->vo_frame.proc_duplicate_frame_data = NULL;
-+ frame->vo_frame.proc_provide_standard_frame_data = NULL;
-+ frame->vo_frame.proc_slice = vaapi_frame_proc_slice;
-+ frame->vo_frame.proc_frame = NULL;
-+ frame->vo_frame.field = vaapi_frame_field;
-+ frame->vo_frame.dispose = vaapi_frame_dispose;
-+ frame->vo_frame.driver = this_gen;
-+
-+ frame->vaapi_accel_data.vo_frame = &frame->vo_frame;
-+ frame->vaapi_accel_data.vaapi_init = &vaapi_init;
-+ frame->vaapi_accel_data.profile_from_imgfmt = &profile_from_imgfmt;
-+ frame->vaapi_accel_data.get_context = &get_context;
-+
-+#if AVVIDEO > 1
-+ frame->vaapi_accel_data.avcodec_decode_video2 = &guarded_avcodec_decode_video2;
-+#else
-+ frame->vaapi_accel_data.avcodec_decode_video = &guarded_avcodec_decode_video;
-+#endif
-+
-+ frame->vaapi_accel_data.get_vaapi_surface = &get_vaapi_surface;
-+ frame->vaapi_accel_data.render_vaapi_surface = &render_vaapi_surface;
-+ frame->vaapi_accel_data.release_vaapi_surface = &release_vaapi_surface;
-+ frame->vaapi_accel_data.guarded_render = &guarded_render;
-+
-+ lprintf("alloc frame\n");
-+
-+ return (vo_frame_t *) frame;
-+}
-+
-+
-+/* Display OSD */
-+static int vaapi_ovl_associate(vo_driver_t *this_gen, int format, int bShow) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAStatus vaStatus;
-+
-+ if(!va_context->valid_context)
-+ return 0;
-+
-+ if(va_context->last_sub_image_fmt && !bShow) {
-+ if(va_context->va_subpic_id != VA_INVALID_ID) {
-+ if(va_context->last_sub_image_fmt == XINE_IMGFMT_VAAPI) {
-+ vaStatus = vaDeassociateSubpicture(va_context->va_display, va_context->va_subpic_id,
-+ va_surface_ids, RENDER_SURFACES);
-+ vaapi_check_status(this_gen, vaStatus, "vaDeassociateSubpicture()");
-+ } else if(va_context->last_sub_image_fmt == XINE_IMGFMT_YV12 ||
-+ va_context->last_sub_image_fmt == XINE_IMGFMT_YUY2) {
-+ vaStatus = vaDeassociateSubpicture(va_context->va_display, va_context->va_subpic_id,
-+ va_soft_surface_ids, SOFT_SURFACES);
-+ vaapi_check_status(this_gen, vaStatus, "vaDeassociateSubpicture()");
-+ }
-+ }
-+ va_context->last_sub_image_fmt = 0;
-+ return 1;
-+ }
-+
-+ if(!va_context->last_sub_image_fmt && bShow) {
-+ unsigned int flags = 0;
-+ unsigned int output_width = va_context->width;
-+ unsigned int output_height = va_context->height;
-+ void *p_base = NULL;
-+
-+ VAStatus vaStatus;
-+
-+ vaapi_destroy_subpicture(this_gen);
-+ vaStatus = vaapi_create_subpicture(this_gen, this->overlay_bitmap_width, this->overlay_bitmap_height);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaapi_create_subpicture()"))
-+ return 0;
-+
-+ vaStatus = vaMapBuffer(va_context->va_display, va_context->va_subpic_image.buf, &p_base);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaMapBuffer()"))
-+ return 0;
-+
-+ xine_fast_memcpy((uint32_t *)p_base, this->overlay_bitmap, this->overlay_bitmap_width * this->overlay_bitmap_height * sizeof(uint32_t));
-+
-+ vaStatus = vaUnmapBuffer(va_context->va_display, va_context->va_subpic_image.buf);
-+ vaapi_check_status(this_gen, vaStatus, "vaUnmapBuffer()");
-+
-+ lprintf( "vaapi_ovl_associate: overlay_width=%d overlay_height=%d unscaled %d va_subpic_id 0x%08x ovl_changed %d has_overlay %d bShow %d overlay_bitmap_width %d overlay_bitmap_height %d va_context->width %d va_context->height %d\n",
-+ this->overlay_output_width, this->overlay_output_height, this->has_overlay,
-+ va_context->va_subpic_id, this->ovl_changed, this->has_overlay, bShow,
-+ this->overlay_bitmap_width, this->overlay_bitmap_height,
-+ va_context->width, va_context->height);
-+
-+ if(format == XINE_IMGFMT_VAAPI) {
-+ lprintf("vaapi_ovl_associate hw\n");
-+ vaStatus = vaAssociateSubpicture(va_context->va_display, va_context->va_subpic_id,
-+ va_surface_ids, RENDER_SURFACES,
-+ 0, 0, va_context->va_subpic_image.width, va_context->va_subpic_image.height,
-+ 0, 0, output_width, output_height, flags);
-+ } else {
-+ lprintf("vaapi_ovl_associate sw\n");
-+ vaStatus = vaAssociateSubpicture(va_context->va_display, va_context->va_subpic_id,
-+ va_soft_surface_ids, SOFT_SURFACES,
-+ 0, 0, va_context->va_subpic_image.width, va_context->va_subpic_image.height,
-+ 0, 0, va_soft_images[0].width, va_soft_images[0].height, flags);
-+ }
-+
-+ if(vaapi_check_status(this_gen, vaStatus, "vaAssociateSubpicture()")) {
-+ va_context->last_sub_image_fmt = format;
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static void vaapi_overlay_clut_yuv2rgb(vaapi_driver_t *this, vo_overlay_t *overlay, vaapi_frame_t *frame)
-+{
-+ int i;
-+ clut_t* clut = (clut_t*) overlay->color;
-+
-+ if (!overlay->rgb_clut) {
-+ for ( i=0; i<sizeof(overlay->color)/sizeof(overlay->color[0]); i++ ) {
-+ *((uint32_t *)&clut[i]) = this->ovl_yuv2rgb->yuv2rgb_single_pixel_fun(this->ovl_yuv2rgb, clut[i].y, clut[i].cb, clut[i].cr);
-+ }
-+ overlay->rgb_clut++;
-+ }
-+ if (!overlay->hili_rgb_clut) {
-+ clut = (clut_t*) overlay->hili_color;
-+ for ( i=0; i<sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
-+ *((uint32_t *)&clut[i]) = this->ovl_yuv2rgb->yuv2rgb_single_pixel_fun(this->ovl_yuv2rgb, clut[i].y, clut[i].cb, clut[i].cr);
-+ }
-+ overlay->hili_rgb_clut++;
-+ }
-+}
-+
-+static void vaapi_overlay_begin (vo_driver_t *this_gen,
-+ vo_frame_t *frame_gen, int changed) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ if ( !changed )
-+ return;
-+
-+ this->has_overlay = 0;
-+ ++this->ovl_changed;
-+
-+ /* Apply OSD layer. */
-+ if(va_context->valid_context) {
-+ lprintf("vaapi_overlay_begin chaned %d\n", changed);
-+
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+
-+ vaapi_ovl_associate(this_gen, frame_gen->format, this->has_overlay);
-+
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+ }
-+}
-+
-+static void vaapi_overlay_blend (vo_driver_t *this_gen,
-+ vo_frame_t *frame_gen, vo_overlay_t *overlay) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ int i = this->ovl_changed;
-+
-+ if (!i)
-+ return;
-+
-+ if (--i >= XINE_VORAW_MAX_OVL)
-+ return;
-+
-+ if (overlay->width <= 0 || overlay->height <= 0 || (!overlay->rle && (!overlay->argb_layer || !overlay->argb_layer->buffer)))
-+ return;
-+
-+ if (overlay->rle)
-+ lprintf("overlay[%d] rle %s%s %dx%d@%d,%d hili rect %d,%d-%d,%d\n", i,
-+ overlay->unscaled ? " unscaled ": " scaled ",
-+ (overlay->rgb_clut > 0 || overlay->hili_rgb_clut > 0) ? " rgb ": " ycbcr ",
-+ overlay->width, overlay->height, overlay->x, overlay->y,
-+ overlay->hili_left, overlay->hili_top,
-+ overlay->hili_right, overlay->hili_bottom);
-+ if (overlay->argb_layer && overlay->argb_layer->buffer)
-+ lprintf("overlay[%d] argb %s %dx%d@%d,%d dirty rect %d,%d-%d,%d\n", i,
-+ overlay->unscaled ? " unscaled ": " scaled ",
-+ overlay->width, overlay->height, overlay->x, overlay->y,
-+ overlay->argb_layer->x1, overlay->argb_layer->y1,
-+ overlay->argb_layer->x2, overlay->argb_layer->y2);
-+
-+
-+ this->overlays[i] = overlay;
-+
-+ ++this->ovl_changed;
-+}
-+
-+static void vaapi_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ vaapi_frame_t *frame = (vaapi_frame_t *) frame_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ int novls = this->ovl_changed;
-+ if (novls < 2) {
-+ this->ovl_changed = 0;
-+ return;
-+ }
-+ --novls;
-+
-+ uint32_t output_width = frame->width;
-+ uint32_t output_height = frame->height;
-+ uint32_t unscaled_width = 0, unscaled_height = 0;
-+ vo_overlay_t *first_scaled = NULL, *first_unscaled = NULL;
-+ vaapi_rect_t dirty_rect, unscaled_dirty_rect;
-+ int has_rle = 0;
-+
-+ int i;
-+ for (i = 0; i < novls; ++i) {
-+ vo_overlay_t *ovl = this->overlays[i];
-+
-+ if (ovl->rle)
-+ has_rle = 1;
-+
-+ if (ovl->unscaled) {
-+ if (first_unscaled) {
-+ if (ovl->x < unscaled_dirty_rect.x1)
-+ unscaled_dirty_rect.x1 = ovl->x;
-+ if (ovl->y < unscaled_dirty_rect.y1)
-+ unscaled_dirty_rect.y1 = ovl->y;
-+ if ((ovl->x + ovl->width) > unscaled_dirty_rect.x2)
-+ unscaled_dirty_rect.x2 = ovl->x + ovl->width;
-+ if ((ovl->y + ovl->height) > unscaled_dirty_rect.y2)
-+ unscaled_dirty_rect.y2 = ovl->y + ovl->height;
-+ } else {
-+ first_unscaled = ovl;
-+ unscaled_dirty_rect.x1 = ovl->x;
-+ unscaled_dirty_rect.y1 = ovl->y;
-+ unscaled_dirty_rect.x2 = ovl->x + ovl->width;
-+ unscaled_dirty_rect.y2 = ovl->y + ovl->height;
-+ }
-+
-+ unscaled_width = unscaled_dirty_rect.x2;
-+ unscaled_height = unscaled_dirty_rect.y2;
-+ } else {
-+ if (first_scaled) {
-+ if (ovl->x < dirty_rect.x1)
-+ dirty_rect.x1 = ovl->x;
-+ if (ovl->y < dirty_rect.y1)
-+ dirty_rect.y1 = ovl->y;
-+ if ((ovl->x + ovl->width) > dirty_rect.x2)
-+ dirty_rect.x2 = ovl->x + ovl->width;
-+ if ((ovl->y + ovl->height) > dirty_rect.y2)
-+ dirty_rect.y2 = ovl->y + ovl->height;
-+ } else {
-+ first_scaled = ovl;
-+ dirty_rect.x1 = ovl->x;
-+ dirty_rect.y1 = ovl->y;
-+ dirty_rect.x2 = ovl->x + ovl->width;
-+ dirty_rect.y2 = ovl->y + ovl->height;
-+ }
-+
-+ if (dirty_rect.x2 > output_width)
-+ output_width = dirty_rect.x2;
-+ if (dirty_rect.y2 > output_height)
-+ output_height = dirty_rect.y2;
-+
-+ }
-+ }
-+
-+ int need_init = 0;
-+
-+ lprintf("dirty_rect.x0 %d dirty_rect.y0 %d dirty_rect.x2 %d dirty_rect.y2 %d output_width %d output_height %d\n",
-+ dirty_rect.x0, dirty_rect.y0, dirty_rect.x2, dirty_rect.y2, output_width, output_height);
-+
-+ if (first_scaled) {
-+ vaapi_rect_t dest;
-+ dest.x1 = first_scaled->x;
-+ dest.y1 = first_scaled->y;
-+ dest.x2 = first_scaled->x + first_scaled->width;
-+ dest.y2 = first_scaled->y + first_scaled->height;
-+ if (!RECT_IS_EQ(dest, dirty_rect))
-+ need_init = 1;
-+ }
-+
-+ int need_unscaled_init = (first_unscaled &&
-+ (first_unscaled->x != unscaled_dirty_rect.x1 ||
-+ first_unscaled->y != unscaled_dirty_rect.y1 ||
-+ (first_unscaled->x + first_unscaled->width) != unscaled_dirty_rect.x2 ||
-+ (first_unscaled->y + first_unscaled->height) != unscaled_dirty_rect.y2));
-+
-+ if (first_scaled) {
-+ this->overlay_output_width = output_width;
-+ this->overlay_output_height = output_height;
-+
-+ need_init = 1;
-+
-+ this->overlay_dirty_rect = dirty_rect;
-+ }
-+
-+ if (first_unscaled) {
-+ this->overlay_unscaled_width = unscaled_width;
-+ this->overlay_unscaled_height = unscaled_height;
-+
-+ need_unscaled_init = 1;
-+ this->overlay_unscaled_dirty_rect = unscaled_dirty_rect;
-+ }
-+
-+ if (has_rle || need_init || need_unscaled_init) {
-+ lprintf("has_rle %d need_init %d need_unscaled_init %d unscaled_width %d unscaled_height %d output_width %d output_height %d\n",
-+ has_rle, need_init, need_unscaled_init, unscaled_width, unscaled_height, output_width, output_height);
-+ if (need_init) {
-+ this->overlay_bitmap_width = output_width;
-+ this->overlay_bitmap_height = output_height;
-+ }
-+ if (need_unscaled_init) {
-+
-+ if(this->vdr_osd_width)
-+ this->overlay_bitmap_width = (this->vdr_osd_width > this->sc.gui_width) ? this->vdr_osd_width : this->sc.gui_width;
-+ else
-+ this->overlay_bitmap_width = (unscaled_width > this->sc.gui_width) ? unscaled_width : this->sc.gui_width;
-+
-+ if(this->vdr_osd_height)
-+ this->overlay_bitmap_height = (this->vdr_osd_height > this->sc.gui_height) ? this->vdr_osd_height : this->sc.gui_height;
-+ else
-+ this->overlay_bitmap_height = (unscaled_height > this->sc.gui_height) ? unscaled_height : this->sc.gui_height;
-+
-+ } else if (need_init) {
-+
-+ if(this->vdr_osd_width)
-+ this->overlay_bitmap_width = (this->vdr_osd_width > this->sc.gui_width) ? this->vdr_osd_width : this->sc.gui_width;
-+ else
-+ this->overlay_bitmap_width = (output_width > this->sc.gui_width) ? output_width : this->sc.gui_width;
-+
-+ if(this->vdr_osd_height)
-+ this->overlay_bitmap_height = (this->vdr_osd_height > this->sc.gui_height) ? this->vdr_osd_height : this->sc.gui_height;
-+ else
-+ this->overlay_bitmap_height = (output_height > this->sc.gui_height) ? output_height : this->sc.gui_height;
-+
-+ }
-+ }
-+
-+ if ((this->overlay_bitmap_width * this->overlay_bitmap_height) > this->overlay_bitmap_size) {
-+ this->overlay_bitmap_size = this->overlay_bitmap_width * this->overlay_bitmap_height;
-+ free(this->overlay_bitmap);
-+ this->overlay_bitmap = calloc( this->overlay_bitmap_size, sizeof(uint32_t));
-+ } else {
-+ memset(this->overlay_bitmap, 0x0, this->overlay_bitmap_size * sizeof(uint32_t));
-+ }
-+
-+ for (i = 0; i < novls; ++i) {
-+ vo_overlay_t *ovl = this->overlays[i];
-+ uint32_t *bitmap = NULL;
-+ uint32_t *rgba = NULL;
-+
-+ if (ovl->rle) {
-+ if(ovl->width<=0 || ovl->height<=0)
-+ continue;
-+
-+ if (!ovl->rgb_clut || !ovl->hili_rgb_clut)
-+ vaapi_overlay_clut_yuv2rgb (this, ovl, frame);
-+
-+ bitmap = rgba = calloc(ovl->width * ovl->height * 4, sizeof(uint32_t));
-+
-+ int num_rle = ovl->num_rle;
-+ rle_elem_t *rle = ovl->rle;
-+ uint32_t red, green, blue, alpha;
-+ clut_t *low_colors = (clut_t*)ovl->color;
-+ clut_t *hili_colors = (clut_t*)ovl->hili_color;
-+ uint8_t *low_trans = ovl->trans;
-+ uint8_t *hili_trans = ovl->hili_trans;
-+ clut_t *colors;
-+ uint8_t *trans;
-+ int rlelen = 0;
-+ uint8_t clr = 0;
-+ int i, pos=0, x, y;
-+
-+ while (num_rle > 0) {
-+ x = pos % ovl->width;
-+ y = pos / ovl->width;
-+
-+ if ( (x>=ovl->hili_left && x<=ovl->hili_right) && (y>=ovl->hili_top && y<=ovl->hili_bottom) ) {
-+ colors = hili_colors;
-+ trans = hili_trans;
-+ }
-+ else {
-+ colors = low_colors;
-+ trans = low_trans;
-+ }
-+ rlelen = rle->len;
-+ clr = rle->color;
-+ for ( i=0; i<rlelen; ++i ) {
-+ if ( trans[clr] == 0 ) {
-+ alpha = red = green = blue = 0;
-+ }
-+ else {
-+ red = colors[clr].y; // red
-+ green = colors[clr].cr; // green
-+ blue = colors[clr].cb; // blue
-+ alpha = trans[clr]*255/15;
-+ }
-+ *rgba = (alpha<<24) | (red<<16) | (green<<8) | blue;
-+ rgba++;
-+ ++pos;
-+ }
-+ ++rle;
-+ --num_rle;
-+ }
-+ lprintf("width %d height %d pos %d %d\n", ovl->width, ovl->height, pos, ovl->width * ovl->height);
-+ } else {
-+ pthread_mutex_lock(&ovl->argb_layer->mutex);
-+ bitmap = ovl->argb_layer->buffer;
-+ }
-+
-+ /* Blit overlay to destination */
-+ uint32_t pitch = ovl->width * sizeof(uint32_t);
-+ uint32_t *copy_dst = this->overlay_bitmap;
-+ uint32_t *copy_src = NULL;
-+ uint32_t height = 0;
-+
-+ copy_src = bitmap;
-+
-+ copy_dst += ovl->y * this->overlay_bitmap_width;
-+
-+ lprintf("overlay_bitmap_width %d overlay_bitmap_height %d ovl->x %d ovl->y %d ovl->width %d ovl->height %d width %d height %d\n",
-+ this->overlay_bitmap_width, this->overlay_bitmap_height, ovl->x, ovl->y, ovl->width, ovl->height, this->overlay_bitmap_width, this->overlay_bitmap_height);
-+
-+ for(height = 0; height < ovl->height; height++) {
-+ if((height + ovl->y) >= this->overlay_bitmap_height)
-+ break;
-+
-+ xine_fast_memcpy(copy_dst + ovl->x, copy_src, pitch);
-+ copy_dst += this->overlay_bitmap_width;
-+ copy_src += ovl->width;
-+ }
-+
-+ if (ovl->rle) {
-+ if(bitmap) {
-+ free(bitmap);
-+ bitmap = NULL;
-+ }
-+ }
-+
-+ if (!ovl->rle)
-+ pthread_mutex_unlock(&ovl->argb_layer->mutex);
-+
-+ }
-+
-+ this->ovl_changed = 0;
-+ this->has_overlay = (first_scaled != NULL) | (first_unscaled != NULL);
-+
-+ lprintf("this->has_overlay %d\n", this->has_overlay);
-+ /* Apply OSD layer. */
-+ if(va_context->valid_context) {
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+
-+ vaapi_ovl_associate(this_gen, frame_gen->format, this->has_overlay);
-+
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+ }
-+}
-+
-+static void vaapi_resize_glx_window (vo_driver_t *this_gen, int width, int height) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ if(this->valid_opengl_context) {
-+ glViewport(0, 0, width, height);
-+ 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)width,
-+ -1.0f / (GLfloat)height,
-+ 1.0f / (GLfloat)width);
-+ glTranslatef(0.0f, -1.0f * (GLfloat)height, 0.0f);
-+ }
-+}
-+
-+static int vaapi_redraw_needed (vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ int ret = 0;
-+
-+ _x_vo_scale_compute_ideal_size( &this->sc );
-+
-+ if ( _x_vo_scale_redraw_needed( &this->sc ) ) {
-+ _x_vo_scale_compute_output_size( &this->sc );
-+
-+ XMoveResizeWindow(this->display, this->window,
-+ 0, 0, this->sc.gui_width, this->sc.gui_height);
-+
-+ vaapi_resize_glx_window(this_gen, this->sc.gui_width, this->sc.gui_height);
-+
-+ ret = 1;
-+ }
-+
-+ return ret;
-+}
-+
-+static void vaapi_provide_standard_frame_data (vo_frame_t *orig, xine_current_frame_data_t *data)
-+{
-+ vaapi_driver_t *driver = (vaapi_driver_t *) orig->driver;
-+ ff_vaapi_context_t *va_context = driver->va_context;
-+
-+ vaapi_accel_t *accel = (vaapi_accel_t *) orig->accel_data;
-+ vo_frame_t *this = accel->vo_frame;
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[accel->index];
-+
-+ uint32_t pitches[3];
-+ uint8_t *base[3];
-+
-+ if(driver == NULL) {
-+ return;
-+ }
-+
-+ if (this->format != XINE_IMGFMT_VAAPI) {
-+ xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE "vaapi_provide_standard_frame_data: unexpected frame format 0x%08x!\n", this->format);
-+ return;
-+ }
-+
-+ if( !accel || va_surface->va_surface_id == VA_INVALID_SURFACE )
-+ return;
-+
-+ lprintf("vaapi_provide_standard_frame_data %s 0x%08x width %d height %d\n",
-+ (this->format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((this->format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2"),
-+ va_surface->va_surface_id, this->width, this->height);
-+
-+ pthread_mutex_lock(&driver->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+
-+ int width = va_context->width;
-+ int height = va_context->height;
-+
-+ data->format = XINE_IMGFMT_YV12;
-+ data->img_size = width * height
-+ + ((width + 1) / 2) * ((height + 1) / 2)
-+ + ((width + 1) / 2) * ((height + 1) / 2);
-+ if (data->img) {
-+ pitches[0] = width;
-+ pitches[2] = width / 2;
-+ pitches[1] = width / 2;
-+ base[0] = data->img;
-+ base[2] = data->img + width * height;
-+ base[1] = data->img + width * height + width * this->height / 4;
-+
-+ VAImage va_image;
-+ VAStatus vaStatus;
-+ void *p_base;
-+
-+ vaStatus = vaSyncSurface(va_context->va_display, va_surface->va_surface_id);
-+ vaapi_check_status(va_context->driver, vaStatus, "vaSyncSurface()");
-+
-+ VASurfaceStatus surf_status = 0;
-+
-+ if(driver->query_va_status) {
-+ vaStatus = vaQuerySurfaceStatus(va_context->va_display, va_surface->va_surface_id, &surf_status);
-+ vaapi_check_status(va_context->driver, vaStatus, "vaQuerySurfaceStatus()");
-+ } else {
-+ surf_status = VASurfaceReady;
-+ }
-+
-+ if(surf_status != VASurfaceReady)
-+ goto error;
-+
-+ vaStatus = vaapi_create_image(va_context->driver, va_surface->va_surface_id, &va_image, width, height, 0);
-+ if(!vaapi_check_status(va_context->driver, vaStatus, "vaapi_create_image()"))
-+ goto error;
-+
-+ lprintf("vaapi_provide_standard_frame_data accel->va_surface_id 0x%08x va_image.image_id 0x%08x va_context->width %d va_context->height %d va_image.width %d va_image.height %d width %d height %d size1 %d size2 %d %d %d %d status %d num_planes %d\n",
-+ va_surface->va_surface_id, va_image.image_id, va_context->width, va_context->height, va_image.width, va_image.height, width, height, va_image.data_size, data->img_size,
-+ va_image.pitches[0], va_image.pitches[1], va_image.pitches[2], surf_status, va_image.num_planes);
-+
-+ if(va_image.image_id == VA_INVALID_ID)
-+ goto error;
-+
-+ if(!va_context->is_bound) {
-+ vaStatus = vaGetImage(va_context->va_display, va_surface->va_surface_id, 0, 0,
-+ va_image.width, va_image.height, va_image.image_id);
-+ } else {
-+ vaStatus = VA_STATUS_SUCCESS;
-+ }
-+
-+ if(vaapi_check_status(va_context->driver, vaStatus, "vaGetImage()")) {
-+ vaStatus = vaMapBuffer( va_context->va_display, va_image.buf, &p_base ) ;
-+ if(vaapi_check_status(va_context->driver, vaStatus, "vaMapBuffer()")) {
-+
-+ /*
-+ uint8_t *src[3] = { NULL, };
-+ src[0] = (uint8_t *)p_base + va_image.offsets[0];
-+ src[1] = (uint8_t *)p_base + va_image.offsets[1];
-+ src[2] = (uint8_t *)p_base + va_image.offsets[2];
-+ */
-+
-+ if( va_image.format.fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) ||
-+ va_image.format.fourcc == VA_FOURCC( 'I', '4', '2', '0' ) ) {
-+ lprintf("VAAPI YV12 image\n");
-+
-+ yv12_to_yv12(
-+ (uint8_t*)p_base + va_image.offsets[0], va_image.pitches[0],
-+ base[0], pitches[0],
-+ (uint8_t*)p_base + va_image.offsets[1], va_image.pitches[1],
-+ base[1], pitches[1],
-+ (uint8_t*)p_base + va_image.offsets[2], va_image.pitches[2],
-+ base[2], pitches[2],
-+ va_image.width, va_image.height);
-+
-+ } else if( va_image.format.fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) ) {
-+ lprintf("VAAPI NV12 image\n");
-+
-+ lprintf("va_image.offsets[0] %d va_image.offsets[1] %d va_image.offsets[2] %d size %d size %d size %d width %d height %d width %d height %d\n",
-+ va_image.offsets[0], va_image.offsets[1], va_image.offsets[2], va_image.data_size, va_image.width * va_image.height,
-+ data->img_size, width, height, va_image.width, va_image.height);
-+
-+ base[0] = data->img;
-+ base[1] = data->img + width * height;
-+ base[2] = data->img + width * height + width * height / 4;
-+
-+ nv12_to_yv12((uint8_t *)p_base + va_image.offsets[0], va_image.pitches[0],
-+ (uint8_t *)p_base + va_image.offsets[1], va_image.pitches[1],
-+ base[0], pitches[0],
-+ base[1], pitches[1],
-+ base[2], pitches[2],
-+ va_image.width, va_image.height,
-+ width, height,
-+ va_image.data_size);
-+
-+ } else {
-+ printf("vaapi_provide_standard_frame_data unsupported image format\n");
-+ }
-+
-+ vaStatus = vaUnmapBuffer(va_context->va_display, va_image.buf);
-+ vaapi_check_status(va_context->driver, vaStatus, "vaUnmapBuffer()");
-+ vaapi_destroy_image(va_context->driver, &va_image);
-+ }
-+ }
-+ }
-+
-+error:
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&driver->vaapi_lock);
-+}
-+
-+static void vaapi_duplicate_frame_data (vo_frame_t *this_gen, vo_frame_t *original)
-+{
-+ vaapi_driver_t *driver = (vaapi_driver_t *) original->driver;
-+ ff_vaapi_context_t *va_context = driver->va_context;
-+
-+ vaapi_frame_t *this = (vaapi_frame_t *)this_gen;
-+ vaapi_frame_t *orig = (vaapi_frame_t *)original;
-+
-+ vaapi_accel_t *accel_this = &this->vaapi_accel_data;
-+ vaapi_accel_t *accel_orig = &orig->vaapi_accel_data;
-+
-+ ff_vaapi_surface_t *va_surface_this = &va_render_surfaces[accel_this->index];
-+ ff_vaapi_surface_t *va_surface_orig = &va_render_surfaces[accel_orig->index];
-+
-+ lprintf("vaapi_duplicate_frame_data %s %s 0x%08x 0x%08x\n",
-+ (this_gen->format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((this_gen->format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2"),
-+ (original->format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((original->format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2"),
-+ va_surface_this->va_surface_id, va_surface_orig->va_surface_id);
-+
-+ if (orig->vo_frame.format != XINE_IMGFMT_VAAPI) {
-+ xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE "vaapi_duplicate_frame_data: unexpected frame format 0x%08x!\n", orig->format);
-+ return;
-+ }
-+
-+ if (this->vo_frame.format != XINE_IMGFMT_VAAPI) {
-+ xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE "vaapi_duplicate_frame_data: unexpected frame format 0x%08x!\n", this->format);
-+ return;
-+ }
-+
-+ pthread_mutex_lock(&driver->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+
-+ VAImage va_image_orig;
-+ VAImage va_image_this;
-+ VAStatus vaStatus;
-+ void *p_base_orig = NULL;
-+ void *p_base_this = NULL;
-+
-+ vaStatus = vaSyncSurface(va_context->va_display, va_surface_orig->va_surface_id);
-+ vaapi_check_status(va_context->driver, vaStatus, "vaSyncSurface()");
-+
-+ int this_width = va_context->width;
-+ int this_height = va_context->height;
-+ int orig_width = va_context->width;
-+ int orig_height = va_context->height;
-+
-+ vaStatus = vaapi_create_image(va_context->driver, va_surface_orig->va_surface_id, &va_image_orig, orig_width, orig_height, 0);
-+ if(!vaapi_check_status(va_context->driver, vaStatus, "vaapi_create_image()")) {
-+ va_image_orig.image_id = VA_INVALID_ID;
-+ goto error;
-+ }
-+
-+ vaStatus = vaapi_create_image(va_context->driver, va_surface_this->va_surface_id, &va_image_this, this_width, this_height, 0);
-+ if(!vaapi_check_status(va_context->driver, vaStatus, "vaapi_create_image()")) {
-+ va_image_this.image_id = VA_INVALID_ID;
-+ goto error;
-+ }
-+
-+ if(va_image_orig.image_id == VA_INVALID_ID || va_image_this.image_id == VA_INVALID_ID) {
-+ printf("vaapi_duplicate_frame_data invalid image\n");
-+ goto error;
-+ }
-+
-+ lprintf("vaapi_duplicate_frame_data va_image_orig.image_id 0x%08x va_image_orig.width %d va_image_orig.height %d width %d height %d size %d %d %d %d\n",
-+ va_image_orig.image_id, va_image_orig.width, va_image_orig.height, this->width, this->height, va_image_orig.data_size,
-+ va_image_orig.pitches[0], va_image_orig.pitches[1], va_image_orig.pitches[2]);
-+
-+ if(!va_context->is_bound) {
-+ vaStatus = vaGetImage(va_context->va_display, va_surface_orig->va_surface_id, 0, 0,
-+ va_image_orig.width, va_image_orig.height, va_image_orig.image_id);
-+ } else {
-+ vaStatus = VA_STATUS_SUCCESS;
-+ }
-+
-+ if(vaapi_check_status(va_context->driver, vaStatus, "vaGetImage()")) {
-+
-+ if(!va_context->is_bound) {
-+ vaStatus = vaPutImage(va_context->va_display, va_surface_this->va_surface_id, va_image_orig.image_id,
-+ 0, 0, va_image_orig.width, va_image_orig.height,
-+ 0, 0, va_image_this.width, va_image_this.height);
-+ vaapi_check_status(va_context->driver, vaStatus, "vaPutImage()");
-+ } else {
-+ vaStatus = vaMapBuffer( va_context->va_display, va_image_orig.buf, &p_base_orig ) ;
-+ if(!vaapi_check_status(va_context->driver, vaStatus, "vaMapBuffer()"))
-+ goto error;
-+
-+ vaStatus = vaMapBuffer( va_context->va_display, va_image_this.buf, &p_base_this ) ;
-+ if(!vaapi_check_status(va_context->driver, vaStatus, "vaMapBuffer()"))
-+ goto error;
-+
-+ int size = (va_image_orig.data_size > va_image_this.data_size) ? va_image_this.data_size : va_image_orig.data_size;
-+ xine_fast_memcpy((uint8_t *) p_base_this, (uint8_t *) p_base_orig, size);
-+
-+ }
-+ }
-+
-+error:
-+ if(p_base_orig) {
-+ vaStatus = vaUnmapBuffer(va_context->va_display, va_image_orig.buf);
-+ vaapi_check_status(va_context->driver, vaStatus, "vaUnmapBuffer()");
-+ }
-+ if(p_base_this) {
-+ vaStatus = vaUnmapBuffer(va_context->va_display, va_image_this.buf);
-+ vaapi_check_status(va_context->driver, vaStatus, "vaUnmapBuffer()");
-+ }
-+
-+ vaapi_destroy_image(va_context->driver, &va_image_orig);
-+ vaapi_destroy_image(va_context->driver, &va_image_this);
-+
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&driver->vaapi_lock);
-+}
-+
-+static void vaapi_update_frame_format (vo_driver_t *this_gen,
-+ vo_frame_t *frame_gen,
-+ uint32_t width, uint32_t height,
-+ double ratio, int format, int flags) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ vaapi_frame_t *frame = (vaapi_frame_t*)frame_gen;
-+ vaapi_accel_t *accel = &frame->vaapi_accel_data;
-+
-+ lprintf("vaapi_update_frame_format\n");
-+
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+
-+ lprintf("vaapi_update_frame_format %s %s width %d height %d\n",
-+ (frame->format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((frame->format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2") ,
-+ (format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2") ,
-+ width, height);
-+
-+ frame->vo_frame.width = width;
-+ frame->vo_frame.height = height;
-+
-+ if ((frame->width != width)
-+ || (frame->height != height)
-+ || (frame->format != format)) {
-+
-+ // (re-) allocate render space
-+ av_freep (&frame->vo_frame.base[0]);
-+ av_freep (&frame->vo_frame.base[1]);
-+ av_freep (&frame->vo_frame.base[2]);
-+
-+ /* set init_vaapi on frame formats XINE_IMGFMT_YV12/XINE_IMGFMT_YUY2 only.
-+ * for XINE_IMGFMT_VAAPI the init was already done.
-+ */
-+ if (format == XINE_IMGFMT_YV12) {
-+ frame->vo_frame.pitches[0] = 8*((width + 7) / 8);
-+ frame->vo_frame.pitches[1] = 8*((width + 15) / 16);
-+ frame->vo_frame.pitches[2] = 8*((width + 15) / 16);
-+ frame->vo_frame.base[0] = av_mallocz (frame->vo_frame.pitches[0] * height + FF_INPUT_BUFFER_PADDING_SIZE);
-+ frame->vo_frame.base[1] = av_mallocz (frame->vo_frame.pitches[1] * ((height+1)/2) + FF_INPUT_BUFFER_PADDING_SIZE);
-+ frame->vo_frame.base[2] = av_mallocz (frame->vo_frame.pitches[2] * ((height+1)/2) + FF_INPUT_BUFFER_PADDING_SIZE);
-+ frame->vo_frame.proc_duplicate_frame_data = NULL;
-+ frame->vo_frame.proc_provide_standard_frame_data = NULL;
-+ lprintf("XINE_IMGFMT_YV12 width %d height %d\n", width, height);
-+ } else if (format == XINE_IMGFMT_YUY2){
-+ frame->vo_frame.pitches[0] = 8*((width + 3) / 4);
-+ frame->vo_frame.base[0] = av_mallocz (frame->vo_frame.pitches[0] * height + FF_INPUT_BUFFER_PADDING_SIZE);
-+ frame->vo_frame.proc_duplicate_frame_data = NULL;
-+ frame->vo_frame.proc_provide_standard_frame_data = NULL;
-+ lprintf("XINE_IMGFMT_YUY2 width %d height %d\n", width, height);
-+ } else if (format == XINE_IMGFMT_VAAPI) {
-+ frame->vo_frame.proc_duplicate_frame_data = vaapi_duplicate_frame_data;
-+ frame->vo_frame.proc_provide_standard_frame_data = vaapi_provide_standard_frame_data;
-+ lprintf("XINE_IMGFMT_VAAPI width %d height %d\n", width, height);
-+ }
-+
-+ frame->width = width;
-+ frame->height = height;
-+ frame->format = format;
-+ frame->flags = flags;
-+ vaapi_frame_field ((vo_frame_t *)frame, flags);
-+ }
-+
-+ if(this->guarded_render) {
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[accel->index];
-+
-+ if(va_surface->status == SURFACE_RENDER_RELEASE) {
-+ va_surface->status = SURFACE_FREE;
-+#ifdef DEBUG_SURFACE
-+ printf("release_surface vaapi_update_frame_format 0x%08x\n", va_surface->va_surface_id);
-+#endif
-+ } else if(va_surface->status == SURFACE_RENDER) {
-+ va_surface->status = SURFACE_RELEASE;
-+#ifdef DEBUG_SURFACE
-+ printf("release_surface vaapi_update_frame_format 0x%08x\n", va_surface->va_surface_id);
-+#endif
-+ }
-+ }
-+
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+
-+ frame->ratio = ratio;
-+ frame->vo_frame.future_frame = NULL;
-+}
-+
-+static inline uint8_t clip_uint8_vlc( int32_t a )
-+{
-+ if( a&(~255) ) return (-a)>>31;
-+ else return a;
-+}
-+
-+
-+static void nv12_to_yv12(const uint8_t *y_src, int y_src_pitch,
-+ const uint8_t *uv_src, int uv_src_pitch,
-+ uint8_t *y_dst, int y_dst_pitch,
-+ uint8_t *u_dst, int u_dst_pitch,
-+ uint8_t *v_dst, int v_dst_pitch,
-+ int src_width, int src_height,
-+ int dst_width, int dst_height,
-+ int src_data_size) {
-+
-+ int y_src_size = src_height * y_src_pitch;
-+ int y, x;
-+
-+ int uv_src_size = src_height * uv_src_pitch / 2;
-+ if((y_src_size + uv_src_size) != (src_data_size))
-+ printf("nv12_to_yv12 strange %d\n", (y_src_size + uv_src_size) - (src_data_size));
-+
-+ int height = (src_height > dst_height) ? dst_height : src_height;
-+ int width = (src_width > dst_width) ? dst_width : src_width;
-+
-+ for(y = 0; y < height; y++) {
-+ xine_fast_memcpy(y_dst, y_src, width);
-+ y_src += y_src_pitch;
-+ y_dst += y_dst_pitch;
-+ }
-+
-+ for(y = 0; y < height; y++) {
-+ const uint8_t *uv_src_tmp = uv_src;
-+ for(x = 0; x < u_dst_pitch; x++) {
-+ if(((y * uv_src_pitch) + x) < uv_src_size) {
-+ *(u_dst + x) = *(uv_src_tmp );
-+ *(v_dst + x) = *(uv_src_tmp + 1);
-+ }
-+ uv_src_tmp += 2;
-+ }
-+ uv_src += uv_src_pitch;
-+ u_dst += u_dst_pitch;
-+ v_dst += v_dst_pitch;
-+ }
-+}
-+
-+static void yv12_to_nv12(const uint8_t *y_src, int y_src_pitch,
-+ const uint8_t *u_src, int u_src_pitch,
-+ const uint8_t *v_src, int v_src_pitch,
-+ uint8_t *y_dst, int y_dst_pitch,
-+ uint8_t *uv_dst, int uv_dst_pitch,
-+ int src_width, int src_height,
-+ int dst_width, int dst_height,
-+ int dst_data_size) {
-+
-+ int y_dst_size = dst_height * y_dst_pitch;
-+ int y, x;
-+
-+ lprintf("yv12_to_nv12 converter\n");
-+
-+ int uv_dst_size = dst_height * uv_dst_pitch / 2;
-+ if((y_dst_size + uv_dst_size) != (dst_data_size))
-+ printf("yv12_to_nv12 strange %d\n", (y_dst_size + uv_dst_size) - (dst_data_size));
-+
-+ int height = (src_height > dst_height) ? dst_height : src_height;
-+ int width = (src_width > dst_width) ? dst_width : src_width;
-+
-+ for(y = 0; y < height; y++) {
-+ xine_fast_memcpy(y_dst, y_src, width);
-+ y_src += y_src_pitch;
-+ y_dst += y_dst_pitch;
-+ }
-+
-+ for(y = 0; y < height; y++) {
-+ uint8_t *uv_dst_tmp = uv_dst;
-+ for(x = 0; x < u_src_pitch; x++) {
-+ if(((y * uv_dst_pitch) + x) < uv_dst_size) {
-+ *(uv_dst_tmp ) = *(u_src + x);
-+ *(uv_dst_tmp + 1) = *(v_src + x);
-+ }
-+ uv_dst_tmp += 2;
-+ }
-+ uv_dst += uv_dst_pitch;
-+ u_src += u_src_pitch;
-+ v_src += v_src_pitch;
-+ }
-+}
-+
-+static void yuy2_to_nv12(const uint8_t *src_yuy2_map, int yuy2_pitch,
-+ uint8_t *y_dst, int y_dst_pitch,
-+ uint8_t *uv_dst, int uv_dst_pitch,
-+ int src_width, int src_height,
-+ int dst_width, int dst_height,
-+ int dst_data_size) {
-+
-+ int height = (src_height > dst_height) ? dst_height : src_height;
-+ int width = (src_width > dst_width) ? dst_width : src_width;
-+
-+ int y, x;
-+ int uv_dst_size = dst_height * uv_dst_pitch / 2;
-+
-+ const uint8_t *yuy2_map = src_yuy2_map;
-+ for(y = 0; y < height; y++) {
-+ uint8_t *y_dst_tmp = y_dst;
-+ const uint8_t *yuy2_src_tmp = yuy2_map;
-+ for(x = 0; x < width / 2; x++) {
-+ *(y_dst_tmp++ ) = *(yuy2_src_tmp++);
-+ yuy2_src_tmp++;
-+ *(y_dst_tmp++ ) = *(yuy2_src_tmp++);
-+ yuy2_src_tmp++;
-+ }
-+ y_dst += y_dst_pitch;
-+ yuy2_map += yuy2_pitch;
-+ }
-+
-+ yuy2_map = src_yuy2_map;
-+ uint8_t *uv_dst_tmp = uv_dst;
-+ for(y = 0; y < height; y++) {
-+ for(x = 0; x < width; x++) {
-+ *(uv_dst_tmp + (height*width/4) ) = (yuy2_map + (height*width/2));
-+ *(uv_dst_tmp + (height*width/4) + 2 ) = (yuy2_map + (height*width/2) + 2);
-+ }
-+ uv_dst += uv_dst_pitch / 2;
-+ yuy2_map += yuy2_pitch;
-+ }
-+
-+}
-+
-+
-+static VAStatus vaapi_software_render_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen,
-+ VAImage *va_image, VASurfaceID va_surface_id) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ vaapi_frame_t *frame = (vaapi_frame_t *) frame_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ void *p_base = NULL;
-+ VAStatus vaStatus;
-+
-+ if(va_image == NULL || va_image->image_id == VA_INVALID_ID ||
-+ va_surface_id == VA_INVALID_SURFACE || !va_context->valid_context)
-+ return VA_STATUS_ERROR_UNKNOWN;
-+
-+ lprintf("vaapi_software_render_frame : va_surface_id 0x%08x va_image.image_id 0x%08x width %d height %d f_width %d f_height %d sw_width %d sw_height %d\n",
-+ va_surface_id, va_image->image_id, va_image->width, va_image->height, frame->width, frame->height,
-+ va_context->sw_width, va_context->sw_height);
-+
-+ if(frame->width != va_image->width || frame->height != va_image->height)
-+ return VA_STATUS_SUCCESS;
-+
-+ vaStatus = vaMapBuffer( va_context->va_display, va_image->buf, &p_base ) ;
-+ if(!vaapi_check_status(va_context->driver, vaStatus, "vaMapBuffer()"))
-+ return vaStatus;
-+
-+
-+ uint8_t *dst[3] = { NULL, };
-+ uint32_t pitches[3];
-+
-+ if(this->swap_uv_planes) {
-+ dst[0] = (uint8_t *)p_base + va_image->offsets[0]; pitches[0] = va_image->pitches[0];
-+ dst[1] = (uint8_t *)p_base + va_image->offsets[1]; pitches[1] = va_image->pitches[1];
-+ dst[2] = (uint8_t *)p_base + va_image->offsets[2]; pitches[2] = va_image->pitches[2];
-+ } else {
-+ dst[0] = (uint8_t *)p_base + va_image->offsets[0]; pitches[0] = va_image->pitches[0];
-+ dst[1] = (uint8_t *)p_base + va_image->offsets[2]; pitches[1] = va_image->pitches[1];
-+ dst[2] = (uint8_t *)p_base + va_image->offsets[1]; pitches[2] = va_image->pitches[2];
-+ }
-+
-+ /* Copy xine frames into VAAPI images */
-+ if(frame->format == XINE_IMGFMT_YV12) {
-+
-+ if (va_image->format.fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) ||
-+ va_image->format.fourcc == VA_FOURCC( 'I', '4', '2', '0' ) ) {
-+ lprintf("vaapi_software_render_frame yv12 -> yv12 convert\n");
-+
-+ yv12_to_yv12(
-+ /* Y */
-+ frame_gen->base[0], frame_gen->pitches[0],
-+ dst[0], pitches[0],
-+ /* U */
-+ frame_gen->base[1], frame_gen->pitches[1],
-+ dst[1], pitches[1],
-+ /* V */
-+ frame_gen->base[2], frame_gen->pitches[2],
-+ dst[2], pitches[2],
-+ /* width x height */
-+ frame_gen->width, frame_gen->height);
-+
-+ } else if (va_image->format.fourcc == VA_FOURCC( 'N', 'V', '1', '2' )) {
-+ lprintf("vaapi_software_render_frame yv12 -> nv12 convert\n");
-+
-+ yv12_to_nv12(frame_gen->base[0], frame_gen->pitches[0],
-+ frame_gen->base[1], frame_gen->pitches[1],
-+ frame_gen->base[2], frame_gen->pitches[2],
-+ (uint8_t *)p_base + va_image->offsets[0], va_image->pitches[0],
-+ (uint8_t *)p_base + va_image->offsets[1], va_image->pitches[1],
-+ frame_gen->width, frame_gen->height,
-+ va_image->width, va_image->height,
-+ va_image->data_size);
-+
-+ }
-+ } else if (frame->format == XINE_IMGFMT_YUY2) {
-+
-+ if (va_image->format.fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) ||
-+ va_image->format.fourcc == VA_FOURCC( 'I', '4', '2', '0' ) ) {
-+ lprintf("vaapi_software_render_frame yuy2 -> yv12 convert\n");
-+
-+ yuy2_to_yv12(frame_gen->base[0], frame_gen->pitches[0],
-+ dst[0], pitches[0],
-+ dst[1], pitches[1],
-+ dst[2], pitches[2],
-+ frame_gen->width, frame_gen->height);
-+
-+ } else if (va_image->format.fourcc == VA_FOURCC( 'N', 'V', '1', '2' )) {
-+ lprintf("vaapi_software_render_frame yuy2 -> nv12 convert\n");
-+
-+ yuy2_to_nv12(frame_gen->base[0], frame_gen->pitches[0],
-+ (uint8_t *)p_base + va_image->offsets[0], va_image->pitches[0],
-+ (uint8_t *)p_base + va_image->offsets[1], va_image->pitches[1],
-+ frame_gen->width, frame_gen->height,
-+ va_image->width, va_image->height,
-+ va_image->data_size);
-+ }
-+
-+ }
-+
-+ vaStatus = vaUnmapBuffer(va_context->va_display, va_image->buf);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaUnmapBuffer()"))
-+ return vaStatus;
-+
-+ if(!va_context->is_bound) {
-+ vaStatus = vaPutImage(va_context->va_display, va_surface_id, va_image->image_id,
-+ 0, 0, va_image->width, va_image->height,
-+ 0, 0, va_image->width, va_image->height);
-+ if(!vaapi_check_status(va_context->driver, vaStatus, "vaPutImage()"))
-+ return vaStatus;
-+ }
-+
-+ return VA_STATUS_SUCCESS;
-+}
-+
-+static VAStatus vaapi_hardware_render_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen,
-+ VASurfaceID va_surface_id) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ vaapi_frame_t *frame = (vaapi_frame_t *) frame_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
-+ int i = 0;
-+ int interlaced_frame = !frame->vo_frame.progressive_frame;
-+ int top_field_first = frame->vo_frame.top_field_first;
-+ int width, height;
-+
-+ if(frame->format == XINE_IMGFMT_VAAPI) {
-+ width = va_context->width;
-+ height = va_context->height;
-+ } else {
-+ width = (frame->width > va_context->sw_width) ? va_context->sw_width : frame->width;
-+ height = (frame->height > va_context->sw_height) ? va_context->sw_height : frame->height;
-+ }
-+
-+ if(!va_context->valid_context || va_surface_id == VA_INVALID_SURFACE)
-+ return VA_STATUS_ERROR_UNKNOWN;
-+
-+ if(this->opengl_render && !this->valid_opengl_context)
-+ return VA_STATUS_ERROR_UNKNOWN;
-+
-+ /* Final VAAPI rendering. The deinterlacing can be controled by xine config.*/
-+ unsigned int deint = this->deinterlace;
-+ for(i = 0; i <= !!((deint > 1) && interlaced_frame); i++) {
-+ unsigned int flags = (deint && (interlaced_frame) ? (((!!(top_field_first)) ^ i) == 0 ? VA_BOTTOM_FIELD : VA_TOP_FIELD) : VA_FRAME_PICTURE);
-+
-+ //flags |= vaapi_get_colorspace_flags(this_gen);
-+
-+ flags |= VA_CLEAR_DRAWABLE;
-+ flags |= this->scaling_level;
-+
-+ lprintf("Putsrfc srfc 0x%08X flags 0x%08x %dx%d -> %dx%d interlaced %d top_field_first %d\n",
-+ va_surface_id, flags, width, height,
-+ this->sc.output_width, this->sc.output_height,
-+ interlaced_frame, top_field_first);
-+
-+ if(this->opengl_render) {
-+
-+ vaapi_x11_trap_errors();
-+
-+ if(this->opengl_use_tfp) {
-+ lprintf("opengl render tfp\n");
-+ vaStatus = vaPutSurface(va_context->va_display, va_surface_id, this->gl_image_pixmap,
-+ 0, 0, width, height, 0, 0, width, height, NULL, 0, flags);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaPutSurface()"))
-+ return vaStatus;
-+ } else {
-+ lprintf("opengl render\n");
-+ vaStatus = vaCopySurfaceGLX(va_context->va_display, va_context->gl_surface, va_surface_id, flags);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaCopySurfaceGLX()"))
-+ return vaStatus;
-+ }
-+ if(vaapi_x11_untrap_errors())
-+ return VA_STATUS_ERROR_UNKNOWN;
-+
-+ vaapi_glx_flip_page(frame_gen, 0, 0, va_context->width, va_context->height);
-+
-+ } else {
-+
-+ vaStatus = vaPutSurface(va_context->va_display, va_surface_id, this->window,
-+ this->sc.displayed_xoffset, this->sc.displayed_yoffset,
-+ this->sc.displayed_width, this->sc.displayed_height,
-+ this->sc.output_xoffset, this->sc.output_yoffset,
-+ this->sc.output_width, this->sc.output_height,
-+ NULL, 0, flags);
-+ if(!vaapi_check_status(this_gen, vaStatus, "vaPutSurface()"))
-+ return vaStatus;
-+ }
-+ // workaround by johns from vdrportal.de
-+ usleep(1 * 1000);
-+ }
-+ return VA_STATUS_SUCCESS;
-+}
-+
-+/* Used in vaapi_display_frame to determine how long displaying a frame takes
-+ - if slower than 60fps, print a message
-+*/
-+/*
-+static double timeOfDay()
-+{
-+ struct timeval t;
-+ gettimeofday( &t, NULL );
-+ return ((double)t.tv_sec) + (((double)t.tv_usec)/1000000.0);
-+}
-+*/
-+
-+static void vaapi_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ vaapi_frame_t *frame = (vaapi_frame_t *) frame_gen;
-+ vaapi_accel_t *accel = &frame->vaapi_accel_data;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[accel->index];
-+ VASurfaceID va_surface_id = VA_INVALID_SURFACE;
-+ VAImage *va_image = NULL;
-+ VAStatus vaStatus;
-+
-+ lprintf("vaapi_display_frame\n");
-+
-+ /*
-+ if((frame->height < 17 || frame->width < 17) && ((frame->format == XINE_IMGFMT_YV12) || (frame->format == XINE_IMGFMT_YUY2))) {
-+ frame->vo_frame.free( frame_gen );
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " frame size to small width %d height %d\n", frame->height, frame->width);
-+ return;
-+ }
-+ */
-+
-+ /*
-+ * let's see if this frame is different in size / aspect
-+ * ratio from the previous one
-+ */
-+
-+ if ( (frame->width != this->sc.delivered_width)
-+ || (frame->height != this->sc.delivered_height)
-+ || (frame->ratio != this->sc.delivered_ratio)
-+ || (frame->vo_frame.crop_left != this->sc.crop_left)
-+ || (frame->vo_frame.crop_right != this->sc.crop_right)
-+ || (frame->vo_frame.crop_top != this->sc.crop_top)
-+ || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) ) {
-+ lprintf("frame format changed\n");
-+ this->sc.force_redraw = 1;
-+ }
-+
-+ /*
-+ * tell gui that we are about to display a frame,
-+ * ask for offset and output size
-+ */
-+ this->sc.delivered_height = frame->height;
-+ this->sc.delivered_width = frame->width;
-+ this->sc.delivered_ratio = frame->ratio;
-+
-+ this->sc.crop_left = frame->vo_frame.crop_left;
-+ this->sc.crop_right = frame->vo_frame.crop_right;
-+ this->sc.crop_top = frame->vo_frame.crop_top;
-+ this->sc.crop_bottom = frame->vo_frame.crop_bottom;
-+
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+
-+ lprintf("vaapi_display_frame %s frame->width %d frame->height %d va_context->sw_width %d va_context->sw_height %d valid_context %d\n",
-+ (frame->format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((frame->format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2") ,
-+ frame->width, frame->height, va_context->sw_width, va_context->sw_height, va_context->valid_context);
-+
-+ if( ((frame->format == XINE_IMGFMT_YV12) || (frame->format == XINE_IMGFMT_YUY2))
-+ && ((frame->width != va_context->sw_width) ||(frame->height != va_context->sw_height )) ) {
-+
-+ lprintf("vaapi_display_frame %s frame->width %d frame->height %d\n",
-+ (frame->format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((frame->format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2") ,
-+ frame->width, frame->height);
-+
-+ unsigned int last_sub_img_fmt = va_context->last_sub_image_fmt;
-+
-+ if(last_sub_img_fmt)
-+ vaapi_ovl_associate(this_gen, frame_gen->format, 0);
-+
-+ if(!va_context->valid_context) {
-+ lprintf("vaapi_display_frame init full context\n");
-+ vaapi_init_internal(frame_gen->driver, SW_CONTEXT_INIT_FORMAT, frame->width, frame->height, 0);
-+ } else {
-+ lprintf("vaapi_display_frame init soft surfaces\n");
-+ vaapi_init_soft_surfaces(frame_gen->driver, frame->width, frame->height);
-+ }
-+
-+ this->sc.force_redraw = 1;
-+ this->init_opengl_render = 1;
-+
-+ if(last_sub_img_fmt)
-+ vaapi_ovl_associate(this_gen, frame_gen->format, this->has_overlay);
-+ }
-+
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+
-+ vaapi_redraw_needed (this_gen);
-+
-+ /* posible race could happen while the lock is opened */
-+ if(!this->va_context || !this->va_context->valid_context)
-+ return;
-+
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+
-+ /* initialize opengl rendering */
-+ if(this->opengl_render && this->init_opengl_render && va_context->valid_context) {
-+ unsigned int last_sub_img_fmt = va_context->last_sub_image_fmt;
-+
-+ if(last_sub_img_fmt)
-+ vaapi_ovl_associate(this_gen, frame_gen->format, 0);
-+
-+ destroy_glx(this_gen);
-+
-+ vaapi_glx_config_glx(frame_gen->driver, va_context->width, va_context->height);
-+
-+ vaapi_resize_glx_window(frame_gen->driver, this->sc.gui_width, this->sc.gui_height);
-+
-+ if(last_sub_img_fmt)
-+ vaapi_ovl_associate(this_gen, frame_gen->format, this->has_overlay);
-+
-+ this->sc.force_redraw = 1;
-+ this->init_opengl_render = 0;
-+ }
-+
-+ /*
-+ double start_time;
-+ double end_time;
-+ double elapse_time;
-+ int factor;
-+
-+ start_time = timeOfDay();
-+ */
-+
-+ if(va_context->valid_context && ( (frame->format == XINE_IMGFMT_VAAPI) || (frame->format == XINE_IMGFMT_YV12) || (frame->format == XINE_IMGFMT_YUY2) )) {
-+
-+ if((frame->format == XINE_IMGFMT_YUY2) || (frame->format == XINE_IMGFMT_YV12)) {
-+ va_surface_id = va_soft_surface_ids[va_context->va_soft_head];
-+ va_image = &va_soft_images[va_context->va_soft_head];
-+ va_context->va_soft_head = (va_context->va_soft_head + 1) % (SOFT_SURFACES);
-+ }
-+
-+ if(this->guarded_render) {
-+ if(frame->format == XINE_IMGFMT_VAAPI) {
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[accel->index];
-+ if(va_surface->status == SURFACE_RENDER || va_surface->status == SURFACE_RENDER_RELEASE) {
-+ va_surface_id = va_surface->va_surface_id;
-+ }
-+ va_image = NULL;
-+ }
-+#ifdef DEBUG_SURFACE
-+ printf("vaapi_display_frame va_surface 0x%08x status %d index %d\n", va_surface_id, va_surface->status, accel->index);
-+#endif
-+ } else {
-+ if(frame->format == XINE_IMGFMT_VAAPI) {
-+ va_surface_id = va_surface->va_surface_id;
-+ va_image = NULL;
-+ }
-+ }
-+
-+ lprintf("2: 0x%08x\n", va_surface_id);
-+
-+ VASurfaceStatus surf_status = 0;
-+ if(va_surface_id != VA_INVALID_SURFACE) {
-+
-+ if(this->query_va_status) {
-+ vaStatus = vaQuerySurfaceStatus(va_context->va_display, va_surface_id, &surf_status);
-+ vaapi_check_status(this_gen, vaStatus, "vaQuerySurfaceStatus()");
-+ } else {
-+ surf_status = VASurfaceReady;
-+ }
-+
-+ if(surf_status != VASurfaceReady) {
-+ va_surface_id = VA_INVALID_SURFACE;
-+ va_image = NULL;
-+#ifdef DEBUG_SURFACE
-+ printf("Surface srfc 0x%08X not ready for render\n", va_surface_id);
-+#endif
-+ }
-+ } else {
-+#ifdef DEBUG_SURFACE
-+ printf("Invalid srfc 0x%08X\n", va_surface_id);
-+#endif
-+ }
-+
-+ if(va_surface_id != VA_INVALID_SURFACE) {
-+
-+ lprintf("vaapi_display_frame: 0x%08x %d %d\n", va_surface_id, va_context->width, va_context->height);
-+
-+ vaStatus = vaSyncSurface(va_context->va_display, va_surface_id);
-+ vaapi_check_status(this_gen, vaStatus, "vaSyncSurface()");
-+
-+ /* transfer image data to a VAAPI surface */
-+ if((frame->format == XINE_IMGFMT_YUY2 || frame->format == XINE_IMGFMT_YV12))
-+ vaapi_software_render_frame(this_gen, frame_gen, va_image, va_surface_id);
-+
-+ vaapi_hardware_render_frame(this_gen, frame_gen, va_surface_id);
-+
-+ }
-+ } else {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " unsupported image format %s width %d height %d valid_context %d\n",
-+ (frame->format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((frame->format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2") ,
-+ frame->width, frame->height, va_context->valid_context);
-+ }
-+
-+ XSync(this->display, False);
-+
-+ //end_time = timeOfDay();
-+
-+ if(this->guarded_render) {
-+ ff_vaapi_surface_t *va_surface = &va_render_surfaces[accel->index];
-+
-+ if(va_surface->status == SURFACE_RENDER_RELEASE) {
-+ va_surface->status = SURFACE_FREE;
-+#ifdef DEBUG_SURFACE
-+ printf("release_surface vaapi_display_frame 0x%08x\n", va_surface->va_surface_id);
-+#endif
-+ } else if(va_surface->status == SURFACE_RENDER) {
-+ va_surface->status = SURFACE_RELEASE;
-+#ifdef DEBUG_SURFACE
-+ printf("release_surface vaapi_display_frame 0x%08x\n", va_surface->va_surface_id);
-+#endif
-+ }
-+ }
-+
-+ DO_UNLOCKDISPLAY;
-+
-+ frame->vo_frame.free( frame_gen );
-+
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+
-+ /*
-+ elapse_time = end_time - start_time;
-+ factor = (int)(elapse_time/(1.0/60.0));
-+
-+ if( factor > 1 )
-+ {
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " PutImage %dX interval (%fs)\n", factor, elapse_time );
-+ }
-+ */
-+}
-+
-+static int vaapi_get_property (vo_driver_t *this_gen, int property) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ switch (property) {
-+ case VO_PROP_WINDOW_WIDTH:
-+ this->props[property].value = this->sc.gui_width;
-+ break;
-+ case VO_PROP_WINDOW_HEIGHT:
-+ this->props[property].value = this->sc.gui_height;
-+ break;
-+ case VO_PROP_OUTPUT_WIDTH:
-+ this->props[property].value = this->sc.output_width;
-+ break;
-+ case VO_PROP_OUTPUT_HEIGHT:
-+ this->props[property].value = this->sc.output_height;
-+ break;
-+ case VO_PROP_OUTPUT_XOFFSET:
-+ this->props[property].value = this->sc.output_xoffset;
-+ break;
-+ case VO_PROP_OUTPUT_YOFFSET:
-+ this->props[property].value = this->sc.output_yoffset;
-+ break;
-+ case VO_PROP_MAX_NUM_FRAMES:
-+ if(!this->guarded_render)
-+ this->props[property].value = RENDER_SURFACES;
-+ else
-+ this->props[property].value = 2;
-+ break;
-+ }
-+
-+ lprintf("vaapi_get_property property=%d, value=%d\n", property, this->props[property].value );
-+
-+ return this->props[property].value;
-+}
-+
-+static int vaapi_set_property (vo_driver_t *this_gen, int property, int value) {
-+
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ lprintf("vaapi_set_property property=%d, value=%d\n", property, value );
-+
-+ if(this->props[property].atom) {
-+ VADisplayAttribute attr;
-+
-+ if((value < this->props[property].min) || (value > this->props[property].max))
-+ value = (this->props[property].min + this->props[property].max) >> 1;
-+
-+ this->props[property].value = value;
-+ attr.type = this->props[property].type;
-+ attr.value = value;
-+
-+ if(va_context && va_context->valid_context) {
-+ vaSetDisplayAttributes(va_context->va_display, &attr, 1);
-+ //vaapi_check_status((vo_driver_t *)this, vaStatus, "vaSetDisplayAttributes()");
-+ }
-+
-+ if (this->props[property].entry)
-+ this->props[property].entry->num_value = this->props[property].value;
-+
-+ vaapi_show_display_props((vo_driver_t*)this);
-+
-+ return this->props[property].value;
-+ } else {
-+ switch (property) {
-+
-+ case VO_PROP_ASPECT_RATIO:
-+ if (value>=XINE_VO_ASPECT_NUM_RATIOS)
-+ value = XINE_VO_ASPECT_AUTO;
-+ this->props[property].value = value;
-+ this->sc.user_ratio = value;
-+ _x_vo_scale_compute_ideal_size (&this->sc);
-+ this->sc.force_redraw = 1;
-+ break;
-+
-+ case VO_PROP_ZOOM_X:
-+ if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) {
-+ this->props[property].value = value;
-+ this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP;
-+ _x_vo_scale_compute_ideal_size (&this->sc);
-+ this->sc.force_redraw = 1;
-+ }
-+ break;
-+
-+ case VO_PROP_ZOOM_Y:
-+ if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) {
-+ this->props[property].value = value;
-+ this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP;
-+ _x_vo_scale_compute_ideal_size (&this->sc);
-+ this->sc.force_redraw = 1;
-+ }
-+ break;
-+ }
-+ }
-+ return value;
-+}
-+
-+static void vaapi_get_property_min_max (vo_driver_t *this_gen,
-+ int property, int *min, int *max) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ *min = this->props[property].min;
-+ *max = this->props[property].max;
-+}
-+
-+static int vaapi_gui_data_exchange (vo_driver_t *this_gen,
-+ int data_type, void *data) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ lprintf("vaapi_gui_data_exchange %d\n", data_type);
-+
-+ switch (data_type) {
-+#ifndef XINE_DISABLE_DEPRECATED_FEATURES
-+ case XINE_GUI_SEND_COMPLETION_EVENT:
-+ break;
-+#endif
-+
-+ case XINE_GUI_SEND_EXPOSE_EVENT: {
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+ lprintf("XINE_GUI_SEND_EXPOSE_EVENT:\n");
-+ this->sc.force_redraw = 1;
-+ this->init_opengl_render = 1;
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+ }
-+ break;
-+
-+ case XINE_GUI_SEND_WILL_DESTROY_DRAWABLE: {
-+ printf("XINE_GUI_SEND_WILL_DESTROY_DRAWABLE\n");
-+ }
-+ break;
-+
-+ case XINE_GUI_SEND_DRAWABLE_CHANGED: {
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+ lprintf("XINE_GUI_SEND_DRAWABLE_CHANGED\n");
-+
-+ this->drawable = (Drawable) data;
-+
-+ XReparentWindow(this->display, this->window, this->drawable, 0, 0);
-+
-+ this->sc.force_redraw = 1;
-+ this->init_opengl_render = 1;
-+
-+ DO_UNLOCKDISPLAY;
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+ }
-+ break;
-+
-+ case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: {
-+ int x1, y1, x2, y2;
-+ x11_rectangle_t *rect = data;
-+
-+ _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1);
-+ _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2);
-+ rect->x = x1;
-+ rect->y = y1;
-+ rect->w = x2-x1;
-+ rect->h = y2-y1;
-+ }
-+ break;
-+
-+ default:
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static void vaapi_dispose (vo_driver_t *this_gen) {
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+ ff_vaapi_context_t *va_context = this->va_context;
-+
-+ lprintf("vaapi_dispose\n");
-+
-+ pthread_mutex_lock(&this->vaapi_lock);
-+ DO_LOCKDISPLAY;
-+
-+ this->ovl_yuv2rgb->dispose(this->ovl_yuv2rgb);
-+ this->yuv2rgb_factory->dispose (this->yuv2rgb_factory);
-+
-+ vaapi_close(this_gen);
-+ free(va_context);
-+
-+ if(this->overlay_bitmap)
-+ free(this->overlay_bitmap);
-+
-+ if(va_surface_ids)
-+ free(va_surface_ids);
-+ if(va_soft_surface_ids)
-+ free(va_soft_surface_ids);
-+ if(va_render_surfaces)
-+ free(va_render_surfaces);
-+ if(va_soft_images)
-+ free(va_soft_images);
-+
-+ XDestroyWindow(this->display, this->window);
-+ DO_UNLOCKDISPLAY;
-+
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+ pthread_mutex_destroy(&this->vaapi_lock);
-+
-+ free (this);
-+}
-+
-+static void vaapi_vdr_osd_width_flag( void *this_gen, xine_cfg_entry_t *entry )
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ this->vdr_osd_width = entry->num_value;
-+}
-+
-+static void vaapi_vdr_osd_height_flag( void *this_gen, xine_cfg_entry_t *entry )
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ this->vdr_osd_height = entry->num_value;
-+}
-+
-+static void vaapi_deinterlace_flag( void *this_gen, xine_cfg_entry_t *entry )
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ this->deinterlace = entry->num_value;
-+ if(this->deinterlace > 2)
-+ this->deinterlace = 2;
-+}
-+
-+static void vaapi_opengl_render( void *this_gen, xine_cfg_entry_t *entry )
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ this->opengl_render = entry->num_value;
-+}
-+
-+static void vaapi_opengl_use_tfp( void *this_gen, xine_cfg_entry_t *entry )
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ this->opengl_use_tfp = entry->num_value;
-+}
-+
-+static void vaapi_guarded_render( void *this_gen, xine_cfg_entry_t *entry )
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ this->guarded_render = entry->num_value;
-+}
-+
-+static void vaapi_scaling_level( void *this_gen, xine_cfg_entry_t *entry )
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ this->scaling_level = entry->num_value;
-+}
-+
-+static void vaapi_swap_uv_planes(void *this_gen, xine_cfg_entry_t *entry)
-+{
-+ vaapi_driver_t *this = (vaapi_driver_t *) this_gen;
-+
-+ this->swap_uv_planes = entry->num_value;
-+}
-+
-+static vo_driver_t *vaapi_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) {
-+
-+ vaapi_class_t *class = (vaapi_class_t *) class_gen;
-+ x11_visual_t *visual = (x11_visual_t *) visual_gen;
-+ vaapi_driver_t *this;
-+ config_values_t *config = class->config;
-+ XSetWindowAttributes xswa;
-+ unsigned long xswa_mask;
-+ XWindowAttributes wattr;
-+ unsigned long black_pixel;
-+ XVisualInfo visualInfo;
-+ XVisualInfo *vi;
-+ int depth;
-+ const int x11_event_mask = ExposureMask |
-+ StructureNotifyMask;
-+
-+ this = (vaapi_driver_t *) calloc(1, sizeof(vaapi_driver_t));
-+ if (!this)
-+ return NULL;
-+
-+ this->config = config;
-+ this->xine = class->xine;
-+
-+ this->display = visual->display;
-+ this->screen = visual->screen;
-+ this->drawable = visual->d;
-+
-+ this->va_context = calloc(1, sizeof(ff_vaapi_context_t));
-+
-+#ifdef LOCKDISPLAY
-+ guarded_display = visual->display;
-+#endif
-+
-+ /* number of video frames from config - register it with the default value. */
-+ int frame_num = config->register_num (config, "engine.buffers.video_num_frames", RENDER_SURFACES, /* default */
-+ _("default number of video frames"),
-+ _("The default number of video frames to request "
-+ "from xine video out driver. Some drivers will "
-+ "override this setting with their own values."),
-+ 20, NULL, this);
-+
-+ /* now make sure we have at least 22 frames, to prevent
-+ * locks with vdpau_h264 */
-+ if(frame_num != RENDER_SURFACES)
-+ config->update_num(config,"engine.buffers.video_num_frames", RENDER_SURFACES);
-+
-+ this->opengl_render = config->register_bool( config, "video.output.vaapi_opengl_render", 0,
-+ _("vaapi: opengl output rendering"),
-+ _("vaapi: opengl output rendering"),
-+ 20, vaapi_opengl_render, this );
-+
-+ this->init_opengl_render = 1;
-+
-+ this->opengl_use_tfp = config->register_bool( config, "video.output.vaapi_opengl_use_tfp", 0,
-+ _("vaapi: opengl rendering tfp"),
-+ _("vaapi: opengl rendering tfp"),
-+ 20, vaapi_opengl_use_tfp, this );
-+
-+ if(this->opengl_render) {
-+ this->opengl_render = vaapi_opengl_verify_direct ((x11_visual_t *)visual_gen);
-+ if(!this->opengl_render)
-+ xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Opengl indirect/software rendering does not work. Fallback to plain VAAPI output !!!!\n");
-+ }
-+
-+ this->valid_opengl_context = 0;
-+ this->gl_vinfo = NULL;
-+ this->gl_pixmap = None;
-+ this->gl_image_pixmap = None;
-+ this->gl_texture = GL_NONE;
-+
-+ this->num_frame_buffers = 0;
-+
-+ va_render_surfaces = calloc(RENDER_SURFACES + 1, sizeof(ff_vaapi_surface_t));
-+ va_surface_ids = calloc(RENDER_SURFACES + 1, sizeof(VASurfaceID));
-+ va_soft_surface_ids = calloc(SOFT_SURFACES + 1, sizeof(VASurfaceID));
-+ va_soft_images = calloc(SOFT_SURFACES + 1, sizeof(VAImage));
-+
-+ vaapi_init_va_context(this);
-+ vaapi_init_subpicture(this);
-+
-+ _x_vo_scale_init (&this->sc, 1, 0, config );
-+
-+ this->sc.frame_output_cb = visual->frame_output_cb;
-+ this->sc.dest_size_cb = visual->dest_size_cb;
-+ this->sc.user_data = visual->user_data;
-+ this->sc.user_ratio = XINE_VO_ASPECT_AUTO;
-+
-+ black_pixel = BlackPixel(this->display, this->screen);
-+
-+ XGetWindowAttributes(this->display, this->drawable, &wattr);
-+
-+ depth = wattr.depth;
-+ if (depth != 15 && depth != 16 && depth != 24 && depth != 32)
-+ depth = 24;
-+
-+ vi = &visualInfo;
-+ XMatchVisualInfo(this->display, this->screen, depth, TrueColor, vi);
-+
-+ xswa_mask = CWBorderPixel | CWBackPixel | CWColormap;
-+ xswa.border_pixel = black_pixel;
-+ xswa.background_pixel = black_pixel;
-+ xswa.colormap = CopyFromParent;
-+
-+ this->window = XCreateWindow(this->display, this->drawable,
-+ 0, 0, 1, 1, 0, depth,
-+ InputOutput, vi->visual, xswa_mask, &xswa);
-+
-+ if(this->window == None)
-+ return NULL;
-+
-+ XSelectInput(this->display, this->window, x11_event_mask);
-+
-+ XMapWindow(this->display, this->window);
-+ vaapi_x11_wait_event(this->display, this->window, MapNotify);
-+
-+ if(vi != &visualInfo)
-+ XFree(vi);
-+
-+ this->capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP | VO_CAP_UNSCALED_OVERLAY | VO_CAP_ARGB_LAYER_OVERLAY | VO_CAP_VAAPI | VO_CAP_CUSTOM_EXTENT_OVERLAY;
-+
-+ /* overlay converter */
-+ this->yuv2rgb_factory = yuv2rgb_factory_init (MODE_24_BGR, 0, NULL);
-+ this->ovl_yuv2rgb = this->yuv2rgb_factory->create_converter( this->yuv2rgb_factory );
-+
-+ this->vo_driver.get_capabilities = vaapi_get_capabilities;
-+ this->vo_driver.alloc_frame = vaapi_alloc_frame;
-+ this->vo_driver.update_frame_format = vaapi_update_frame_format;
-+ this->vo_driver.overlay_begin = vaapi_overlay_begin;
-+ this->vo_driver.overlay_blend = vaapi_overlay_blend;
-+ this->vo_driver.overlay_end = vaapi_overlay_end;
-+ this->vo_driver.display_frame = vaapi_display_frame;
-+ this->vo_driver.get_property = vaapi_get_property;
-+ this->vo_driver.set_property = vaapi_set_property;
-+ this->vo_driver.get_property_min_max = vaapi_get_property_min_max;
-+ this->vo_driver.gui_data_exchange = vaapi_gui_data_exchange;
-+ this->vo_driver.dispose = vaapi_dispose;
-+ this->vo_driver.redraw_needed = vaapi_redraw_needed;
-+
-+ this->deinterlace = 0;
-+ this->vdr_osd_width = 0;
-+ this->vdr_osd_height = 0;
-+
-+ this->vdr_osd_width = config->register_num( config, "video.output.vaapi_vdr_osd_width", 0,
-+ _("vaapi: VDR osd width workaround."),
-+ _("vaapi: VDR osd width workaround."),
-+ 10, vaapi_vdr_osd_width_flag, this );
-+
-+ this->vdr_osd_height = config->register_num( config, "video.output.vaapi_vdr_osd_height", 0,
-+ _("vaapi: VDR osd height workaround."),
-+ _("vaapi: VDR osd height workaround."),
-+ 10, vaapi_vdr_osd_height_flag, this );
-+
-+ this->deinterlace = config->register_num( config, "video.output.vaapi_deinterlace", 0,
-+ _("vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )."),
-+ _("vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )."),
-+ 10, vaapi_deinterlace_flag, this );
-+
-+ this->guarded_render = config->register_num( config, "video.output.vaapi_guarded_render", 1,
-+ _("vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )"),
-+ _("vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )"),
-+ 10, vaapi_guarded_render, this );
-+
-+ this->scaling_level_enum = config->register_enum(config, "video.output.vaapi_scaling_level", 0,
-+ (char **)scaling_level_enum_names,
-+ _("vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla (anamorphic)"),
-+ _("vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla (anamorphic)"),
-+ 10, vaapi_scaling_level, this);
-+
-+ this->scaling_level = scaling_level_enum_values[this->scaling_level_enum];
-+
-+ this->swap_uv_planes = config->register_bool( config, "video.output.vaapi_swap_uv_planes", 0,
-+ _("vaapi: swap UV planes."),
-+ _("vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n"
-+ "There the UV planes are swapped.\n"),
-+ 10, vaapi_swap_uv_planes, this);
-+
-+
-+ pthread_mutex_init(&this->vaapi_lock, NULL);
-+
-+ pthread_mutex_lock(&this->vaapi_lock);
-+
-+ int i;
-+ for (i = 0; i < VO_NUM_PROPERTIES; i++) {
-+ this->props[i].value = 0;
-+ this->props[i].min = 0;
-+ this->props[i].max = 0;
-+ this->props[i].atom = 0;
-+ this->props[i].entry = NULL;
-+ this->props[i].this = this;
-+ }
-+
-+ this->sc.user_ratio =
-+ this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO;
-+ this->props[VO_PROP_ZOOM_X].value = 100;
-+ this->props[VO_PROP_ZOOM_Y].value = 100;
-+
-+ this->va_context->last_sub_surface_id = VA_INVALID_SURFACE;
-+ this->va_context->last_sub_image_fmt = 0;
-+
-+ if(vaapi_init_internal((vo_driver_t *)this, SW_CONTEXT_INIT_FORMAT, SW_WIDTH, SW_HEIGHT, 0) != VA_STATUS_SUCCESS) {
-+ vaapi_dispose((vo_driver_t *)this);
-+ return NULL;
-+ }
-+ vaapi_close((vo_driver_t *)this);
-+ this->va_context->valid_context = 0;
-+ this->va_context->driver = (vo_driver_t *)this;
-+
-+ pthread_mutex_unlock(&this->vaapi_lock);
-+
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Deinterlace : %d\n", this->deinterlace);
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Render surfaces : %d\n", RENDER_SURFACES);
-+ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Opengl render : %d\n", this->opengl_render);
-+
-+ return &this->vo_driver;
-+}
-+
-+/*
-+ * class functions
-+ */
-+static void *vaapi_init_class (xine_t *xine, void *visual_gen) {
-+ vaapi_class_t *this = (vaapi_class_t *) calloc(1, sizeof(vaapi_class_t));
-+
-+ this->driver_class.open_plugin = vaapi_open_plugin;
-+ this->driver_class.identifier = "vaapi";
-+ this->driver_class.description = N_("xine video output plugin using the MIT X video extension");
-+ this->driver_class.dispose = default_video_driver_class_dispose;
-+ this->config = xine->config;
-+ this->xine = xine;
-+
-+ return this;
-+}
-+
-+static const vo_info_t vo_info_vaapi = {
-+ 9, /* priority */
-+ XINE_VISUAL_TYPE_X11 /* visual type */
-+};
-+
-+/*
-+ * exported plugin catalog entry
-+ */
-+
-+const plugin_info_t xine_plugin_info[] EXPORTED = {
-+ /* type, API, "name", version, special_info, init_function */
-+ { PLUGIN_VIDEO_OUT, 22, "vaapi", XINE_VERSION_CODE, &vo_info_vaapi, vaapi_init_class },
-+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-+};
-diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am
-index 6fc6890..437c8bd 100644
---- a/src/xine-engine/Makefile.am
-+++ b/src/xine-engine/Makefile.am
-@@ -11,7 +11,7 @@ XINEUTILS_LIB = $(top_builddir)/src/xine-utils/libxineutils.la
- YUV_LIB = $(top_builddir)/src/video_out/libyuv2rgb.la
-
- # FIXME: these are currently unused:
--EXTRA_DIST = lrb.c lrb.h accel_vdpau.h accel_xvmc.h
-+EXTRA_DIST = lrb.c lrb.h accel_vdpau.h accel_vaapi.h accel_xvmc.h
-
- if WIN32
- DEF_FILE = libxine-$(XINE_MAJOR).def
-diff --git a/src/xine-engine/accel_vaapi.h b/src/xine-engine/accel_vaapi.h
-new file mode 100644
-index 0000000..666b23f
---- /dev/null
-+++ b/src/xine-engine/accel_vaapi.h
-@@ -0,0 +1,135 @@
-+/*
-+ * Copyright (C) 2008 the xine project
-+ *
-+ * This file is part of xine, a free video player.
-+ *
-+ * xine 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.
-+ *
-+ * xine 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 this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
-+ *
-+ *
-+ * Common acceleration definitions for vdpau
-+ *
-+ *
-+ */
-+
-+#ifndef HAVE_XINE_ACCEL_VAAPI_H
-+#define HAVE_XINE_ACCEL_VAAPI_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+#include <va/va_x11.h>
-+#include <pthread.h>
-+#ifdef HAVE_FFMPEG_AVUTIL_H
-+# include <avcodec.h>
-+#else
-+# include <libavcodec/avcodec.h>
-+#endif
-+
-+#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 32)
-+# define AVVIDEO 2
-+#else
-+# define AVVIDEO 1
-+# define pp_context pp_context_t
-+# define pp_mode pp_mode_t
-+#endif
-+
-+#define NUM_OUTPUT_SURFACES 22
-+
-+#define SURFACE_FREE 0
-+#define SURFACE_ALOC 1
-+#define SURFACE_RELEASE 2
-+#define SURFACE_RENDER 3
-+#define SURFACE_RENDER_RELEASE 5
-+
-+struct vaapi_equalizer {
-+ VADisplayAttribute brightness;
-+ VADisplayAttribute contrast;
-+ VADisplayAttribute hue;
-+ VADisplayAttribute saturation;
-+};
-+
-+typedef struct ff_vaapi_context_s ff_vaapi_context_t;
-+
-+struct ff_vaapi_context_s {
-+ VADisplay va_display;
-+ VAContextID va_context_id;
-+ VAConfigID va_config_id;
-+ int width;
-+ int height;
-+ int sw_width;
-+ int sw_height;
-+ int va_profile;
-+ unsigned int va_colorspace;
-+ VAImage va_subpic_image;
-+ VASubpictureID va_subpic_id;
-+ int va_subpic_width;
-+ int va_subpic_height;
-+ int is_bound;
-+ void *gl_surface;
-+ unsigned int soft_head;
-+ unsigned int valid_context;
-+ unsigned int va_head;
-+ unsigned int va_soft_head;
-+ vo_driver_t *driver;
-+ unsigned int last_sub_image_fmt;
-+ VASurfaceID last_sub_surface_id;
-+ struct vaapi_equalizer va_equalizer;
-+ VAImageFormat *va_image_formats;
-+ int va_num_image_formats;
-+ VAImageFormat *va_subpic_formats;
-+ int va_num_subpic_formats;
-+};
-+
-+typedef struct ff_vaapi_surface_s ff_vaapi_surface_t;
-+typedef struct vaapi_accel_s vaapi_accel_t;
-+
-+struct ff_vaapi_surface_s {
-+ unsigned int index;
-+ vaapi_accel_t *accel;
-+ VASurfaceID va_surface_id;
-+ unsigned int status;
-+};
-+
-+struct vaapi_accel_s {
-+ unsigned int index;
-+ vo_frame_t *vo_frame;
-+
-+#if AVVIDEO > 1
-+ int (*avcodec_decode_video2)(vo_frame_t *frame_gen, AVCodecContext *avctx, AVFrame *picture,
-+ int *got_picture_ptr, AVPacket *avpkt);
-+#else
-+ int (*avcodec_decode_video)(vo_frame_t *frame_gen, AVCodecContext *avctx, AVFrame *picture,
-+ int *got_picture_ptr, uint8_t *buf, int buf_size);
-+#endif
-+ VAStatus (*vaapi_init)(vo_frame_t *frame_gen, int va_profile, int width, int height, int softrender);
-+ int (*profile_from_imgfmt)(vo_frame_t *frame_gen, enum PixelFormat pix_fmt, int codec_id, int vaapi_mpeg_sofdec);
-+ ff_vaapi_context_t *(*get_context)(vo_frame_t *frame_gen);
-+ int (*guarded_render)(vo_frame_t *frame_gen);
-+ ff_vaapi_surface_t *(*get_vaapi_surface)(vo_frame_t *frame_gen);
-+ void (*render_vaapi_surface)(vo_frame_t *frame_gen, ff_vaapi_surface_t *va_surface);
-+ void (*release_vaapi_surface)(vo_frame_t *frame_gen, ff_vaapi_surface_t *va_surface);
-+};
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
-+
-diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
-index 8a2cc4b..584eeed 100644
---- a/src/xine-engine/video_out.c
-+++ b/src/xine-engine/video_out.c
-@@ -737,6 +737,13 @@ static vo_frame_t *vo_get_frame (xine_video_port_t *this_gen,
- return img;
- }
-
-+static double tt()
-+{
-+ struct timeval tv;
-+ gettimeofday(&tv, 0);
-+ return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
-+}
-+
- static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) {
-
- vos_t *this = (vos_t *) img->port;
-@@ -746,6 +753,30 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) {
- int frames_to_skip;
- int duration;
-
-+/*
-+if (1)
-+{
-+ double t1 = tt();
-+ static double t0 = -1;
-+ if (t0 == -1) t0 = t1;
-+ double dt = t1 - t0;
-+ t0 = t1;
-+ static int64_t pts = 0;
-+ fprintf(stderr, "img->pts: %12" PRId64 ", pts: %12" PRId64 ", img->duration: %4d, time since last vo_frame_draw: %7.3lf ms", img->pts, pts, img->duration, dt);
-+ if (img->pts)
-+ {
-+ if (pts != img->pts)
-+ fprintf(stderr, " ERROR: %12" PRId64 "", img->pts - pts);
-+ pts = img->pts + img->duration;
-+ }
-+ else
-+ {
-+ pts += img->duration;
-+ }
-+ fprintf(stderr, "\n");
-+}
-+*/
-+
- /* handle anonymous streams like NULL for easy checking */
- if (stream == XINE_ANON_STREAM) stream = NULL;
-
diff --git a/multimedia/libxine/pkg-plist b/multimedia/libxine/pkg-plist
index f19f6c992cb1..3df44a2a4486 100644
--- a/multimedia/libxine/pkg-plist
+++ b/multimedia/libxine/pkg-plist
@@ -181,6 +181,7 @@ share/xine-lib/fonts/serif-64.xinefont.gz
%%PLUGINSDIR%%/xineplug_vo_out_xcbxv.so
%%PLUGINSDIR%%/xineplug_vo_out_xshm.so
%%PLUGINSDIR%%/xineplug_vo_out_xv.so
+%%VAAPI%%%%PLUGINSDIR%%/xineplug_vo_out_vaapi.so
%%WITH_XVMC%%%%PLUGINSDIR%%/xineplug_vo_out_xvmc.so
%%WITH_XVMC%%%%PLUGINSDIR%%/xineplug_vo_out_xxmc.so
%%WITH_WAVPACK%%%%PLUGINSDIR%%/xineplug_wavpack.so