diff options
author | Juergen Lock <nox@FreeBSD.org> | 2013-11-23 19:20:55 +0000 |
---|---|---|
committer | Juergen Lock <nox@FreeBSD.org> | 2013-11-23 19:20:55 +0000 |
commit | a268657341ecf6cfa8ef072615d421393c41f496 (patch) | |
tree | 8ed126684fc5ca301458a6369f1d30d1f419d37e /multimedia | |
parent | dacd35c759ae64348cd18f0579a1f57dbf089c9e (diff) | |
download | ports-a268657341ecf6cfa8ef072615d421393c41f496.tar.gz ports-a268657341ecf6cfa8ef072615d421393c41f496.zip |
Notes
Diffstat (limited to 'multimedia')
-rw-r--r-- | multimedia/libxine/Makefile | 11 | ||||
-rw-r--r-- | multimedia/libxine/files/extrapatch-vdpau-configure.ac | 11 | ||||
-rw-r--r-- | multimedia/libxine/files/extrapatch-vdpau-src-vdr-input_vdr.c | 12 | ||||
-rw-r--r-- | multimedia/libxine/files/extrapatch-vdpau-src-video_out-video_out_vdpau.c | 91 | ||||
-rw-r--r-- | multimedia/libxine/files/ffmpeg-vaapi_xine-lib-1.2.2-defaultoff.diff | 5997 | ||||
-rw-r--r-- | multimedia/libxine/pkg-plist | 1 |
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 |