Index: Makefile =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/Makefile,v retrieving revision 1.177 diff -u -p -r1.177 Makefile --- Makefile 18 Jan 2012 17:36:26 -0000 1.177 +++ Makefile 6 Feb 2012 18:01:54 -0000 @@ -6,16 +6,12 @@ # PORTNAME= xine -PORTVERSION= 1.1.19 -PORTREVISION= 9 +PORTVERSION= 1.2.1 CATEGORIES= multimedia ipv6 MASTER_SITES= SF/${PORTNAME}/${PORTNAME}-lib/${PORTVERSION} PKGNAMEPREFIX= lib DISTNAME= ${PORTNAME}-lib-${PORTVERSION} -PATCH_SITES= ${MASTER_SITE_LOCAL} -PATCH_SITE_SUBDIR= makc - MAINTAINER= nox@FreeBSD.org COMMENT= Libraries for xine multimedia player @@ -34,7 +30,8 @@ LIB_DEPENDS= FLAC.10:${PORTSDIR}/audio/f mad.2:${PORTSDIR}/audio/libmad \ dca.0:${PORTSDIR}/multimedia/libdca \ avcodec.1:${PORTSDIR}/multimedia/ffmpeg \ - faad.2:${PORTSDIR}/audio/faad + faad.2:${PORTSDIR}/audio/faad \ + vdpau.1:${PORTSDIR}/multimedia/libvdpau .if !defined(PACKAGE_BUILDING) LIB_DEPENDS+= dvdcss.${DVDCSS_LIBVERSION}:${PORTSDIR}/multimedia/libdvdcss @@ -65,11 +62,11 @@ CONFIGURE_ARGS= --with-w32-path=${LOCALB --with-external-ffmpeg \ --with-external-libfaad \ --disable-v4l \ - --without-alsa + --without-alsa \ + --disable-musepack MAKE_JOBS_SAFE= yes -OPTIONS= ARTS "Enable aRts support" off \ - CACA "Enable libcaca support" off \ +OPTIONS= CACA "Enable libcaca support" off \ ESOUND "Enable EsounD support" off \ JACK "Enable JACK support" off \ GNOMEVFS2 "Enable GnomeVFS2 support" off \ @@ -80,14 +77,13 @@ OPTIONS= ARTS "Enable aRts support" off IMAGEMAGICK "Enable ImageMagick support" off \ GTK2 "Enable gdkpixbuf support" off \ WAVPACK "Enable WavPack support" off \ - VAAPI "Enable VAAPI support" off \ - VDPAU "Enable VDPAU support" on + VAAPI "Enable VAAPI support" off -MAN1= xine-config.1 xine-list-1.1.1 +MAN1= xine-config.1 xine-list-1.2.1 MAN5= xine.5 DOCSDIR= ${PREFIX}/share/doc/xine-lib -PLIST_SUB= PLUGINSDIR="lib/xine/plugins/1.29" +PLIST_SUB= PLUGINSDIR="lib/xine/plugins/2.1" # DVDCSS version hardcoded in src/input/input_dvd.c misc/cdda_server.c # and src/input/libdvdnav/dvd_input.c (dlopen'ed) @@ -116,15 +112,6 @@ PLIST_SUB+= NLS="@comment " CONFIGURE_ARGS+= --disable-nls .endif -.if defined(WITH_ARTS) -LIB_DEPENDS+= artsc.0:${PORTSDIR}/audio/arts -PLIST_SUB+= WITH_ARTS="" -CONFIGURE_ARGS+= --with-arts --enable-artstest -.else -PLIST_SUB+= WITH_ARTS="@comment " -CONFIGURE_ARGS+= --disable-arts --disable-artstest -.endif - .if defined(WITH_CACA) LIB_DEPENDS+= caca.0:${PORTSDIR}/graphics/libcaca PLIST_SUB+= WITH_CACA="" @@ -224,15 +211,6 @@ CONFIGURE_ARGS+= --without-wavpack LIB_DEPENDS+= va.1:${PORTSDIR}/multimedia/libva .endif -.if defined(WITH_VDPAU) -PATCHFILES+= xine-vdpau.bz2 -USE_AUTOTOOLS= autoconf -LIB_DEPENDS+= vdpau.1:${PORTSDIR}/multimedia/libvdpau -PLIST_SUB+= VDPAU="" -.else -PLIST_SUB+= VDPAU="@comment " -.endif - .if ${CONFIGURE_ARGS:M*--without-imagemagick*} == "" || ${CONFIGURE_ARGS:M*-disable-gdkpixbuf*} == "" PLIST_SUB+= WITH_DMX_IMAGE="" .else @@ -248,12 +226,7 @@ CONFIGURE_ARGS+= --disable-vidix post-patch: .if defined(WITH_VAAPI) - ${PATCH} ${PATCH_DIST_ARGS} <${FILESDIR}/ffmpeg-vaapi_xine-lib-1.1.19-initerrorhack.diff -.endif -.if defined(WITH_VDPAU) - for i in `${LS} ${FILESDIR}/extrapatch-vdpau*`; do \ - ${PATCH} ${PATCH_DIST_ARGS} <$$i ;\ - done + ${PATCH} ${PATCH_DIST_ARGS} <${FILESDIR}/ffmpeg-vaapi_xine-lib-1.2.1-defaultoff.diff .endif .for f in libtool ltmain.sh @${REINPLACE_CMD} -e \ @@ -283,9 +256,8 @@ pre-configure: @${REINPLACE_CMD} -e \ 's|-malign-loops|-falign-loops|g ; \ s|-malign-jumps|-falign-jumps|g ; \ - s|-malign-functions|-falign-functions|g' ${WRKSRC}/configure - -pre-build: - @${CP} -p ${LOCALBASE}/include/dts.h ${WRKSRC}/src/libdts/ + s|-malign-functions|-falign-functions|g ; \ + s|{libdir}/pkgconfig|{prefix}/libdata/pkgconfig|g' \ + ${WRKSRC}/configure .include Index: distinfo =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/distinfo,v retrieving revision 1.43 diff -u -p -r1.43 distinfo --- distinfo 15 Jan 2011 22:46:39 -0000 1.43 +++ distinfo 6 Feb 2012 17:48:18 -0000 @@ -1,6 +1,2 @@ -SHA256 (xine-lib-1.1.19.tar.xz) = f834f646880bb44186018d12280ac27c8314447de9335b6fe390157b26df9cd9 -SIZE (xine-lib-1.1.19.tar.xz) = 5782580 -SHA256 (xine-lib_1.1.19-2.etobi2.debian.tar.gz) = 41d2ff49284973690914dd8fea0ec25cbbc2a6b60d391bdefe8fab5335eca6b7 -SIZE (xine-lib_1.1.19-2.etobi2.debian.tar.gz) = 179402 -SHA256 (xine-vdpau.bz2) = 25ab5eaa0f5a62e74478feaf1458c81b9e779cac362f04ae5800a73c471d49b2 -SIZE (xine-vdpau.bz2) = 93194 +SHA256 (xine-lib-1.2.1.tar.xz) = 2d4ff0d275b46a197c6a914fdef154e9dd4c88b383f6e1f5efbb8d47a8e03d4e +SIZE (xine-lib-1.2.1.tar.xz) = 4843584 Index: pkg-plist =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/pkg-plist,v retrieving revision 1.57 diff -u -p -r1.57 pkg-plist --- pkg-plist 15 Jan 2011 22:46:39 -0000 1.57 +++ pkg-plist 5 Feb 2012 14:18:51 -0000 @@ -1,5 +1,5 @@ bin/xine-config -bin/xine-list-1.1 +bin/xine-list-1.2 include/xine.h include/xine/alphablend.h include/xine/attributes.h @@ -26,14 +26,16 @@ include/xine/resample.h include/xine/ring_buffer.h include/xine/scratch.h include/xine/sorted_array.h +include/xine/spu.h include/xine/spu_decoder.h +include/xine/version.h +include/xine/vdr.h include/xine/video_decoder.h include/xine/video_out.h include/xine/video_overlay.h include/xine/vo_scale.h include/xine/xine_buffer.h include/xine/xine_internal.h -include/xine/xine_mmx.h include/xine/xine_plugin.h include/xine/xineintl.h include/xine/xineutils.h @@ -41,7 +43,44 @@ include/xine/xmllexer.h include/xine/xmlparser.h lib/libxine.la lib/libxine.so -lib/libxine.so.1 +lib/libxine.so.2 +lib/libxine-interface.la +share/xine-lib/fonts/cetus-16.xinefont.gz +share/xine-lib/fonts/cetus-20.xinefont.gz +share/xine-lib/fonts/cetus-24.xinefont.gz +share/xine-lib/fonts/cetus-32.xinefont.gz +share/xine-lib/fonts/cetus-48.xinefont.gz +share/xine-lib/fonts/cetus-64.xinefont.gz +share/xine-lib/fonts/cc-16.xinefont.gz +share/xine-lib/fonts/cc-20.xinefont.gz +share/xine-lib/fonts/cc-24.xinefont.gz +share/xine-lib/fonts/cc-32.xinefont.gz +share/xine-lib/fonts/cc-48.xinefont.gz +share/xine-lib/fonts/cc-64.xinefont.gz +share/xine-lib/fonts/cci-16.xinefont.gz +share/xine-lib/fonts/cci-20.xinefont.gz +share/xine-lib/fonts/cci-24.xinefont.gz +share/xine-lib/fonts/cci-32.xinefont.gz +share/xine-lib/fonts/cci-48.xinefont.gz +share/xine-lib/fonts/cci-64.xinefont.gz +share/xine-lib/fonts/mono-16.xinefont.gz +share/xine-lib/fonts/mono-20.xinefont.gz +share/xine-lib/fonts/mono-24.xinefont.gz +share/xine-lib/fonts/mono-32.xinefont.gz +share/xine-lib/fonts/mono-48.xinefont.gz +share/xine-lib/fonts/mono-64.xinefont.gz +share/xine-lib/fonts/sans-16.xinefont.gz +share/xine-lib/fonts/sans-20.xinefont.gz +share/xine-lib/fonts/sans-24.xinefont.gz +share/xine-lib/fonts/sans-32.xinefont.gz +share/xine-lib/fonts/sans-48.xinefont.gz +share/xine-lib/fonts/sans-64.xinefont.gz +share/xine-lib/fonts/serif-16.xinefont.gz +share/xine-lib/fonts/serif-20.xinefont.gz +share/xine-lib/fonts/serif-24.xinefont.gz +share/xine-lib/fonts/serif-32.xinefont.gz +share/xine-lib/fonts/serif-48.xinefont.gz +share/xine-lib/fonts/serif-64.xinefont.gz %%PLUGINSDIR%%/mime.types %%PLUGINSDIR%%/post/xineplug_post_audio_filters.so %%PLUGINSDIR%%/post/xineplug_post_goom.so @@ -50,20 +89,6 @@ lib/libxine.so.1 %%PLUGINSDIR%%/post/xineplug_post_switch.so %%PLUGINSDIR%%/post/xineplug_post_tvtime.so %%PLUGINSDIR%%/post/xineplug_post_visualizations.so -@exec mkdir -p %D/%%PLUGINSDIR%%/vidix -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/cyberblade_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/mach64_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/mga_crtc2_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/mga_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/nvidia_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/pm2_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/pm3_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/radeon_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/rage128_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/savage_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/sis_vid.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/vidix/unichrome_vid.so -%%WITH_ARTS%%%%PLUGINSDIR%%/xineplug_ao_out_arts.so %%WITH_ESOUND%%%%PLUGINSDIR%%/xineplug_ao_out_esd.so %%WITH_JACK%%%%PLUGINSDIR%%/xineplug_ao_out_jack.so %%PLUGINSDIR%%/xineplug_ao_out_file.so @@ -81,21 +106,15 @@ lib/libxine.so.1 %%WITH_IMAGEMAGICK%%%%PLUGINSDIR%%/xineplug_decode_image.so %%PLUGINSDIR%%/xineplug_decode_lpcm.so %%PLUGINSDIR%%/xineplug_decode_mad.so -%%PLUGINSDIR%%/xineplug_decode_mpc.so %%PLUGINSDIR%%/xineplug_decode_mpeg2.so -%%PLUGINSDIR%%/xineplug_decode_nsf.so %%WITH_VIDIX%%%%PLUGINSDIR%%/xineplug_decode_qt.so %%PLUGINSDIR%%/xineplug_decode_real.so %%PLUGINSDIR%%/xineplug_decode_rgb.so -%%PLUGINSDIR%%/xineplug_decode_speex.so %%PLUGINSDIR%%/xineplug_decode_spu.so %%PLUGINSDIR%%/xineplug_decode_spucc.so %%PLUGINSDIR%%/xineplug_decode_spucmml.so %%PLUGINSDIR%%/xineplug_decode_spudvb.so %%PLUGINSDIR%%/xineplug_decode_spuhdmv.so -%%PLUGINSDIR%%/xineplug_decode_sputext.so -%%PLUGINSDIR%%/xineplug_decode_theora.so -%%PLUGINSDIR%%/xineplug_decode_vorbis.so %%WITH_VIDIX%%%%PLUGINSDIR%%/xineplug_decode_w32dll.so %%PLUGINSDIR%%/xineplug_decode_yuv.so %%PLUGINSDIR%%/xineplug_dmx_asf.so @@ -114,18 +133,15 @@ lib/libxine.so.1 %%PLUGINSDIR%%/xineplug_dmx_mpeg_pes.so %%PLUGINSDIR%%/xineplug_dmx_mpeg_ts.so %%PLUGINSDIR%%/xineplug_dmx_nsv.so -%%PLUGINSDIR%%/xineplug_dmx_ogg.so %%PLUGINSDIR%%/xineplug_dmx_pva.so %%PLUGINSDIR%%/xineplug_dmx_qt.so %%PLUGINSDIR%%/xineplug_dmx_rawdv.so %%PLUGINSDIR%%/xineplug_dmx_real.so %%PLUGINSDIR%%/xineplug_dmx_slave.so -%%PLUGINSDIR%%/xineplug_dmx_sputext.so %%PLUGINSDIR%%/xineplug_dmx_yuv4mpeg2.so %%PLUGINSDIR%%/xineplug_dmx_yuv_frames.so %%PLUGINSDIR%%/xineplug_flac.so %%PLUGINSDIR%%/xineplug_inp_cdda.so -%%PLUGINSDIR%%/xineplug_inp_dvb.so %%PLUGINSDIR%%/xineplug_inp_dvd.so %%PLUGINSDIR%%/xineplug_inp_file.so %%WITH_GNOMEVFS2%%%%PLUGINSDIR%%/xineplug_inp_gnome_vfs.so @@ -145,7 +161,6 @@ lib/libxine.so.1 %%PLUGINSDIR%%/xineplug_vo_out_opengl.so %%PLUGINSDIR%%/xineplug_vo_out_raw.so %%PLUGINSDIR%%/xineplug_vo_out_sdl.so -%%WITH_VIDIX%%%%PLUGINSDIR%%/xineplug_vo_out_vidix.so %%PLUGINSDIR%%/xineplug_vo_out_xcbshm.so %%PLUGINSDIR%%/xineplug_vo_out_xcbxv.so %%PLUGINSDIR%%/xineplug_vo_out_xshm.so @@ -153,6 +168,19 @@ lib/libxine.so.1 %%WITH_XVMC%%%%PLUGINSDIR%%/xineplug_vo_out_xvmc.so %%WITH_XVMC%%%%PLUGINSDIR%%/xineplug_vo_out_xxmc.so %%WITH_WAVPACK%%%%PLUGINSDIR%%/xineplug_wavpack.so +%%PLUGINSDIR%%/xineplug_vo_out_vdpau.so +%%PLUGINSDIR%%/xineplug_dmx_vc1_es.so +%%PLUGINSDIR%%/xineplug_decode_vdpau_h264_alter.so +%%PLUGINSDIR%%/xineplug_decode_vdpau_h264.so +%%PLUGINSDIR%%/xineplug_decode_vdpau_mpeg12.so +%%PLUGINSDIR%%/xineplug_decode_vdpau_mpeg4.so +%%PLUGINSDIR%%/xineplug_decode_vdpau_vc1.so +%%PLUGINSDIR%%/xineplug_vdr.so +%%PLUGINSDIR%%/xineplug_nsf.so +%%PLUGINSDIR%%/xineplug_sputext.so +%%PLUGINSDIR%%/xineplug_dmx_modplug.so +%%PLUGINSDIR%%/xineplug_dmx_playlist.so +%%PLUGINSDIR%%/xineplug_xiph.so libdata/pkgconfig/libxine.pc share/aclocal/xine.m4 %%DOCSDIR%%/COPYING @@ -162,14 +190,15 @@ share/aclocal/xine.m4 %%DOCSDIR%%/README %%DOCSDIR%%/README.MINGWCROSS %%DOCSDIR%%/README.WIN32 +%%DOCSDIR%%/README.cetus %%DOCSDIR%%/README.dvb %%DOCSDIR%%/README.dxr3 %%DOCSDIR%%/README.freebsd %%DOCSDIR%%/README.irix +%%DOCSDIR%%/README.macosx %%DOCSDIR%%/README.network_dvd %%DOCSDIR%%/README.opengl %%DOCSDIR%%/README.solaris -%%DOCSDIR%%/README.syncfb %%DOCSDIR%%/README_xxmc.html %%DOCSDIR%%/TODO %%DOCSDIR%%/faq.html @@ -179,63 +208,20 @@ share/aclocal/xine.m4 %%DOCSDIR%%/hackersguide/library.png %%DOCSDIR%%/hackersguide/overlays.png %%DOCSDIR%%/hackersguide/post_frame.png -%%NLS%%share/locale/cs/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/de/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/en_US/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/eo/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/es/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/eu/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/fr/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/it/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/pl/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/pt_BR/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/sk/LC_MESSAGES/libxine1.mo -%%NLS%%share/locale/tr/LC_MESSAGES/libxine1.mo -%%DATADIR%%/libxine1/fonts/cc-16.xinefont.gz -%%DATADIR%%/libxine1/fonts/cc-20.xinefont.gz -%%DATADIR%%/libxine1/fonts/cc-24.xinefont.gz -%%DATADIR%%/libxine1/fonts/cc-32.xinefont.gz -%%DATADIR%%/libxine1/fonts/cc-48.xinefont.gz -%%DATADIR%%/libxine1/fonts/cc-64.xinefont.gz -%%DATADIR%%/libxine1/fonts/cci-16.xinefont.gz -%%DATADIR%%/libxine1/fonts/cci-20.xinefont.gz -%%DATADIR%%/libxine1/fonts/cci-24.xinefont.gz -%%DATADIR%%/libxine1/fonts/cci-32.xinefont.gz -%%DATADIR%%/libxine1/fonts/cci-48.xinefont.gz -%%DATADIR%%/libxine1/fonts/cci-64.xinefont.gz -%%DATADIR%%/libxine1/fonts/cetus-16.xinefont.gz -%%DATADIR%%/libxine1/fonts/cetus-20.xinefont.gz -%%DATADIR%%/libxine1/fonts/cetus-24.xinefont.gz -%%DATADIR%%/libxine1/fonts/cetus-32.xinefont.gz -%%DATADIR%%/libxine1/fonts/cetus-48.xinefont.gz -%%DATADIR%%/libxine1/fonts/cetus-64.xinefont.gz -%%DATADIR%%/libxine1/fonts/mono-16.xinefont.gz -%%DATADIR%%/libxine1/fonts/mono-20.xinefont.gz -%%DATADIR%%/libxine1/fonts/mono-24.xinefont.gz -%%DATADIR%%/libxine1/fonts/mono-32.xinefont.gz -%%DATADIR%%/libxine1/fonts/mono-48.xinefont.gz -%%DATADIR%%/libxine1/fonts/mono-64.xinefont.gz -%%DATADIR%%/libxine1/fonts/sans-16.xinefont.gz -%%DATADIR%%/libxine1/fonts/sans-20.xinefont.gz -%%DATADIR%%/libxine1/fonts/sans-24.xinefont.gz -%%DATADIR%%/libxine1/fonts/sans-32.xinefont.gz -%%DATADIR%%/libxine1/fonts/sans-48.xinefont.gz -%%DATADIR%%/libxine1/fonts/sans-64.xinefont.gz -%%DATADIR%%/libxine1/fonts/serif-16.xinefont.gz -%%DATADIR%%/libxine1/fonts/serif-20.xinefont.gz -%%DATADIR%%/libxine1/fonts/serif-24.xinefont.gz -%%DATADIR%%/libxine1/fonts/serif-32.xinefont.gz -%%DATADIR%%/libxine1/fonts/serif-48.xinefont.gz -%%DATADIR%%/libxine1/fonts/serif-64.xinefont.gz -%%VDPAU%%include/xine/vdr.h -%%VDPAU%%%%PLUGINSDIR%%/xineplug_vo_out_vdpau.so -%%VDPAU%%%%PLUGINSDIR%%/xineplug_dmx_vc1_es.so -%%VDPAU%%%%PLUGINSDIR%%/xineplug_decode_vdpau_h264.so -%%VDPAU%%%%PLUGINSDIR%%/xineplug_decode_vdpau_mpeg12.so -%%VDPAU%%%%PLUGINSDIR%%/xineplug_decode_vdpau_vc1.so -%%VDPAU%%%%PLUGINSDIR%%/xineplug_vdr.so +%%NLS%%share/locale/cs/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/de/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/en_US/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/eo/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/es/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/eu/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/fr/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/it/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/ja/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/pl/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/pt_BR/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/sk/LC_MESSAGES/libxine2.mo +%%NLS%%share/locale/tr/LC_MESSAGES/libxine2.mo @dirrm include/xine -@dirrm %%PLUGINSDIR%%/vidix @dirrm %%PLUGINSDIR%%/post @dirrmtry %%PLUGINSDIR%% @dirrmtry lib/xine/plugins @@ -246,6 +232,6 @@ share/aclocal/xine.m4 %%NLS%%@dirrmtry share/locale/pl_PL %%NLS%%@dirrmtry share/locale/en_US/LC_MESSAGES %%NLS%%@dirrmtry share/locale/en_US -@dirrm %%DATADIR%%/libxine1/fonts -@dirrm %%DATADIR%%/libxine1 +@dirrm share/xine-lib/fonts +@dirrm share/xine-lib @dirrmtry %%DATADIR%% Index: files/ffmpeg-vaapi_xine-lib-1.1.19-initerrorhack.diff =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/ffmpeg-vaapi_xine-lib-1.1.19-initerrorhack.diff,v retrieving revision 1.2 diff -u -p -r1.2 ffmpeg-vaapi_xine-lib-1.1.19-initerrorhack.diff --- files/ffmpeg-vaapi_xine-lib-1.1.19-initerrorhack.diff 25 Sep 2011 15:48:00 -0000 1.2 +++ files/ffmpeg-vaapi_xine-lib-1.1.19-initerrorhack.diff 28 Jan 2012 04:37:17 -0000 @@ -1,851 +0,0 @@ -diff -Naur xine-lib-1.1.19.orig/src/combined/ffmpeg/ff_video_decoder.c xine-lib-1.1.19/src/combined/ffmpeg/ff_video_decoder.c ---- xine-lib-1.1.19.orig/src/combined/ffmpeg/ff_video_decoder.c -+++ xine-lib-1.1.19/src/combined/ffmpeg/ff_video_decoder.c -@@ -51,6 +51,21 @@ - # include - #endif - -+#include -+#include -+//#include -+ -+typedef struct ff_va_surfaces_s ff_va_surfaces_t; -+ -+struct ff_va_surfaces_s -+{ -+ int count; -+ VASurfaceID **free; -+ VASurfaceID **used; -+}; -+ -+#define NUM_SURFACES 21 -+ - #define VIDEOBUFSIZE (128*1024) - #define SLICE_BUFFER_SIZE (1194*1024) - -@@ -89,6 +104,7 @@ typedef struct ff_video_class_s { - int thread_count; - int8_t skip_loop_filter_enum; - int8_t choose_speed_over_accuracy; -+ int enable_vaapi; - - xine_t *xine; - } ff_video_class_t; -@@ -127,6 +143,7 @@ struct ff_video_decoder_s { - int slice_offset_size; - - AVFrame *av_frame; -+ //AVPacket av_pkt; - AVCodecContext *context; - AVCodec *codec; - -@@ -154,8 +171,31 @@ struct ff_video_decoder_s { - #ifdef LOG - enum PixelFormat debug_fmt; - #endif -+ -+}; -+ -+typedef struct ff_vaapi_context_s ff_vaapi_context_t; -+ -+struct ff_vaapi_context_s { -+ VAImage va_image; -+ Display *display; -+ VADisplay *va_display; -+ VAImageFormat *va_ifmts; -+ uint8_t *va_image_data; -+ VAContextID va_context_id; -+ VAConfigID va_config_id; -+ VASurfaceID *va_surface_id; -+ struct ff_va_surfaces_s va_surfaces; -+ int width; -+ int height; -+ int va_profile; -+ struct vaapi_context *vaapi_context; -+ int use_vaapi; - }; - -+static struct ff_vaapi_context_s *va_context; -+ -+static VAStatus init_vaapi(struct ff_vaapi_context_s *va_context, int va_profile, int width, int height); - - static void set_stream_info(ff_video_decoder_t *this) { - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); -@@ -163,7 +203,70 @@ static void set_stream_info(ff_video_dec - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->aspect_ratio * 10000); - } - -+/* -+ * XXX Error on init_vaapi() didn't cause fall back to standard rendering, -+ * so do a crude test on plugin open. -+ */ -+#define INIT_ERROR_HACK -+ - #ifdef ENABLE_DIRECT_RENDERING -+ -+static void draw_slice(struct AVCodecContext *context, const AVFrame *src, int offset[4], int y, int type, int height) { -+ uint8_t *source[4]= {src->data[0] + offset[0], src->data[1] + offset[1], src->data[2] + offset[2], src->data[3] + offset[3]}; -+ int strides[4] = {src->linesize[0], src->linesize[1], src->linesize[2]}; -+ -+ if (height < 0) { -+ int i; -+ height = -height; -+ y -= height; -+ for (i = 0; i < 4; i++) { -+ strides[i] = -strides[i]; -+ source[i] -= strides[i]; -+ } -+ } -+} -+ -+static VAProfile* find_profile(VAProfile* p, int np, int codec) -+{ -+ int i; -+ -+ for(i = 0; i < np; i++) -+ { -+ if(p[i] == codec) -+ return &p[i]; -+ } -+ -+ return NULL; -+} -+ -+int get_profile(int codec_id) { -+ int profile; -+ -+ switch (codec_id) { -+ case CODEC_ID_MPEG2VIDEO: -+ profile = VAProfileMPEG2Main; -+ break; -+ case CODEC_ID_MPEG4: -+ case CODEC_ID_H263: -+ profile = VAProfileMPEG4AdvancedSimple; -+ break; -+ case CODEC_ID_H264: -+ profile = VAProfileH264High; -+ break; -+ case CODEC_ID_WMV3: -+ profile = VAProfileVC1Main; -+ break; -+ case CODEC_ID_VC1: -+ profile = VAProfileVC1Advanced; -+ break; -+ default: -+ profile = -1; -+ break; -+ } -+ -+ return profile; -+} -+ - /* called from ffmpeg to do direct rendering method 1 */ - static int get_buffer(AVCodecContext *context, AVFrame *av_frame){ - ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; -@@ -185,6 +288,43 @@ static int get_buffer(AVCodecContext *co - - avcodec_align_dimensions(context, &width, &height); - -+ if( va_context->use_vaapi ) { -+ int i = 0; -+ struct ff_va_surfaces_s *va_surfaces = &va_context->va_surfaces; -+ -+ for(i = 0; i < va_surfaces->count; i++) -+ { -+ //printf("srfc #%d %p\n",i,va_srfcs->srfc_free[i]); -+ if(va_surfaces->free[i]) -+ { -+ va_surfaces->used[i] = va_surfaces->free[i]; -+ va_surfaces->free[i] = NULL; -+ break; -+ } -+ } -+ if(i == va_surfaces->count) -+ { -+ printf("ERROR get surface\n"); -+ return -1; -+ } -+ -+ -+ av_frame->type = FF_BUFFER_TYPE_USER; -+ av_frame->age = 256*256*256*64; // FIXME FIXME from ffmpeg -+ av_frame->data[0] = (void*)va_surfaces->used[i]; -+ av_frame->data[1] = NULL; -+ av_frame->data[2] = NULL; -+ av_frame->data[3] = (void*)(size_t)*va_surfaces->used[i]; -+ av_frame->linesize[0] = 0; -+ av_frame->linesize[1] = 0; -+ av_frame->linesize[2] = 0; -+ av_frame->linesize[3] = 0; -+ -+ this->is_direct_rendering_disabled = 1; -+ -+ return 0; -+ } -+ - if( this->context->pix_fmt != PIX_FMT_YUV420P && this->context->pix_fmt != PIX_FMT_YUVJ420P ) { - if (!this->is_direct_rendering_disabled) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, -@@ -254,10 +394,33 @@ static int get_buffer(AVCodecContext *co - static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){ - ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; - -+ if( va_context->use_vaapi ) { -+ struct ff_va_surfaces_s *va_surfaces = &va_context->va_surfaces; -+ VASurfaceID va_surface_id = (VASurfaceID)(size_t)av_frame->data[3]; -+ int i = 0; -+ -+ for(i = 0; i < va_surfaces->count; i++) -+ { -+ //printf("srfc #%d %p 0x%08X\n",i,va_srfcs->srfc_used[i], va_srfcs->srfc_used[i] ? *va_srfcs->srfc_used[i] : -1); -+ if(va_surfaces->used[i] && (*va_surfaces->used[i] == va_surface_id)) -+ { -+ va_surfaces->free[i] = va_surfaces->used[i]; -+ va_surfaces->used[i] = NULL; -+ break; -+ } -+ } -+ -+ av_frame->data[0] = NULL; -+ av_frame->data[1] = NULL; -+ av_frame->data[2] = NULL; -+ av_frame->data[3] = NULL; -+ return; -+ } -+ - if (av_frame->type == FF_BUFFER_TYPE_USER) { - if ( av_frame->opaque ) { -- vo_frame_t *img = (vo_frame_t *)av_frame->opaque; -- -+ vo_frame_t *img = (vo_frame_t *)av_frame->opaque; -+ - img->free(img); - } - -@@ -299,13 +462,272 @@ static const int skip_loop_filter_enum_v - AVDISCARD_ALL - }; - -+static const char *VAProfile2string(VAProfile profile) -+{ -+ switch(profile) { -+#define PROFILE(profile) \ -+ case VAProfile##profile: return "VAProfile" #profile -+ PROFILE(MPEG2Simple); -+ PROFILE(MPEG2Main); -+ PROFILE(MPEG4Simple); -+ PROFILE(MPEG4AdvancedSimple); -+ PROFILE(MPEG4Main); -+ PROFILE(H264Baseline); -+ PROFILE(H264Main); -+ PROFILE(H264High); -+ PROFILE(VC1Simple); -+ PROFILE(VC1Main); -+ PROFILE(VC1Advanced); -+#undef PROFILE -+ default: break; -+ } -+ return ""; -+} -+ -+static const char *VAEntrypoint2string(VAEntrypoint entrypoint) -+{ -+ switch(entrypoint) -+ { -+#define ENTRYPOINT(entrypoint) \ -+ case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint -+ ENTRYPOINT(VLD); -+ ENTRYPOINT(IZZ); -+ ENTRYPOINT(IDCT); -+ ENTRYPOINT(MoComp); -+ ENTRYPOINT(Deblocking); -+#undef ENTRYPOINT -+ default: break; -+ } -+ return ""; -+} -+ -+static enum PixelFormat get_format(struct AVCodecContext *context, const enum PixelFormat *fmt) -+{ -+ int i, profile; -+ -+ for (i = 0; fmt[i] != PIX_FMT_NONE; i++) { -+ if (fmt[i] != PIX_FMT_VAAPI_VLD) -+ continue; -+ -+ profile = get_profile(context->codec_id); -+ -+ if (profile >= 0) { -+ VAStatus status; -+ -+ status = init_vaapi(va_context, profile, context->width, context->height); -+ -+ if( status == VA_STATUS_SUCCESS ) { -+ -+ //context->draw_horiz_band = draw_slice; -+ context->draw_horiz_band = NULL; -+ context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; -+ context->dsp_mask = AV_CPU_FLAG_FORCE | AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE; -+ -+ va_context->vaapi_context->config_id = va_context->va_config_id; -+ va_context->vaapi_context->context_id = va_context->va_context_id; -+ context->hwaccel_context = va_context->vaapi_context; -+ printf("init vaapi successfully\n"); -+ va_context->use_vaapi = 1; -+ return fmt[i]; -+ } else { -+ va_context->use_vaapi = 0; -+ printf("vaapi init error\n"); -+ } -+ } else { -+ va_context->use_vaapi = 0; -+ } -+ } -+ return PIX_FMT_NONE; -+} -+ -+static void close_vaapi(ff_vaapi_context_t *va_context) { -+ if (va_context->use_vaapi == 0); -+ return; -+ -+ if(va_context->va_context_id) { -+ if(va_context->va_image.image_id != VA_INVALID_ID ) { -+ vaDestroyImage(va_context->va_display, va_context->va_image.image_id ); -+ } -+ if(va_context->va_context_id != VA_INVALID_ID) { -+ vaDestroyContext(va_context->va_display, va_context->va_context_id); -+ } -+ -+ int i = 0; -+ for( i = 0; i < va_context->va_surfaces.count; i++ ) { -+ if( va_context->va_surface_id[i] != VA_INVALID_SURFACE) { -+ vaDestroySurfaces(va_context->va_display, &va_context->va_surface_id[i], 1); -+ } -+ } -+ -+ if(va_context->va_config_id) -+ vaDestroyConfig(va_context->va_display, va_context->va_config_id); -+ -+ vaTerminate(va_context->va_display); -+ XCloseDisplay(va_context->display); -+ -+ free(va_context->va_surfaces.free); -+ free(va_context->va_surfaces.used); -+ free(va_context->va_surface_id); -+ free(va_context->vaapi_context); -+ free(va_context); -+ -+ va_context = NULL; -+ } -+} -+ -+static VAStatus create_vaapi_image(struct ff_vaapi_context_s *va_context) { -+ int i; -+ int fmt_count = vaMaxNumImageFormats( va_context->va_display ); -+ VAImageFormat *va_p_fmt = calloc( fmt_count, sizeof(*va_p_fmt) ); -+ VAImageFormat va_fmt; -+ -+ if( vaQueryImageFormats( va_context->va_display , va_p_fmt, &fmt_count ) ) { -+ free(va_p_fmt); -+ goto error; -+ } -+ -+ for( i = 0; i < fmt_count; i++ ) { -+ if ( va_p_fmt[i].fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) || -+ va_p_fmt[i].fourcc == VA_FOURCC( 'I', '4', '2', '0' ) || -+ va_p_fmt[i].fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) ) { -+ -+ if( vaCreateImage( va_context->va_display, &va_p_fmt[i], va_context->width, va_context->height, &va_context->va_image) ) { -+ va_context->va_image.image_id = VA_INVALID_ID; -+ continue; -+ } -+ if( vaGetImage(va_context->va_display, va_context->va_surface_id[0], 0, 0, -+ va_context->width, va_context->height, va_context->va_image.image_id) ) { -+ vaDestroyImage( va_context->va_display, va_context->va_image.image_id ); -+ va_context->va_image.image_id = VA_INVALID_ID; -+ continue; -+ } -+ printf("found valid image format\n"); -+ va_fmt = va_p_fmt[i]; -+ break; -+ } -+ } -+ free(va_p_fmt); -+ -+ if(va_context->va_image.image_id == VA_INVALID_ID) -+ goto error; -+ -+ return VA_STATUS_SUCCESS; -+ -+error: -+ return VA_STATUS_ERROR_UNKNOWN; -+} -+ -+static VAStatus init_vaapi(struct ff_vaapi_context_s *va_context, int va_profile, int width, int height) { -+ size_t i; -+ VAStatus status = VA_STATUS_ERROR_UNKNOWN; -+ int surface_count = NUM_SURFACES; -+ VAConfigAttrib va_attrib; -+ int maj, min; -+ VAProfile *va_profiles = NULL; -+ VAProfile *va_profile_search = NULL; -+ int number_profiles; -+ -+ va_context->width = width; -+ va_context->height = height; -+ va_context->va_profile = va_profile; -+ -+ va_context->va_surfaces.free = NULL; -+ va_context->va_surfaces.used = NULL; -+ -+ va_context->va_display = NULL; -+ va_context->va_config_id = VA_INVALID_ID; -+ va_context->va_context_id = VA_INVALID_ID; -+ va_context->va_image.image_id = VA_INVALID_ID; -+ -+ va_context->display = XOpenDisplay(NULL); -+ if(!va_context->display) -+ goto error; -+ -+ va_context->va_display = vaGetDisplay(va_context->display); -+ va_context->vaapi_context->display = va_context->va_display; -+ -+ if(!va_context->va_display) -+ goto error; -+ -+ if(vaInitialize(va_context->va_display, &maj, &min)) -+ goto error; -+ -+ printf("libva: %d.%d\n", maj, min); -+ -+ printf("AvCodecContext w %d h %d\n", va_context->width, va_context->height); -+ -+ memset( &va_attrib, 0, sizeof(va_attrib) ); -+ va_attrib.type = VAConfigAttribRTFormat; -+ -+ va_profiles = malloc(vaMaxNumProfiles(va_context->va_display) * sizeof(VAProfile)); -+ -+ if(vaQueryConfigProfiles(va_context->va_display, va_profiles, &number_profiles)) { -+ free(va_profiles); -+ goto error; -+ } -+ -+ free(va_profiles); -+ -+ -+ va_profile_search = find_profile(va_profiles, number_profiles, va_profile); -+ -+ if(!va_profile_search) -+ goto error; -+ -+ printf("Profile: %d (%s) Entrypoint %d (%s)\n", va_context->va_profile, VAProfile2string(va_context->va_profile), VAEntrypointVLD, VAEntrypoint2string(VAEntrypointVLD)); -+ -+ if( vaGetConfigAttributes(va_context->va_display, va_context->va_profile, VAEntrypointVLD, &va_attrib, 1) ) -+ goto error; -+ -+ if( (va_attrib.value & VA_RT_FORMAT_YUV420) == 0 ) -+ goto error; -+ -+ if( vaCreateConfig(va_context->va_display, va_context->va_profile, VAEntrypointVLD, &va_attrib, 1, &va_context->va_config_id) ) { -+ va_context->va_config_id = VA_INVALID_ID; -+ goto error; -+ } -+ -+ if(va_context->va_surface_id == NULL) { -+ va_context->va_surface_id = malloc(sizeof(VASurfaceID) * surface_count); -+ va_context->va_surfaces.free = malloc(sizeof(VASurfaceID*) * surface_count); -+ va_context->va_surfaces.used = malloc(sizeof(VASurfaceID*) * surface_count); -+ } -+ -+ if( vaCreateSurfaces(va_context->va_display, va_context->width, va_context->height, VA_RT_FORMAT_YUV420, surface_count, va_context->va_surface_id) ) -+ goto error; -+ -+ for(i = 0; i < surface_count; i++) { -+ va_context->va_surfaces.free[i] = &va_context->va_surface_id[i]; -+ va_context->va_surfaces.used[i] = NULL; -+ } -+ -+ va_context->va_surfaces.count = surface_count; -+ -+ if(vaCreateContext(va_context->va_display, va_context->va_config_id, va_context->width, va_context->height, -+ VA_PROGRESSIVE, va_context->va_surface_id, surface_count, &va_context->va_context_id) ) { -+ va_context->va_context_id = VA_INVALID_ID; -+ goto error; -+ } -+ -+ status = create_vaapi_image(va_context); -+ if(status != VA_STATUS_SUCCESS) -+ goto error; -+ -+ va_context->use_vaapi = 1; -+ return VA_STATUS_SUCCESS; -+ -+error: -+ va_context->use_vaapi = 0; -+ return VA_STATUS_ERROR_UNKNOWN; -+} -+ - static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) { - size_t i; - - /* find the decoder */ - this->codec = NULL; - -- for(i = 0; i < sizeof(ff_video_lookup)/sizeof(ff_codec_t); i++) -+ for(i = 0; i < sizeof(ff_video_lookup)/sizeof(ff_codec_t); i++) { - if(ff_video_lookup[i].type == codec_type) { - pthread_mutex_lock(&ffmpeg_lock); - this->codec = avcodec_find_decoder(ff_video_lookup[i].id); -@@ -314,6 +736,8 @@ static void init_video_codec (ff_video_d - ff_video_lookup[i].name); - break; - } -+ } -+ - - if (!this->codec) { - xprintf (this->stream->xine, XINE_VERBOSITY_LOG, -@@ -327,9 +751,11 @@ static void init_video_codec (ff_video_d - - this->context->width = this->bih.biWidth; - this->context->height = this->bih.biHeight; -+ - this->context->stream_codec_tag = this->context->codec_tag = - _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC); - -+ //av_init_packet(&this->av_pkt); - - /* Some codecs (eg rv10) copy flags in init so it's necessary to set - * this flag here in case we are going to use direct rendering */ -@@ -339,7 +765,6 @@ static void init_video_codec (ff_video_d - - if (this->class->choose_speed_over_accuracy) - this->context->flags2 |= CODEC_FLAG2_FAST; -- - pthread_mutex_lock(&ffmpeg_lock); - if (avcodec_open (this->context, this->codec) < 0) { - pthread_mutex_unlock(&ffmpeg_lock); -@@ -353,7 +778,6 @@ static void init_video_codec (ff_video_d - - if (this->codec->id == CODEC_ID_VC1 && - (!this->bih.biWidth || !this->bih.biHeight)) { -- /* VC1 codec must be re-opened with correct width and height. */ - avcodec_close(this->context); - - if (avcodec_open (this->context, this->codec) < 0) { -@@ -406,6 +830,13 @@ static void init_video_codec (ff_video_d - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("ffmpeg_video_dec: direct rendering enabled\n")); - } -+ if( this->class->enable_vaapi && !this->is_mpeg12) { -+ this->context->get_buffer = get_buffer; -+ this->context->reget_buffer = get_buffer; -+ this->context->release_buffer = release_buffer; -+ this->context->get_format = get_format; -+ this->context->thread_count = 1; -+ } - #endif - - /* flag for interlaced streams */ -@@ -429,7 +860,13 @@ static void init_video_codec (ff_video_d - this->frame_flags |= VO_INTERLACED_FLAG; - break; - } -+} -+ - -+static void enable_vaapi(void *user_data, xine_cfg_entry_t *entry) { -+ ff_video_class_t *class = (ff_video_class_t *) user_data; -+ -+ class->enable_vaapi = entry->num_value; - } - - static void choose_speed_over_accuracy_cb(void *user_data, xine_cfg_entry_t *entry) { -@@ -558,6 +995,36 @@ static int ff_handle_mpeg_sequence(ff_vi - return 1; - } - -+/* -+*/ -+ -+static int nv12_to_yv12(ff_video_decoder_t *this, uint8_t *data, int len, vo_frame_t *img) { -+ unsigned int Y_size = img->width * this->bih.biHeight; -+ unsigned int UV_size = img->width * this->bih.biHeight / 4; -+ unsigned int idx; -+ unsigned char *dst_Y = img->base[0]; -+ unsigned char *dst_U = img->base[1]; -+ unsigned char *dst_V = img->base[2]; -+ unsigned char *src = data + Y_size; -+ -+ // sanity check raw stream -+ if ( (len != (Y_size + (UV_size<<1))) ) { -+ printf("hmblck: Image size inconsistent with data size.\n"); -+ return 0; -+ } -+ -+ // luma data is easy, just copy it -+ xine_fast_memcpy(dst_Y, data, Y_size); -+ -+ // chroma data is interlaced UVUV... so deinterlace it -+ for(idx=0; idxdebug_fmt = this->context->pix_fmt); - #endif - -+ if(this->context->pix_fmt == PIX_FMT_VAAPI_VLD && va_context->va_image.image_id != VA_INVALID_ID) { -+ void *p_base; -+ const uint32_t fourcc = va_context->va_image.format.fourcc; -+ VAStatus status; -+ -+ if( !vaGetImage( va_context->va_display, (VASurfaceID)(size_t)this->av_frame->data[3], -+ 0, 0, img->width, this->bih.biHeight, va_context->va_image.image_id) ) { -+ -+ status = vaMapBuffer( va_context->va_display, va_context->va_image.buf, &p_base ) ; -+ if ( status == VA_STATUS_SUCCESS ) { -+ if( fourcc == VA_FOURCC('Y','V','1','2') || -+ fourcc == VA_FOURCC('I','4','2','0') ) { -+ -+ lprintf("VAAPI YV12 image\n"); -+ -+ yv12_to_yv12( -+ /* Y */ -+ (uint8_t*)p_base, img->width, -+ img->base[0], img->pitches[0], -+ /* U */ -+ (uint8_t*)p_base + (img->width * img->height * 5/4), img->width/2, -+ img->base[1], img->pitches[1], -+ /* V */ -+ (uint8_t*)p_base + (img->width * img->height), img->width/2, -+ img->base[2], img->pitches[2], -+ /* width x height */ -+ img->width, img->height); -+ -+ } -+ if( fourcc == VA_FOURCC('N','V','1','2') ) { -+ -+ lprintf("VAAPI NV12 image\n"); -+ -+ nv12_to_yv12(this, (uint8_t*)p_base, va_context->va_image.data_size, img); -+ -+ } -+ -+ status = vaUnmapBuffer( va_context->va_display, va_context->va_image.buf ); -+ } -+ } -+ return; -+ } -+ - dy = img->base[0]; - du = img->base[1]; - dv = img->base[2]; -@@ -1038,6 +1548,11 @@ static void ff_handle_mpeg12_buffer (ff_ - - lprintf("handle_mpeg12_buffer\n"); - -+ if (buf->decoder_flags & BUF_FLAG_FRAME_START) { -+ lprintf("BUF_FLAG_FRAME_START\n"); -+ this->size = 0; -+ } -+ - while ((size > 0) || (flush == 1)) { - - uint8_t *current; -@@ -1403,47 +1918,48 @@ static void ff_handle_buffer (ff_video_d - - /* aspect ratio provided by ffmpeg, override previous setting */ - if ((this->aspect_ratio_prio < 2) && -- av_cmp_q(this->context->sample_aspect_ratio, avr00)) { -+ av_cmp_q(this->context->sample_aspect_ratio, avr00)) { - - if (!this->bih.biWidth || !this->bih.biHeight) { - this->bih.biWidth = this->context->width; - this->bih.biHeight = this->context->height; - } - -- this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) * -- (double)this->bih.biWidth / (double)this->bih.biHeight; -- this->aspect_ratio_prio = 2; -- lprintf("ffmpeg aspect ratio: %f\n", this->aspect_ratio); -- set_stream_info(this); -+ this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) * -+ (double)this->bih.biWidth / (double)this->bih.biHeight; -+ this->aspect_ratio_prio = 2; -+ lprintf("ffmpeg aspect ratio: %f\n", this->aspect_ratio); -+ set_stream_info(this); - } - - if (got_picture && this->av_frame->data[0]) { - /* got a picture, draw it */ - got_one_picture = 1; -+ - if(!this->av_frame->opaque) { -- /* indirect rendering */ -+ /* indirect rendering */ - -- /* initialize the colorspace converter */ -- if (!this->cs_convert_init) { -- if ((this->context->pix_fmt == PIX_FMT_RGB32) || -- (this->context->pix_fmt == PIX_FMT_RGB565) || -- (this->context->pix_fmt == PIX_FMT_RGB555) || -- (this->context->pix_fmt == PIX_FMT_BGR24) || -- (this->context->pix_fmt == PIX_FMT_RGB24) || -- (this->context->pix_fmt == PIX_FMT_PAL8)) { -- this->output_format = XINE_IMGFMT_YUY2; -- init_yuv_planes(&this->yuv, (this->bih.biWidth + 15) & ~15, this->bih.biHeight); -- this->yuv_init = 1; -- } -- this->cs_convert_init = 1; -- } -- -- if (this->aspect_ratio_prio == 0) { -- this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight; -- this->aspect_ratio_prio = 1; -- lprintf("default aspect ratio: %f\n", this->aspect_ratio); -- set_stream_info(this); -- } -+ /* initialize the colorspace converter */ -+ if (!this->cs_convert_init) { -+ if ((this->context->pix_fmt == PIX_FMT_RGB32) || -+ (this->context->pix_fmt == PIX_FMT_RGB565) || -+ (this->context->pix_fmt == PIX_FMT_RGB555) || -+ (this->context->pix_fmt == PIX_FMT_BGR24) || -+ (this->context->pix_fmt == PIX_FMT_RGB24) || -+ (this->context->pix_fmt == PIX_FMT_PAL8)) { -+ this->output_format = XINE_IMGFMT_YUY2; -+ init_yuv_planes(&this->yuv, (this->bih.biWidth + 15) & ~15, this->bih.biHeight); -+ this->yuv_init = 1; -+ } -+ this->cs_convert_init = 1; -+ } -+ -+ if (this->aspect_ratio_prio == 0) { -+ this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight; -+ this->aspect_ratio_prio = 1; -+ lprintf("default aspect ratio: %f\n", this->aspect_ratio); -+ set_stream_info(this); -+ } - - /* xine-lib expects the framesize to be a multiple of 16x16 (macroblock) */ - img = this->stream->video_out->get_frame (this->stream->video_out, -@@ -1484,7 +2000,7 @@ static void ff_handle_buffer (ff_video_d - this->av_frame->pict_type); - - } else if (!this->av_frame->opaque) { -- /* colorspace conversion or copy */ -+ /* colorspace conversion or copy */ - ff_convert_frame(this, img); - } - -@@ -1572,6 +2088,15 @@ static void ff_decode_data (video_decode - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, (this->reported_video_step = this->video_step)); - } - -+ int codec_type = buf->type & 0xFFFF0000; -+ if (codec_type == BUF_VIDEO_MPEG) { -+ this->is_mpeg12 = 1; -+ if ( this->mpeg_parser == NULL ) { -+ this->mpeg_parser = calloc(1, sizeof(mpeg_parser_t)); -+ mpeg_parser_init(this->mpeg_parser); -+ } -+ } -+ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) { - - ff_handle_preview_buffer(this, buf); -@@ -1589,24 +2114,24 @@ static void ff_decode_data (video_decode - ff_handle_header_buffer(this, buf); - - if (buf->decoder_flags & BUF_FLAG_ASPECT) { -- if (this->aspect_ratio_prio < 3) { -- this->aspect_ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; -- this->aspect_ratio_prio = 3; -- lprintf("aspect ratio: %f\n", this->aspect_ratio); -- set_stream_info(this); -- } -+ if (this->aspect_ratio_prio < 3) { -+ this->aspect_ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; -+ this->aspect_ratio_prio = 3; -+ lprintf("aspect ratio: %f\n", this->aspect_ratio); -+ set_stream_info(this); -+ } - } - - } else { - - /* decode */ - if (buf->pts) -- this->pts = buf->pts; -+ this->pts = buf->pts; - - if (this->is_mpeg12) { -- ff_handle_mpeg12_buffer(this, buf); -+ ff_handle_mpeg12_buffer(this, buf); - } else { -- ff_handle_buffer(this, buf); -+ ff_handle_buffer(this, buf); - } - - } -@@ -1685,6 +2210,8 @@ static void ff_dispose (video_decoder_t - - lprintf ("ff_dispose\n"); - -+ close_vaapi(va_context); -+ - if (this->decoder_ok) { - xine_list_iterator_t it; - AVFrame *av_frame; -@@ -1776,10 +2303,31 @@ static video_decoder_t *ff_video_open_pl - - this->dr1_frames = xine_list_new(); - -+ va_context = calloc(1, sizeof(ff_vaapi_context_t)); -+ va_context->vaapi_context = calloc(1, sizeof(struct vaapi_context)); -+ - #ifdef LOG - this->debug_fmt = -1; - #endif - -+ this->class->enable_vaapi = this->class->xine->config->register_bool(this->class->xine->config, "video.processing.ffmpeg_enable_vaapi", 1, -+ _("Enable usage of VAAPI"), -+ _("Let you enable the usage of VAAPI.\n"), -+ 10, enable_vaapi, this->class); -+ -+#ifdef INIT_ERROR_HACK -+ if ((init_vaapi(va_context, VAProfileH264High, 1280, 720) == VA_STATUS_SUCCESS )) { -+ close_vaapi(va_context); -+ } else { -+ this->class->enable_vaapi = 0; -+ xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: VAAPI Enabled in config, but output video out driver does not support vaapi.\n")); -+ } -+ free(va_context->vaapi_context); -+ free(va_context); -+ va_context = calloc(1, sizeof(ff_vaapi_context_t)); -+ va_context->vaapi_context = calloc(1, sizeof(struct vaapi_context)); -+#endif -+ - return &this->video_decoder; - } - -diff -Naur xine-lib-1.1.19.orig/src/combined/ffmpeg/Makefile.am xine-lib-1.1.19/src/combined/ffmpeg/Makefile.am ---- xine-lib-1.1.19.orig/src/combined/ffmpeg/Makefile.am 2010-03-09 23:17:05.000000000 +0100 -+++ xine-lib-1.1.19/src/combined/ffmpeg/Makefile.am 2010-10-14 14:49:01.000000000 +0200 -@@ -43,7 +43,7 @@ - - xineplug_decode_ff_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) - xineplug_decode_ff_la_LDFLAGS = $(xineplug_ldflags) $(IMPURE_TEXT_LDFLAGS) --xineplug_decode_ff_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm $(ZLIB_LIBS) \ -+xineplug_decode_ff_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm -lva-x11 -lva -lX11 $(ZLIB_LIBS) \ - $(link_ffmpeg) $(PTHREAD_LIBS) $(LTLIBINTL) - - xineplug_decode_dvaudio_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) Index: files/patch-configure =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-configure,v retrieving revision 1.13 diff -u -p -r1.13 patch-configure --- files/patch-configure 19 Jun 2010 11:06:36 -0000 1.13 +++ files/patch-configure 25 Jan 2012 21:50:40 -0000 @@ -1,30 +0,0 @@ ---- ./configure.orig 2010-03-06 22:36:24.000000000 +0300 -+++ ./configure 2010-06-19 02:21:36.862142625 +0400 -@@ -17061,9 +17061,6 @@ - - done - -- if test "$ac_cv_header_ffmpeg_avutil_h" = "yes" && test "$ac_cv_header_libavutil_avutil_h" = "yes"; then -- as_fn_error "old & new ffmpeg headers found - you need to clean up!" "$LINENO" 5 -- fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: using external ffmpeg" >&5 - $as_echo "using external ffmpeg" >&6; } -@@ -23234,6 +23231,8 @@ - fi - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" -+else -+no_theora=yes - fi - - if test "x$no_libFLAC" = "x" ; then -@@ -29752,7 +29751,7 @@ - - xinelibdir='${libdir}/xine' - xinedatadir='${datadir}/xine' --pkgconfigdir='${libdir}/pkgconfig' -+pkgconfigdir='${prefix}/libdata/pkgconfig' - - - Index: files/patch-libav-0.7 =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-libav-0.7,v retrieving revision 1.1 diff -u -p -r1.1 patch-libav-0.7 --- files/patch-libav-0.7 25 Sep 2011 15:48:00 -0000 1.1 +++ files/patch-libav-0.7 25 Jan 2012 21:50:40 -0000 @@ -1,237 +0,0 @@ -From: Reinhard Tartler -Subject: unbreak compilation with Libav 0.7 - -Index: src/combined/ffmpeg/ff_video_decoder.c -=================================================================== ---- xine-lib.orig/src/combined/ffmpeg/ff_video_decoder.c 2011-05-27 19:46:33.550935020 +0200 -+++ xine-lib/src/combined/ffmpeg/ff_video_decoder.c 2011-05-27 19:58:40.030934613 +0200 -@@ -58,12 +58,28 @@ - - #define ENABLE_DIRECT_RENDERING - -+#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 -+ - /* reordered_opaque appeared in libavcodec 51.68.0 */ - #define AVCODEC_HAS_REORDERED_OPAQUE - #if LIBAVCODEC_VERSION_INT < 0x334400 - # undef AVCODEC_HAS_REORDERED_OPAQUE - #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 -+ - typedef struct ff_video_decoder_s ff_video_decoder_t; - - typedef struct ff_video_class_s { -@@ -116,8 +132,8 @@ - - int pp_quality; - int pp_flags; -- pp_context_t *pp_context; -- pp_mode_t *pp_mode; -+ pp_context *pp_context; -+ pp_mode *pp_mode; - - /* mpeg-es parsing */ - mpeg_parser_t *mpeg_parser; -@@ -1055,12 +1071,26 @@ - } - - /* skip decoding b frames if too late */ -+#if AVVIDEO > 1 -+ this->context->skip_frame = (this->skipframes > 0) ? AVDISCARD_NONREF : AVDISCARD_DEFAULT; -+#else - this->context->hurry_up = (this->skipframes > 0); -+#endif - - lprintf("avcodec_decode_video: size=%d\n", this->mpeg_parser->buffer_size); -+#if AVVIDEO > 1 -+ AVPacket avpkt; -+ av_init_packet(&avpkt); -+ 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, -+ &got_picture, &avpkt); -+#else - len = avcodec_decode_video (this->context, this->av_frame, - &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); - len = current - buf->content - offset; -@@ -1112,7 +1142,13 @@ - - } else { - -- if (this->context->hurry_up) { -+ if ( -+#if AVVIDEO > 1 -+ this->context->skip_frame != AVDISCARD_DEFAULT -+#else -+ this->context->hurry_up -+#endif -+ ) { - /* skipped frame, output a bad frame */ - img = this->stream->video_out->get_frame (this->stream->video_out, - this->bih.biWidth, -@@ -1304,13 +1340,25 @@ - got_picture = 0; - } else { - /* skip decoding b frames if too late */ -+#if AVVIDEO > 1 -+ this->context->skip_frame = (this->skipframes > 0) ? AVDISCARD_NONREF : AVDISCARD_DEFAULT; -+#else - this->context->hurry_up = (this->skipframes > 0); -- -+#endif - lprintf("buffer size: %d\n", this->size); -+#if AVVIDEO > 1 -+ AVPacket avpkt; -+ av_init_packet(&avpkt); -+ 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, -+ &got_picture, &avpkt); -+#else - len = avcodec_decode_video (this->context, this->av_frame, - &got_picture, &chunk_buf[offset], - this->size); -- -+#endif - #ifdef AVCODEC_HAS_REORDERED_OPAQUE - /* reset consumed pts value */ - this->context->reordered_opaque = ff_tag_pts(this, 0); -Index: src/input/input_cdda.c -=================================================================== ---- xine-lib.orig/src/input/input_cdda.c 2011-05-27 19:46:33.570934872 +0200 -+++ xine-lib/src/input/input_cdda.c 2011-05-27 19:46:38.340934964 +0200 -@@ -89,6 +89,14 @@ - #define CD_LEADOUT_TRACK 0xAA - #define CD_BLOCK_OFFSET 150 - -+#ifdef HAVE_LIBAVUTIL_SHA1_H -+/* old libavutil/sha1.h was found... */ -+#define AVSHA AVSHA1 -+# define av_sha_init(c,b) av_sha1_init(c) -+# define av_sha_update av_sha1_update -+# define av_sha_final av_sha1_final -+#endif -+ - typedef struct _cdrom_toc_entry { - int track_mode; - int first_frame; -Index: src/post/planar/pp.c -=================================================================== ---- xine-lib.orig/src/post/planar/pp.c 2011-05-27 19:46:33.540935109 +0200 -+++ xine-lib/src/post/planar/pp.c 2011-05-27 19:51:21.830934917 +0200 -@@ -35,6 +35,12 @@ - # include - #endif - -+#if LIBPOSTPROC_VERSION_MAJOR < 52 -+# define pp_context pp_context_t -+# define pp_mode pp_mode_t -+# define PP_PARAMETERS_T -+#endif -+ - #define PP_STRING_SIZE 256 /* size of pp mode string (including all options) */ - - /* plugin class initialization function */ -@@ -76,8 +82,8 @@ - - /* libpostproc specific stuff */ - int pp_flags; -- pp_context_t *pp_context; -- pp_mode_t *pp_mode; -+ pp_context *pp_context; -+ pp_mode *pp_mode; - - pthread_mutex_t lock; - }; -Index: src/combined/ffmpeg/ff_audio_decoder.c -=================================================================== ---- xine-lib.orig/src/combined/ffmpeg/ff_audio_decoder.c 2011-05-27 19:53:22.700933869 +0200 -+++ xine-lib/src/combined/ffmpeg/ff_audio_decoder.c 2011-05-27 19:55:40.820939483 +0200 -@@ -46,6 +46,13 @@ - - #define AUDIOBUFSIZE (64 * 1024) - -+#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 32) -+# define AVAUDIO 3 -+#else -+# define AVAUDIO 2 -+#endif -+ -+ - typedef struct { - audio_decoder_class_t decoder_class; - } ff_audio_class_t; -@@ -255,6 +262,9 @@ - buf->decoder_info[2]); - - } else if (!(buf->decoder_flags & BUF_FLAG_SPECIAL)) { -+#if AVAUDIO > 2 -+ AVPacket avpkt; -+#endif - - if( !this->decoder_ok ) { - if ( ! this->context || ! this->codec ) { -@@ -286,11 +296,21 @@ - if (!this->output_open) { - if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) { - decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; -+#if AVAUDIO > 2 -+ av_init_packet (&avpkt); -+ avpkt.data = (uint8_t *)&this->buf[0]; -+ avpkt.size = this->size; -+ avpkt.flags = AV_PKT_FLAG_KEY; -+ avcodec_decode_audio3 (this->context, -+ (int16_t *)this->decode_buffer, -+ &decode_buffer_size, &avpkt); -+#else - avcodec_decode_audio2 (this->context, - (int16_t *)this->decode_buffer, - &decode_buffer_size, - &this->buf[0], - this->size); -+#endif - this->audio_bits = this->context->bits_per_sample; - this->audio_sample_rate = this->context->sample_rate; - this->audio_channels = this->context->channels; -@@ -311,12 +331,21 @@ - offset = 0; - while (this->size>0) { - decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; -+#if AVAUDIO > 2 -+ av_init_packet (&avpkt); -+ avpkt.data = (uint8_t *)&this->buf[offset]; -+ avpkt.size = this->size; -+ avpkt.flags = AV_PKT_FLAG_KEY; -+ bytes_consumed = avcodec_decode_audio3 (this->context, -+ (int16_t *)this->decode_buffer, -+ &decode_buffer_size, &avpkt); -+#else - bytes_consumed = avcodec_decode_audio2 (this->context, - (int16_t *)this->decode_buffer, - &decode_buffer_size, - &this->buf[offset], - this->size); -- -+#endif - if (bytes_consumed<0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "ffmpeg_audio_dec: error decompressing audio frame\n"); Index: files/patch-misc_libxine.pc.in =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-misc_libxine.pc.in,v retrieving revision 1.1 diff -u -p -r1.1 patch-misc_libxine.pc.in --- files/patch-misc_libxine.pc.in 3 Feb 2008 14:10:47 -0000 1.1 +++ files/patch-misc_libxine.pc.in 25 Jan 2012 21:50:40 -0000 @@ -1,14 +1,14 @@ ---- misc/libxine.pc.in.orig 2008-02-03 22:02:31.000000000 +0900 -+++ misc/libxine.pc.in 2008-02-03 22:03:24.000000000 +0900 -@@ -19,7 +19,7 @@ +--- misc/libxine.pc.in.orig ++++ misc/libxine.pc.in +@@ -22,7 +22,7 @@ Name: libxine Description: The xine engine library Version: @XINE_MAJOR@.@XINE_MINOR@.@XINE_SUB@@XINE_PATCH@ - Requires: + Requires.private: @XDG_BASEDIR_REQUIRES@ -Libs: -L${libdir} -lxine -Libs.private: @ZLIB_LIBS@ @NET_LIBS@ @PTHREAD_LIBS@ @LIBICONV@ @RT_LIBS@ -Cflags: -I${includedir} -Cflags.private: @PTHREAD_CFLAGS@ +Libs: -L${libdir} -lxine @ZLIB_LIBS@ @NET_LIBS@ @PTHREAD_LIBS@ @LIBICONV@ @RT_LIBS@ -+Libs.private: ++Libs.private: +Cflags: -I${includedir} @PTHREAD_CFLAGS@ -+Cflags.private: ++Cflags.private: Index: files/patch-src-video_out-xxmc.h =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src-video_out-xxmc.h,v retrieving revision 1.1 diff -u -p -r1.1 patch-src-video_out-xxmc.h --- files/patch-src-video_out-xxmc.h 11 Oct 2011 18:29:09 -0000 1.1 +++ files/patch-src-video_out-xxmc.h 25 Jan 2012 21:50:40 -0000 @@ -1,10 +0,0 @@ ---- src/video_out/xxmc.h.orig -+++ src/video_out/xxmc.h -@@ -79,6 +79,7 @@ - #include - #ifdef HAVE_VLDXVMC - #include -+ #include - #else - #include - #include Index: files/patch-src:libffmpeg:libavcodec:h263.c =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src:libffmpeg:libavcodec:h263.c,v retrieving revision 1.8 diff -u -p -r1.8 patch-src:libffmpeg:libavcodec:h263.c --- files/patch-src:libffmpeg:libavcodec:h263.c 29 Nov 2006 20:38:21 -0000 1.8 +++ files/patch-src:libffmpeg:libavcodec:h263.c 25 Jan 2012 21:50:40 -0000 @@ -1,39 +0,0 @@ ---- src/libffmpeg/libavcodec/h263.c.orig Sun Jul 9 16:38:11 2006 -+++ src/libffmpeg/libavcodec/h263.c Thu Sep 28 12:53:39 2006 -@@ -38,6 +38,7 @@ - #include "mpegvideo.h" - #include "h263data.h" - #include "mpeg4data.h" -+#include "xine_internal.h" - - //#undef NDEBUG - //#include -@@ -66,8 +67,8 @@ - static int h263p_decode_umotion(MpegEncContext * s, int pred); - static int h263_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded); --static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); --static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, -+static int __inline mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); -+static int __inline mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded, int intra, int rvlc); - static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, - uint8_t *scan_table); -@@ -4684,7 +4685,7 @@ - * @param dir_ptr the prediction direction will be stored here - * @return the quantized dc - */ --static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) -+static __inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) - { - int level, code; - -@@ -4729,7 +4730,7 @@ - * decodes a block. - * @return <0 if an error occured - */ --static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, -+static __inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded, int intra, int rvlc) - { - int level, i, last, run; Index: files/patch-src:libffmpeg:libavcodec:mpeg12.c =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src:libffmpeg:libavcodec:mpeg12.c,v retrieving revision 1.6 diff -u -p -r1.6 patch-src:libffmpeg:libavcodec:mpeg12.c --- files/patch-src:libffmpeg:libavcodec:mpeg12.c 1 Aug 2006 17:18:59 -0000 1.6 +++ files/patch-src:libffmpeg:libavcodec:mpeg12.c 25 Jan 2012 21:50:40 -0000 @@ -1,94 +0,0 @@ ---- src/libffmpeg/libavcodec/mpeg12.c.orig Sun Jul 9 23:38:32 2006 -+++ src/libffmpeg/libavcodec/mpeg12.c Wed Aug 2 01:25:48 2006 -@@ -65,21 +65,21 @@ - int component); - static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added - #endif //CONFIG_ENCODERS --static inline int mpeg1_decode_block_inter(MpegEncContext *s, -+static __inline int mpeg1_decode_block_inter(MpegEncContext *s, - DCTELEM *block, - int n); --static inline int mpeg1_decode_block_intra(MpegEncContext *s, -+static __inline int mpeg1_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n); --static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n); --static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, -+static __inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n); -+static __inline int mpeg2_decode_block_non_intra(MpegEncContext *s, - DCTELEM *block, - int n); --static inline int mpeg2_decode_block_intra(MpegEncContext *s, -+static __inline int mpeg2_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n); --static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n); --static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n); -+static __inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n); -+static __inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n); - static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred); - static void exchange_uv(MpegEncContext *s); - -@@ -1505,7 +1505,7 @@ - return diff; - } - --static inline int mpeg1_decode_block_intra(MpegEncContext *s, -+static __inline int mpeg1_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n) - { -@@ -1578,7 +1578,7 @@ - return 0; - } - --static inline int mpeg1_decode_block_inter(MpegEncContext *s, -+static __inline int mpeg1_decode_block_inter(MpegEncContext *s, - DCTELEM *block, - int n) - { -@@ -1656,7 +1656,7 @@ - return 0; - } - --static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n) -+static __inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n) - { - int level, i, j, run; - RLTable *rl = &rl_mpeg1; -@@ -1728,7 +1728,7 @@ - } - - --static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, -+static __inline int mpeg2_decode_block_non_intra(MpegEncContext *s, - DCTELEM *block, - int n) - { -@@ -1809,7 +1809,7 @@ - return 0; - } - --static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, -+static __inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, - DCTELEM *block, - int n) - { -@@ -1872,7 +1872,7 @@ - } - - --static inline int mpeg2_decode_block_intra(MpegEncContext *s, -+static __inline int mpeg2_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n) - { -@@ -1952,7 +1952,7 @@ - return 0; - } - --static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, -+static __inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n) - { Index: files/patch-src:libffmpeg:libavcodec:msmpeg4.c =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src:libffmpeg:libavcodec:msmpeg4.c,v retrieving revision 1.6 diff -u -p -r1.6 patch-src:libffmpeg:libavcodec:msmpeg4.c --- files/patch-src:libffmpeg:libavcodec:msmpeg4.c 1 Aug 2006 17:18:59 -0000 1.6 +++ files/patch-src:libffmpeg:libavcodec:msmpeg4.c 25 Jan 2012 21:50:40 -0000 @@ -1,20 +0,0 @@ ---- src/libffmpeg/libavcodec/msmpeg4.c.orig Sun Jul 9 23:38:34 2006 -+++ src/libffmpeg/libavcodec/msmpeg4.c Wed Aug 2 01:27:48 2006 -@@ -60,7 +60,7 @@ - static uint32_t v2_dc_chroma_table[512][2]; - - static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n); --static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, -+static __inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded, const uint8_t *scantable); - static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); - static int msmpeg4_decode_motion(MpegEncContext * s, -@@ -1659,7 +1659,7 @@ - return 0; - } - //#define ERROR_DETAILS --static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, -+static __inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded, const uint8_t *scan_table) - { - int level, i, last, run, run_diff; Index: files/patch-src:xine-engine:post.h =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src:xine-engine:post.h,v retrieving revision 1.2 diff -u -p -r1.2 patch-src:xine-engine:post.h --- files/patch-src:xine-engine:post.h 3 Jul 2011 19:53:19 -0000 1.2 +++ files/patch-src:xine-engine:post.h 25 Jan 2012 21:50:40 -0000 @@ -1,11 +0,0 @@ ---- src/xine-engine/post.h.orig 2010-06-03 15:54:12.000000000 +0200 -+++ src/xine-engine/post.h 2010-06-03 15:59:20.000000000 +0200 -@@ -377,7 +377,7 @@ static xine_post_api_parameter_t temp_p[ - - #define PARAM_ITEM( param_type, var, enumv, min, max, readonly, descr ) \ - { param_type, #var, sizeof(temp_s.var), \ -- (char*)&temp_s.var-(char*)&temp_s, enumv, min, max, readonly, descr }, -+ offsetof(__typeof__(temp_s), var), enumv, min, max, readonly, descr }, - - #define END_PARAM_DESCR( name ) \ - { POST_PARAM_TYPE_LAST, NULL, 0, 0, NULL, 0, 0, 1, NULL } \ Index: files/patch-src:xine-engine:xine_internal.h =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src:xine-engine:xine_internal.h,v retrieving revision 1.5 diff -u -p -r1.5 patch-src:xine-engine:xine_internal.h --- files/patch-src:xine-engine:xine_internal.h 29 Nov 2006 20:38:21 -0000 1.5 +++ files/patch-src:xine-engine:xine_internal.h 25 Jan 2012 21:50:40 -0000 @@ -1,127 +0,0 @@ ---- src/xine-engine/xine_internal.h.orig Sat Apr 22 00:46:33 2006 -+++ src/xine-engine/xine_internal.h Thu Sep 28 16:13:27 2006 -@@ -72,6 +72,124 @@ - # include - #endif - -+#ifndef INT8_MIN -+#define INT8_MIN (-0x7f-1) -+#endif -+ -+#ifndef INT8_MAX -+#define INT8_MAX 0x7f -+#endif -+ -+#ifndef INT16_MAX -+#define INT16_MAX 0x7fff -+#endif -+ -+#ifndef INT16_MIN -+#define INT16_MIN (-0x7fff-1) -+#endif -+ -+#ifndef INT32_MAX -+#define INT32_MAX 0x7fffffff -+#endif -+ -+#ifndef INT32_MIN -+#define INT32_MIN (-0x7fffffff-1) -+#endif -+ -+#ifndef PRIdMAX -+#define PRIdMAX "lld" -+#endif -+ -+#ifndef SCNdMAX -+#define SCNdMAX "lld" -+#endif -+ -+#ifndef PRIiMAX -+#define PRIiMAX "lld" -+typedef long long intmax_t; -+#endif -+ -+ -+#ifndef PRId32 -+#define PRId32 "d" -+#endif -+ -+#ifndef SCNd32 -+#define SCNd32 "d" -+#endif -+ -+#ifndef PRIdFAST16 -+#define PRIdFAST16 "d" -+#endif -+ -+#ifndef PRIdFAST32 -+#define PRIdFAST32 "d" -+#endif -+ -+#ifndef SCNu32 -+#define SCNu32 "u" -+#endif -+ -+ -+#ifndef PRId64 -+#if defined(__alpha__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) -+#define PRId64 "ld" -+#else if defined(__i386__) || defined(__powerpc__) -+#define PRId64 "lld" -+#endif -+#endif -+ -+#ifndef SCNd64 -+#define SCNd64 PRId64 -+#endif -+ -+#ifndef PRIu64 -+#if defined(__alpha__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) -+#define PRIu64 "lu" -+#else if defined(__i386__) || defined(__powerpc__) -+#define PRIu64 "llu" -+#endif -+#endif -+ -+#ifndef SCNu64 -+#define SCNu64 PRIu64 -+#endif -+ -+#ifndef PRIX64 -+#if defined(__alpha__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) -+#define PRIX64 "lX" -+#else if defined(__i386__) || defined(__powerpc__) -+#define PRIX64 "llX" -+#endif -+#endif -+ -+ -+#ifndef PRIx32 -+#define PRIx32 "x" -+#endif -+ -+#ifndef PRIx16 -+#define PRIx16 "x" -+#endif -+ -+#ifndef PRIx8 -+#define PRIx8 "x" -+#endif -+ -+#ifndef PRIXMAX -+#define PRIXMAX "llX" -+#endif -+ -+#ifndef PRIxMAX -+#define PRIxMAX "llx" -+#endif -+ -+#ifndef UINT64_C -+#define UINT64_C(c) (c ## ULL) -+#endif -+ -+ -+ - - #define XINE_MAX_EVENT_LISTENERS 50 - #define XINE_MAX_EVENT_TYPES 100 Index: files/patch-src_audio_out_audio_oss_out.c =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src_audio_out_audio_oss_out.c,v retrieving revision 1.3 diff -u -p -r1.3 patch-src_audio_out_audio_oss_out.c --- files/patch-src_audio_out_audio_oss_out.c 19 Jun 2010 11:06:36 -0000 1.3 +++ files/patch-src_audio_out_audio_oss_out.c 25 Jan 2012 21:50:40 -0000 @@ -1,6 +1,6 @@ ---- ./src/audio_out/audio_oss_out.c.orig 2010-01-15 01:17:54.000000000 +0300 -+++ ./src/audio_out/audio_oss_out.c 2010-06-19 01:49:48.446683938 +0400 -@@ -160,7 +160,7 @@ +--- ./src/audio_out/audio_oss_out.c.orig ++++ ./src/audio_out/audio_oss_out.c +@@ -159,7 +159,7 @@ static int ao_oss_open(ao_driver_t *this uint32_t bits, uint32_t rate, int mode) { oss_driver_t *this = (oss_driver_t *) this_gen; @@ -9,7 +9,7 @@ xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: ao_open rate=%d, mode=%d, dev=%s\n", rate, mode, this->audio_dev); -@@ -292,14 +292,14 @@ +@@ -291,14 +291,14 @@ static int ao_oss_open(ao_driver_t *this if (bits==8) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: SNDCTL_DSP_SETFMT failed for AFMT_U8.\n"); if (tmp != AFMT_U8) @@ -26,7 +26,7 @@ else xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: The AFMT_S16_NE ioctl failed.\n"); return 0; -@@ -318,7 +318,7 @@ +@@ -317,7 +317,7 @@ static int ao_oss_open(ao_driver_t *this tmp = AFMT_AC3; if (ioctl(this->audio_fd, SNDCTL_DSP_SETFMT, &tmp) < 0 || tmp != AFMT_AC3) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, @@ -35,16 +35,16 @@ tmp = AFMT_S16_LE; ioctl(this->audio_fd, SNDCTL_DSP_SETFMT, &tmp); } -@@ -374,7 +374,7 @@ +@@ -373,7 +373,7 @@ static int ao_oss_delay(ao_driver_t *thi count_info info; oss_driver_t *this = (oss_driver_t *) this_gen; -- int bytes_left; -+ long bytes_left; +- int bytes_left = 0; ++ long bytes_left = 0; int frames; struct timeval tv; -@@ -514,7 +514,7 @@ +@@ -512,7 +512,7 @@ static void ao_oss_exit(ao_driver_t *thi static int ao_oss_get_property (ao_driver_t *this_gen, int property) { oss_driver_t *this = (oss_driver_t *) this_gen; @@ -53,7 +53,7 @@ switch(property) { case AO_PROP_PCM_VOL: -@@ -523,7 +523,7 @@ +@@ -521,7 +521,7 @@ static int ao_oss_get_property (ao_drive if(this->mixer.fd != -1) { IOCTL_REQUEST_TYPE cmd = 0; @@ -62,7 +62,7 @@ ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); -@@ -553,7 +553,7 @@ +@@ -551,7 +551,7 @@ static int ao_oss_get_property (ao_drive static int ao_oss_set_property (ao_driver_t *this_gen, int property, int value) { oss_driver_t *this = (oss_driver_t *) this_gen; @@ -71,7 +71,7 @@ switch(property) { case AO_PROP_PCM_VOL: -@@ -562,7 +562,7 @@ +@@ -560,7 +560,7 @@ static int ao_oss_set_property (ao_drive if(this->mixer.fd != -1) { IOCTL_REQUEST_TYPE cmd = 0; @@ -80,7 +80,7 @@ ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); -@@ -591,7 +591,7 @@ +@@ -589,7 +589,7 @@ static int ao_oss_set_property (ao_drive if(this->mixer.fd != -1) { IOCTL_REQUEST_TYPE cmd = 0; @@ -89,16 +89,16 @@ ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); -@@ -664,7 +664,7 @@ +@@ -662,7 +662,7 @@ static int ao_oss_ctrl(ao_driver_t *this static int probe_audio_devices(oss_driver_t *this) { - const char *base_names[2] = {"/dev/dsp", "/dev/sound/dsp"}; + static const char *const base_names[2] = {"/dev/dsp", "/dev/sound/dsp"}; int base_num, i; - int audio_fd, rate; + long audio_fd, rate; int best_rate; char devname[30]; -@@ -703,9 +703,9 @@ +@@ -701,9 +701,9 @@ static ao_driver_t *open_plugin (audio_d oss_class_t *class = (oss_class_t *) class_gen; config_values_t *config = class->config; oss_driver_t *this; Index: files/patch-src_libffmpeg_libavcodec_dsputil.c =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src_libffmpeg_libavcodec_dsputil.c,v retrieving revision 1.1 diff -u -p -r1.1 patch-src_libffmpeg_libavcodec_dsputil.c --- files/patch-src_libffmpeg_libavcodec_dsputil.c 18 Feb 2007 16:07:49 -0000 1.1 +++ files/patch-src_libffmpeg_libavcodec_dsputil.c 25 Jan 2012 21:50:40 -0000 @@ -1,11 +0,0 @@ ---- src/libffmpeg/libavcodec/dsputil.c.orig Sun Feb 18 22:17:14 2007 -+++ src/libffmpeg/libavcodec/dsputil.c Sun Feb 18 22:15:46 2007 -@@ -3810,7 +3810,7 @@ - static int did_fail=0; - DECLARE_ALIGNED_16(int, aligned); - -- if((int)&aligned & 15){ -+ if((intptr_t)&aligned & 15){ - if(!did_fail){ - #if defined(HAVE_MMX) || defined(HAVE_ALTIVEC) - av_log(NULL, AV_LOG_ERROR, Index: files/patch-src_libffmpeg_libavcodec_huffyuv.c =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src_libffmpeg_libavcodec_huffyuv.c,v retrieving revision 1.1 diff -u -p -r1.1 patch-src_libffmpeg_libavcodec_huffyuv.c --- files/patch-src_libffmpeg_libavcodec_huffyuv.c 29 Nov 2006 20:38:21 -0000 1.1 +++ files/patch-src_libffmpeg_libavcodec_huffyuv.c 25 Jan 2012 21:50:40 -0000 @@ -1,10 +0,0 @@ ---- src/libffmpeg/libavcodec/huffyuv.c.orig Thu Sep 28 13:25:07 2006 -+++ src/libffmpeg/libavcodec/huffyuv.c Thu Sep 28 13:25:32 2006 -@@ -30,6 +30,7 @@ - #include "bitstream.h" - #include "avcodec.h" - #include "dsputil.h" -+#include "xine_internal.h" - - #define VLC_BITS 11 - Index: files/patch-src_libffmpeg_libavcodec_mpegvideo.c =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src_libffmpeg_libavcodec_mpegvideo.c,v retrieving revision 1.1 diff -u -p -r1.1 patch-src_libffmpeg_libavcodec_mpegvideo.c --- files/patch-src_libffmpeg_libavcodec_mpegvideo.c 29 Nov 2006 20:38:21 -0000 1.1 +++ files/patch-src_libffmpeg_libavcodec_mpegvideo.c 25 Jan 2012 21:50:40 -0000 @@ -1,10 +0,0 @@ ---- src/libffmpeg/libavcodec/mpegvideo.c.orig Thu Sep 28 13:27:10 2006 -+++ src/libffmpeg/libavcodec/mpegvideo.c Thu Sep 28 13:27:35 2006 -@@ -30,6 +30,7 @@ - #include "mpegvideo.h" - #include "faandct.h" - #include -+#include "xine_internal.h" - - #ifdef USE_FASTMEMCPY - #include "fastmemcpy.h" Index: files/patch-src_libffmpeg_libavcodec_vorbis.c =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src_libffmpeg_libavcodec_vorbis.c,v retrieving revision 1.1 diff -u -p -r1.1 patch-src_libffmpeg_libavcodec_vorbis.c --- files/patch-src_libffmpeg_libavcodec_vorbis.c 29 Nov 2006 20:38:21 -0000 1.1 +++ files/patch-src_libffmpeg_libavcodec_vorbis.c 25 Jan 2012 21:50:40 -0000 @@ -1,11 +0,0 @@ ---- src/libffmpeg/libavcodec/vorbis.c.orig Thu Sep 28 13:27:16 2006 -+++ src/libffmpeg/libavcodec/vorbis.c Thu Sep 28 13:27:41 2006 -@@ -29,6 +29,8 @@ - #include "dsputil.h" - - #include "vorbis.h" -+#include "xine_internal.h" -+ - - #define V_NB_BITS 8 - #define V_NB_BITS2 11 Index: files/patch-src_video_out_libdha_sysdep_pci_freebsd.c =================================================================== RCS file: /home/pcvs/ports/multimedia/libxine/files/patch-src_video_out_libdha_sysdep_pci_freebsd.c,v retrieving revision 1.1 diff -u -p -r1.1 patch-src_video_out_libdha_sysdep_pci_freebsd.c --- files/patch-src_video_out_libdha_sysdep_pci_freebsd.c 28 May 2006 14:27:17 -0000 1.1 +++ files/patch-src_video_out_libdha_sysdep_pci_freebsd.c 25 Jan 2012 21:50:40 -0000 @@ -1,11 +0,0 @@ ---- src/video_out/libdha/sysdep/pci_freebsd.c.orig Sun May 28 22:49:02 2006 -+++ src/video_out/libdha/sysdep/pci_freebsd.c Sun May 28 22:50:59 2006 -@@ -8,7 +8,7 @@ - /* machine/console.h seems to be outdated by recent FreeBSD * - * however pcvt_ioctl.h seems to exist for very long time */ - /* #include */ --#include -+#include - #ifndef GCCUSESGAS - #define GCCUSESGAS - #endif Index: files/ffmpeg-vaapi_xine-lib-1.2.1-defaultoff.diff @@ -0,0 +1,5990 @@ +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 19731e8..571f2e5 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 5a04011..d648f5d 100644 +--- a/include/xine/video_out.h ++++ b/include/xine/video_out.h +@@ -303,6 +303,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 5334b8d..fbfe0b0 100644 +--- a/src/combined/ffmpeg/ff_video_decoder.c ++++ b/src/combined/ffmpeg/ff_video_decoder.c +@@ -50,6 +50,8 @@ + # include + #endif + ++#include ++#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; + + xine_t *xine; + } ff_video_class_t; +@@ -134,8 +139,12 @@ 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 set_stream_info(ff_video_decoder_t *this) { + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); +@@ -159,13 +168,74 @@ 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_YUV420P && this->context->pix_fmt != PIX_FMT_YUVJ420P ) { ++ 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->context->pix_fmt != PIX_FMT_YUV420P && 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")); +@@ -234,6 +304,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; +@@ -244,7 +326,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); +- assert(it); ++ //assert(it); + if( it != NULL ) + xine_list_remove(this->dr1_frames, it); + } else { +@@ -279,6 +361,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; + +@@ -324,6 +451,47 @@ 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]; ++ } ++ ++ if (this->class->thread_count > 1) { ++ if (this->codec->id != CODEC_ID_SVQ3 ++#ifndef DEPRECATED_AVCODEC_THREAD_INIT ++ && avcodec_thread_init(this->context, this->class->thread_count) != -1 ++#endif ++ ) ++ this->context->thread_count = this->class->thread_count; ++ } ++ ++ /* enable direct rendering by default */ ++ this->output_format = XINE_IMGFMT_YV12; ++#ifdef ENABLE_DIRECT_RENDERING ++ if( this->codec->capabilities & CODEC_CAP_DR1 && this->codec->id != CODEC_ID_H264 ) { ++ 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")); ++ } ++ ++ if( this->class->enable_vaapi ) { ++ 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")); ++ } ++#endif ++ + pthread_mutex_lock(&ffmpeg_lock); + if (avcodec_open (this->context, this->codec) < 0) { + pthread_mutex_unlock(&ffmpeg_lock); +@@ -351,17 +519,6 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) + } + } + +- if (this->class->thread_count > 1) { +- if (this->codec->id != CODEC_ID_SVQ3 +-#ifndef DEPRECATED_AVCODEC_THREAD_INIT +- && avcodec_thread_init(this->context, this->class->thread_count) != -1 +-#endif +- ) +- this->context->thread_count = this->class->thread_count; +- } +- +- this->context->skip_loop_filter = skip_loop_filter_enum_values[this->class->skip_loop_filter_enum]; +- + pthread_mutex_unlock(&ffmpeg_lock); + + lprintf("lavc decoder opened\n"); +@@ -384,37 +541,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->codec->id != CODEC_ID_H264 ) { +- 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; ++ } + } + + /* dont want initial AV_NOPTS_VALUE here */ +@@ -422,6 +570,24 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) + + } + ++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; + +@@ -537,7 +703,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; + +@@ -549,9 +715,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) +@@ -561,18 +727,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 */ +@@ -583,18 +749,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 */ +@@ -624,7 +790,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]); +@@ -653,7 +819,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]); +@@ -682,7 +848,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]); +@@ -706,7 +872,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]); +@@ -730,7 +896,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]); +@@ -769,7 +935,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]); +@@ -781,7 +947,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { + + dy += img->pitches[0]; + +- sy += this->av_frame->linesize[0]; ++ sy += av_frame->linesize[0]; + } + + for (y = 0; y < this->bih.biHeight / 2; y++) { +@@ -818,11 +984,11 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { + dv += img->pitches[2]; + + if (this->context->pix_fmt != PIX_FMT_YUV420P) { +- 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]; + } + } + } +@@ -1126,6 +1292,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"); + +@@ -1187,12 +1357,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); +@@ -1210,9 +1391,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, +@@ -1223,17 +1419,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; +@@ -1241,6 +1476,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) +@@ -1269,6 +1512,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 ); ++ } + } + } + +@@ -1365,12 +1614,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); +@@ -1422,6 +1682,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; +@@ -1429,7 +1694,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) || +@@ -1465,10 +1730,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 */ +@@ -1481,7 +1746,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, +@@ -1490,7 +1755,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); +@@ -1519,6 +1785,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) +@@ -1742,6 +2017,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); + } + +@@ -1785,11 +2063,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; + } + +@@ -1849,6 +2158,21 @@ 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); ++ + return this; + } + +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 ++#include ++#include ++#include ++#include ++ ++#include ++#if defined(__FreeBSD__) ++#include ++#endif ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include "yuv2rgb.h" ++ ++#define LOG_MODULE "video_out_vaapi" ++#define LOG_VERBOSE ++/* ++#define LOG ++*/ ++/* ++#define DEBUG_SURFACE ++*/ ++#include "xine.h" ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#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 ++#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 ""; ++} ++ ++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 ""; ++} ++ ++/* 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; icolor)/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; icolor)/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; iwidth, 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 616da19..c4da0f5 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 ++#include ++#ifdef HAVE_FFMPEG_AVUTIL_H ++# include ++#else ++# include ++#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 cc42813..819e423 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; + Index: files/patch-contrib-libdha-sysdep-pci_freebsd.c @@ -0,0 +1,11 @@ +--- contrib/libdha/sysdep/pci_freebsd.c.orig ++++ contrib/libdha/sysdep/pci_freebsd.c +@@ -8,7 +8,7 @@ + /* machine/console.h seems to be outdated by recent FreeBSD * + * however pcvt_ioctl.h seems to exist for very long time */ + /* #include */ +-#include ++#include + #ifndef GCCUSESGAS + #define GCCUSESGAS + #endif Index: files/patch-include-xine-post.h @@ -0,0 +1,11 @@ +--- include/xine/post.h.orig ++++ include/xine/post.h +@@ -397,7 +397,7 @@ static xine_post_api_parameter_t temp_p[ + + #define PARAM_ITEM( param_type, var, enumv, min, max, readonly, descr ) \ + { param_type, #var, sizeof(temp_s.var), \ +- (char*)&temp_s.var-(char*)&temp_s, enumv, min, max, readonly, descr }, ++ offsetof(__typeof__(temp_s), var), enumv, min, max, readonly, descr }, + + #define END_PARAM_DESCR( name ) \ + { POST_PARAM_TYPE_LAST, NULL, 0, 0, NULL, 0, 0, 1, NULL } \ Index: files/patch-include-xine-xine_internal.h @@ -0,0 +1,127 @@ +--- include/xine/xine_internal.h.orig ++++ include/xine/xine_internal.h +@@ -72,6 +72,124 @@ + # include + #endif + ++#ifndef INT8_MIN ++#define INT8_MIN (-0x7f-1) ++#endif ++ ++#ifndef INT8_MAX ++#define INT8_MAX 0x7f ++#endif ++ ++#ifndef INT16_MAX ++#define INT16_MAX 0x7fff ++#endif ++ ++#ifndef INT16_MIN ++#define INT16_MIN (-0x7fff-1) ++#endif ++ ++#ifndef INT32_MAX ++#define INT32_MAX 0x7fffffff ++#endif ++ ++#ifndef INT32_MIN ++#define INT32_MIN (-0x7fffffff-1) ++#endif ++ ++#ifndef PRIdMAX ++#define PRIdMAX "lld" ++#endif ++ ++#ifndef SCNdMAX ++#define SCNdMAX "lld" ++#endif ++ ++#ifndef PRIiMAX ++#define PRIiMAX "lld" ++typedef long long intmax_t; ++#endif ++ ++ ++#ifndef PRId32 ++#define PRId32 "d" ++#endif ++ ++#ifndef SCNd32 ++#define SCNd32 "d" ++#endif ++ ++#ifndef PRIdFAST16 ++#define PRIdFAST16 "d" ++#endif ++ ++#ifndef PRIdFAST32 ++#define PRIdFAST32 "d" ++#endif ++ ++#ifndef SCNu32 ++#define SCNu32 "u" ++#endif ++ ++ ++#ifndef PRId64 ++#if defined(__alpha__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) ++#define PRId64 "ld" ++#else if defined(__i386__) || defined(__powerpc__) ++#define PRId64 "lld" ++#endif ++#endif ++ ++#ifndef SCNd64 ++#define SCNd64 PRId64 ++#endif ++ ++#ifndef PRIu64 ++#if defined(__alpha__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) ++#define PRIu64 "lu" ++#else if defined(__i386__) || defined(__powerpc__) ++#define PRIu64 "llu" ++#endif ++#endif ++ ++#ifndef SCNu64 ++#define SCNu64 PRIu64 ++#endif ++ ++#ifndef PRIX64 ++#if defined(__alpha__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) ++#define PRIX64 "lX" ++#else if defined(__i386__) || defined(__powerpc__) ++#define PRIX64 "llX" ++#endif ++#endif ++ ++ ++#ifndef PRIx32 ++#define PRIx32 "x" ++#endif ++ ++#ifndef PRIx16 ++#define PRIx16 "x" ++#endif ++ ++#ifndef PRIx8 ++#define PRIx8 "x" ++#endif ++ ++#ifndef PRIXMAX ++#define PRIXMAX "llX" ++#endif ++ ++#ifndef PRIxMAX ++#define PRIxMAX "llx" ++#endif ++ ++#ifndef UINT64_C ++#define UINT64_C(c) (c ## ULL) ++#endif ++ ++ ++ + + #define XINE_MAX_EVENT_LISTENERS 50 + #define XINE_MAX_EVENT_TYPES 100 Index: files/patch-src-vdr-input_vdr.c @@ -0,0 +1,12 @@ +--- src/vdr/input_vdr.c.orig ++++ src/vdr/input_vdr.c +@@ -32,6 +32,9 @@ + #include + #include + ++#ifdef __FreeBSD__ ++#include ++#endif + #include + #include + #include Index: files/patch-src-libw32dll-wine-registry.c @@ -0,0 +1,13 @@ +--- src/libw32dll/wine/registry.c.orig ++++ src/libw32dll/wine/registry.c +@@ -7,6 +7,10 @@ + #include + #include + ++#ifdef __FreeBSD__ ++#include ++#endif ++ + #include "winbase.h" + #include "winreg.h" + #include "winnt.h"